Thank you for your interest in contributing to this library! This document provides comprehensive guidelines for contributing using our Agentic Framework for 10x productivity gains.
- Agentic Framework Philosophy
- Feature Development Process
- Validation Workflows
- Platform Implementation Order
- Development Setup
- Debugging
- Code Style
- Pull Request Process
- Release Process
This project supports two development approaches - choose the one that best fits your workflow:
For those using AI agents or seeking 10x productivity gains through automated feedback loops:
Core Philosophy:
- Fast validation (< 2 minutes to prove functionality works)
- Real device testing instead of mocked behavior
- Automated feedback loops as the key to productivity
- Quality assurance that prevents team regressions
Quick Commands:
cd apps/playground
scripts/agentic/start-metro.sh # Start Metro
scripts/agentic/app-state.sh eval "__AGENTIC__.startRecording({ sampleRate: 44100, channels: 1 })" # Start recording
scripts/agentic/app-state.sh state # Check state
scripts/agentic/app-state.sh eval "__AGENTIC__.stopRecording()" # Stop recordingAgent Constraints:
- NEVER IMPLEMENT UNLESS ASKED
- ALWAYS VERIFY IN SOURCE CODE
- MINIMIZE DIFF - smallest possible changes
- NO WORKAROUNDS - fix root causes
- REAL TESTING ONLY - no simulated results
For those preferring traditional test-driven development:
Core Philosophy:
- Write tests first to define expected behavior
- Red → Green → Refactor cycle
- High test coverage and living documentation
- Cross-platform consistency through comprehensive testing
Quick Commands:
# Run traditional test suite
./scripts/run_tests.sh all # All platforms
./scripts/run_tests.sh android # Android only
./scripts/run_tests.sh ios # iOS onlyTDD Workflow:
- Write failing tests first
- Implement minimal code to pass
- Refactor while keeping tests green
- Validate on all platforms
Both approaches ensure high-quality, cross-platform consistent features. Choose based on your development style and tooling preferences.
Before writing any code:
-
Define the Feature Goal
- What problem does this solve?
- Who will use this feature?
- What are the success criteria?
-
Design the API
// Example: New audio feature API design interface AudioFeatureConfig { sampleRate?: number; windowSize?: number; hopLength?: number; } interface AudioFeatureResult { timestamp: number; value: number; confidence?: number; } // Define the public API function extractAudioFeature( audioData: Float32Array, config?: AudioFeatureConfig ): AudioFeatureResult[];
-
Create Architecture Document
- Create a design doc in
docs/architecture/FEATURE_NAME.md - Include API design, data flow, and platform considerations
- Get review and approval before proceeding
- Create a design doc in
Creating comprehensive test specifications helps ensure robust implementations:
-
Create Test Plan
# Test Plan: [Feature Name] ## Unit Tests - [ ] Basic functionality with default parameters - [ ] Custom configuration handling - [ ] Edge cases (empty data, invalid params) - [ ] Error scenarios ## Integration Tests - [ ] Works with audio recording - [ ] Works with file processing - [ ] Performance benchmarks ## Platform Tests - [ ] iOS implementation matches spec - [ ] Android implementation matches spec - [ ] Web implementation matches spec
-
Write Test Cases First (When Possible)
// Example test file: __tests__/audioFeature.test.ts describe('AudioFeature', () => { it('should extract features from audio data', () => { const audioData = generateTestTone(440, 1.0); // 440Hz, 1 second const features = extractAudioFeature(audioData); expect(features).toHaveLength(43); // 1 second at default hop expect(features[0].timestamp).toBe(0); expect(features[0].value).toBeCloseTo(0.5, 2); }); it('should handle empty audio data', () => { const features = extractAudioFeature(new Float32Array(0)); expect(features).toEqual([]); }); // More test cases... });
Follow this recommended implementation order:
// src/types/AudioFeature.ts
export interface AudioFeatureExtractor {
extract(audioData: Float32Array, config?: AudioFeatureConfig): AudioFeatureResult[];
getName(): string;
getDefaultConfig(): AudioFeatureConfig;
}// ios/AudioFeatureExtractor.swift
class AudioFeatureExtractor {
func extract(audioData: [Float], config: AudioFeatureConfig?) -> [AudioFeatureResult] {
// Implementation
}
}Validation: Run iOS tests
cd packages/audio-studio
./scripts/run_tests.sh ios// android/src/main/java/net/siteed/audiostudio/AudioFeatureExtractor.kt
class AudioFeatureExtractor {
fun extract(audioData: FloatArray, config: AudioFeatureConfig?): List<AudioFeatureResult> {
// Implementation
}
}Validation: Run Android tests
cd packages/audio-studio
./scripts/run_tests.sh android// src/web/AudioFeatureExtractor.ts
export class AudioFeatureExtractor {
extract(audioData: Float32Array, config?: AudioFeatureConfig): AudioFeatureResult[] {
// Implementation using Web Audio API
}
}Run cross-platform tests to ensure consistency:
cd packages/audio-studio
yarn test:integrationMANDATORY: Update the playground app to demonstrate the new feature:
cd apps/playgroundRequired updates:
- Add UI controls in the appropriate settings screen
- Show feature in action with real examples
- Display platform limitations discovered during testing
- Include performance metrics if relevant
Example additions for a new feature:
// In RecordingSettings.tsx or appropriate component
<SettingsSection title="Buffer Configuration">
<Slider
label="Buffer Duration"
value={config.bufferDurationSeconds}
onValueChange={(value) => updateConfig({ bufferDurationSeconds: value })}
minimumValue={0.01}
maximumValue={0.5}
/>
{Platform.OS === 'ios' && (
<Text style={styles.warning}>
Note: iOS enforces minimum 0.1s buffer size
</Text>
)}
</SettingsSection>
// Add toggle for skip file writing
<Switch
label="Skip File Writing (Streaming Only)"
value={config.skipFileWriting}
onValueChange={(value) => updateConfig({ skipFileWriting: value })}
/>Choose the validation approach that fits your development style:
For AI-assisted development with fast feedback loops:
# 1. Create feature branch
git checkout -b feature/audio-pitch-detection
# 2. Implement feature
# 3. Start Metro and navigate to test screen
cd apps/playground
scripts/agentic/start-metro.sh
scripts/agentic/app-navigate.sh "/(tabs)/record"
# 4. Validate via CDP bridge (< 2 minutes)
scripts/agentic/app-state.sh eval "__AGENTIC__.startRecording({ sampleRate: 44100, channels: 1 })"
scripts/agentic/app-state.sh state
scripts/agentic/app-state.sh eval "__AGENTIC__.stopRecording()"
scripts/agentic/screenshot.sh validation-result
# 5. Optional: Run E2E tests
yarn e2e:android:agent-validation
yarn e2e:ios:agent-validationBenefits:
- Validates real functionality on actual devices
- Immediate feedback (< 2 minutes)
- No test maintenance overhead
- Discovers platform limitations immediately
For traditional test-driven development:
# 1. Create feature branch
git checkout -b feature/audio-pitch-detection
# 2. Write test first (TDD approach)
touch src/__tests__/pitchDetection.test.ts
# Write failing tests
# 3. Run tests (should fail)
yarn test
# 4. Implement for iOS
# Edit ios/PitchDetector.swift
./scripts/run_tests.sh ios
# 5. Implement for Android
# Edit android/src/main/java/.../PitchDetector.kt
./scripts/run_tests.sh android
# 6. Ensure all tests pass
./scripts/run_tests.sh all
# 7. Add integration tests
# Edit e2e/pitchDetection.e2e.ts
# 8. Run full test suite
yarn test:allBenefits:
- Comprehensive test coverage
- Living documentation through tests
- Detailed error scenario testing
- Traditional development comfort
-
Unit Tests
- Pure logic without platform dependencies
- Fast, isolated tests
- Location:
src/__tests__/
-
Platform Tests
- iOS:
ios/AudioStudioTests/ - Android:
android/src/test/(unit) andandroid/src/androidTest/(instrumented) - Test native implementations
- iOS:
-
Integration Tests
- End-to-end feature tests
- Cross-platform consistency tests
- Location:
e2e/
./scripts/run_tests.sh # All platforms
./scripts/run_tests.sh android # Android only
./scripts/run_tests.sh ios # iOS only-
Environment Setup
# Install dependencies yarn install # Build the module yarn build # Prepare test environment yarn test:prepare
-
Platform-Specific Setup
- iOS: Xcode 14+ with Swift 5.7+
- Android: Android Studio with Kotlin 1.8+
- Web: Node.js 18+ with TypeScript 5+
Test audio files are located in test-assets/:
jfk.wav- Speech sample (mono, 16kHz)chorus.wav- Music sample (stereo, 44.1kHz)tone_440hz.wav- Pure tone for frequency tests
Android
adb logcat -v time | grep "ExpoAudioStudio" # Module logs
adb logcat -v time | grep "ExpoAudioStudio" | grep " E " # Errors onlyiOS
# Simulator
xcrun simctl spawn booted log stream --predicate 'process contains "AudioDevPlayground"'
# Device
log stream --predicate 'process contains "AudioDevPlayground"'Visual Tools: Xcode Console app or macOS Console.app
-
TypeScript/JavaScript
- Use functional programming patterns
- Prefer interfaces over types
- No enums, use const objects
- Comprehensive JSDoc comments
-
Kotlin (Android)
- Follow Kotlin coding conventions
- Use coroutines for async operations
- Prefer data classes for models
-
Swift (iOS)
- Follow Swift API design guidelines
- Use async/await for async operations
- Prefer structs over classes when possible
-
Test Naming
// Good it('should extract MFCC features from mono audio at 16kHz', () => {}); // Bad it('test mfcc', () => {});
-
Test Structure
- Arrange: Set up test data
- Act: Execute the function
- Assert: Verify the result
-
Test Coverage Goals
- Target 80% coverage for new features
- Aim for 100% coverage for critical paths
- Include edge cases and error scenarios
All pull requests involving native code changes MUST verify that the code compiles on the target platforms. This includes:
-
Swift Code Changes (iOS)
- Verify compilation using Xcode or command line
- Check for scope errors, undefined variables, and type mismatches
- Run:
cd apps/playground && yarn ios --build-onlyor similar
-
Kotlin Code Changes (Android)
- Verify compilation using Android Studio or Gradle
- Check for compilation errors and lint warnings
- Run:
cd apps/playground && yarn android --build-onlyor similar
-
Integration Test Compilation
- Ensure tests compile and run without errors
- Verify test imports and dependencies are correct
Common Issues to Watch For:
- Variable scope errors (accessing variables outside their scope)
- Missing imports or undefined symbols
- Type mismatches between platforms
- Changes that compile but would fail at runtime
Example of a scope error that should be caught:
// WRONG: compressedURL is out of scope
if let compressedURL = compressedFileURL {
// compressedURL is only available inside this block
}
let filename = compressedURL?.lastPathComponent // ❌ Compilation error
// CORRECT: Use the class property
let filename = compressedFileURL?.lastPathComponent // ✅ Compiles correctlyAll new features MUST include integration tests that validate ACTUAL platform behavior. See PR_METHODOLOGY.md for detailed requirements.
Integration tests are critical because they:
- Reveal undocumented platform limitations (e.g., iOS minimum buffer sizes)
- Validate actual behavior, not mocked behavior
- Ensure cross-platform consistency
- Serve as living documentation
Example from the buffer duration feature:
// Integration test discovered iOS enforces minimum 4800 frames
// This critical limitation would have been missed by unit tests-
Verify Platform Compilation (MANDATORY for native code changes)
# For iOS changes - verify Swift compilation cd apps/playground && yarn ios --build-only # For Android changes - verify Kotlin compilation cd apps/playground && yarn android --build-only # Alternative: Build through Xcode/Android Studio
-
Run Full Test Suite
yarn test:all yarn lint yarn format:check
-
Update Documentation
- Update API documentation
- Update test plan if needed
- Add usage examples
-
Self Review Checklist
- Native code compiles successfully on target platforms
- No scope errors or undefined variables
- All tests pass on all platforms
- New features have tests (highly recommended)
- API changes are documented
- Breaking changes are noted
- Performance impact is measured
## Description
Brief description of the feature/fix
## Platform Compilation Verification (MANDATORY for native code changes)
- [ ] **iOS compilation verified** (Swift code compiles without errors)
- [ ] **Android compilation verified** (Kotlin code compiles without errors)
- [ ] No scope errors or undefined variables
- [ ] Tested with: `cd apps/playground && yarn ios --build-only` (or equivalent)
## Integration Tests
- [ ] **MANDATORY for new features**: Integration tests that validate ACTUAL platform behavior
- [ ] Tests reveal any platform limitations (document them!)
- [ ] iOS integration tests pass
- [ ] Android integration tests pass
- [ ] Test results included below
## Test Results
## Architecture Decision
Link to design doc or explain architectural choices
## Testing
- [ ] Unit tests added/updated
- [ ] Platform tests pass (iOS/Android/Web)
- [ ] Cross-platform consistency verified
## Documentation
- [ ] Updated EXISTING docs (don't create new files for config options)
- [ ] Added examples to relevant guides
- [ ] Platform-specific behavior documented
## Checklist
- [ ] **Platform compilation verified** (iOS/Android)
- [ ] Integration tests REQUIRED for features
- [ ] Minimal file changes
- [ ] No unnecessary subdirectories
- [ ] Breaking changes documented
- [ ] Follows code style guidelines
- [ ] Playground app updated with new feature
Semantic versioning is used:
- Major: Breaking API changes
- Minor: New features (backward compatible)
- Patch: Bug fixes
-
Pre-release
- All tests pass
- Documentation updated
- CHANGELOG.md updated
- Version bumped
-
Testing
- Run on iOS device
- Run on Android device
- Test in playground app
- Performance benchmarks
-
Release
yarn release:prepare yarn release:publish
-
Design Phase
// 1. Define types in src/types/ interface NewFeatureConfig { /* ... */ } interface NewFeatureResult { /* ... */ }
-
Test Phase (Recommended)
// 2. Write tests in src/__tests__/ describe('NewFeature', () => { // Test cases });
-
Implementation Phase
// 3. Android: android/src/main/java/.../NewFeature.kt class NewFeature { /* ... */ }
// 4. iOS: ios/NewFeature.swift class NewFeature { /* ... */ }
-
Integration Phase
// 5. Expose in module API export function processNewFeature(/* ... */) { /* ... */ }
// Test both platforms produce same results
it('should produce consistent results across platforms', async () => {
const audioData = loadTestAudio('test.wav');
const iosResult = await runIosImplementation(audioData);
const androidResult = await runAndroidImplementation(audioData);
expect(iosResult).toEqual(androidResult);
});- Documentation: Check
docs/folder - Examples: See playground app
- Issues: GitHub issues for bugs/features
- Discussions: GitHub discussions for questions
Note: The testing framework is continuously improving. Contributors are encouraged to help expand test coverage and improve testing practices as the project evolves.