Development Guide
Detailed guide for setting up your development environment and working with the ai.matey codebase.
Prerequisites
Section titled “Prerequisites”Before you begin, ensure you have:
- Node.js 18+ installed
- npm 9+ (comes with Node.js)
- Git for version control
- A code editor (we recommend VS Code)
Initial Setup
Section titled “Initial Setup”1. Clone the Repository
Section titled “1. Clone the Repository”# Fork the repository on GitHub first, then:git clone https://github.com/YOUR_USERNAME/ai.matey.gitcd ai.matey2. Install Dependencies
Section titled “2. Install Dependencies”npm installThis installs dependencies for all packages in the monorepo.
3. Set Up Environment
Section titled “3. Set Up Environment”Create a .env file for API keys (optional, needed for testing):
OPENAI_API_KEY=sk-...ANTHROPIC_API_KEY=sk-ant-...GEMINI_API_KEY=...GROQ_API_KEY=...Note: Never commit API keys! The .env file is gitignored.
4. Build All Packages
Section titled “4. Build All Packages”npm run buildThis builds all packages in dependency order using Turbo.
Monorepo Structure
Section titled “Monorepo Structure”ai.matey uses npm workspaces for package management and Turbo for build orchestration.
Workspaces
Section titled “Workspaces”{ "workspaces": [ "packages/*" ]}All packages are in packages/. Dependencies between packages are managed automatically.
Package Dependencies
Section titled “Package Dependencies”Packages have internal dependencies:
ai.matey.core → ai.matey.typesai.matey.frontend → ai.matey.typesai.matey.backend → ai.matey.typesai.matey.middleware → ai.matey.core, ai.matey.typesDevelopment Commands
Section titled “Development Commands”# Build all packagesnpm run build
# Build specific packagenpm run build --workspace=ai.matey.core
# Build in watch modenpm run dev# Run all testsnpm test
# Run tests for specific packagenpm test --workspace=ai.matey.core
# Run tests in watch modenpm test -- --watch
# Run tests with coveragenpm test -- --coverage# Check all packagesnpm run lint
# Auto-fix issuesnpm run lint:fix
# Lint specific packagenpm run lint --workspace=ai.matey.coreFormat
Section titled “Format”# Format all codenpm run format
# Check formattingnpm run format:check# Clean build artifactsnpm run clean
# Clean and rebuildnpm run clean && npm run buildWorking with Packages
Section titled “Working with Packages”Creating a New Package
Section titled “Creating a New Package”-
Create package directory:
Terminal window mkdir packages/ai.matey.newpackagecd packages/ai.matey.newpackage -
Initialize package.json:
{"name": "ai.matey.newpackage","version": "0.1.0","main": "./dist/index.js","types": "./dist/index.d.ts","scripts": {"build": "tsc","test": "jest"},"dependencies": {"ai.matey.types": "*"},"devDependencies": {"typescript": "^5.0.0","jest": "^29.0.0"}} -
Add tsconfig.json:
{"extends": "../../tsconfig.json","compilerOptions": {"outDir": "./dist","rootDir": "./src"},"include": ["src/**/*"]} -
Create source files:
Terminal window mkdir srctouch src/index.ts
Adding Dependencies
Section titled “Adding Dependencies”# Add to specific packagenpm install package-name --workspace=ai.matey.core
# Add to root (dev dependencies)npm install -D package-nameLinking Between Packages
Section titled “Linking Between Packages”Packages automatically link in the monorepo:
{ "dependencies": { "ai.matey.core": "*" // Uses local version }}TypeScript Configuration
Section titled “TypeScript Configuration”Root tsconfig.json
Section titled “Root tsconfig.json”{ "compilerOptions": { "target": "ES2020", "module": "commonjs", "lib": ["ES2020"], "declaration": true, "declarationMap": true, "sourceMap": true, "outDir": "./dist", "rootDir": "./src", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true }}Package-Specific Config
Section titled “Package-Specific Config”Packages extend the root config:
{ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "./dist", "rootDir": "./src" }, "include": ["src/**/*"], "references": [ { "path": "../ai.matey.types" } ]}Testing
Section titled “Testing”Test Structure
Section titled “Test Structure”Tests live alongside source code:
src/├── bridge.ts├── bridge.test.ts├── router.ts└── router.test.tsWriting Tests
Section titled “Writing Tests”import { Bridge } from './bridge';import { MockFrontendAdapter, MockBackendAdapter } from '../test-utils';
describe('Bridge', () => { let bridge: Bridge; let mockBackend: MockBackendAdapter;
beforeEach(() => { mockBackend = new MockBackendAdapter(); bridge = new Bridge( new MockFrontendAdapter(), mockBackend ); });
describe('chat()', () => { it('should process requests correctly', async () => { mockBackend.setResponse({ choices: [{ message: { content: 'Test response' } }] });
const response = await bridge.chat({ model: 'test', messages: [{ role: 'user', content: 'Test' }] });
expect(response.choices[0].message.content).toBe('Test response'); });
it('should handle errors', async () => { mockBackend.setError(new Error('API Error'));
await expect( bridge.chat({ model: 'test', messages: [{ role: 'user', content: 'Test' }] }) ).rejects.toThrow('API Error'); }); });
describe('chatStream()', () => { it('should stream responses', async () => { const stream = await bridge.chatStream({ model: 'test', messages: [{ role: 'user', content: 'Test' }], stream: true });
const chunks = []; for await (const chunk of stream) { chunks.push(chunk); }
expect(chunks.length).toBeGreaterThan(0); }); });});Test Utilities
Section titled “Test Utilities”Create mock adapters for testing:
export class MockBackendAdapter implements BackendAdapter { name = 'mock'; private response: any; private error: Error | null = null;
setResponse(response: any) { this.response = response; }
setError(error: Error) { this.error = error; }
async chat(request: IRChatCompletionRequest) { if (this.error) throw this.error; return this.response || { choices: [{ message: { content: 'Mock' } }] }; }
async *chatStream(request: IRChatCompletionRequest) { if (this.error) throw this.error; yield { choices: [{ delta: { content: 'Mock' } }] }; }}Debugging
Section titled “Debugging”VS Code Configuration
Section titled “VS Code Configuration”Create .vscode/launch.json:
{ "version": "0.2.0", "configurations": [ { "type": "node", "request": "launch", "name": "Debug Tests", "program": "${workspaceFolder}/node_modules/jest/bin/jest", "args": ["--runInBand", "--no-coverage"], "cwd": "${workspaceFolder}", "console": "integratedTerminal" }, { "type": "node", "request": "launch", "name": "Debug Current File", "program": "${file}", "cwd": "${workspaceFolder}", "console": "integratedTerminal" } ]}Debugging Tips
Section titled “Debugging Tips”- Use breakpoints in VS Code
- Add
debuggerstatements in code - Use console.log strategically
- Run tests in watch mode for quick feedback
Build System (Turbo)
Section titled “Build System (Turbo)”Turbo Configuration
Section titled “Turbo Configuration”{ "pipeline": { "build": { "dependsOn": ["^build"], "outputs": ["dist/**"] }, "test": { "dependsOn": ["build"], "outputs": [] }, "lint": { "outputs": [] } }}Caching
Section titled “Caching”Turbo caches build outputs. To clear cache:
npx turbo run build --forceCommon Tasks
Section titled “Common Tasks”Adding a New Backend Adapter
Section titled “Adding a New Backend Adapter”-
Create adapter file:
Terminal window cd packages/ai.matey.backendtouch src/adapters/newprovider.ts -
Implement adapter:
export class NewProviderBackendAdapter implements BackendAdapter {name = 'newprovider';// ... implementation} -
Add tests:
Terminal window touch src/adapters/newprovider.test.ts -
Export:
src/index.ts export { NewProviderBackendAdapter } from './adapters/newprovider'; -
Test:
Terminal window npm test --workspace=ai.matey.backend
Adding New Middleware
Section titled “Adding New Middleware”-
Create middleware file:
Terminal window cd packages/ai.matey.middlewaretouch src/newmiddleware.ts -
Implement:
export function createNewMiddleware(options) {return {name: 'new-middleware',async execute(request, next) {// Implementationreturn await next(request);}};} -
Test and export
Troubleshooting
Section titled “Troubleshooting”Build Failures
Section titled “Build Failures”# Clean and rebuildnpm run cleannpm installnpm run buildTest Failures
Section titled “Test Failures”# Run specific testnpm test -- bridge.test.ts
# Update snapshotsnpm test -- -uType Errors
Section titled “Type Errors”# Check typesnpx tsc --noEmit
# Rebuild typesnpm run build --workspace=ai.matey.typesDependency Issues
Section titled “Dependency Issues”# Clear npm cachenpm cache clean --force
# Reinstallrm -rf node_modulesnpm installBest Practices
Section titled “Best Practices”- Write tests first (TDD)
- Keep PRs focused - one feature/fix per PR
- Update docs with code changes
- Add examples for new features
- Run linter before committing
- Test edge cases
- Handle errors gracefully
Next Steps
Section titled “Next Steps”- Architecture Guide - Understanding the codebase
- Contributing Guide - General contribution guidelines
Happy coding! 🚀