Files
flynn/CONTRIBUTING.md
William Valentin 8a6cd7f559 docs: Add comprehensive documentation for production deployment and contribution
This commit adds 6 new documentation files to fill critical gaps:

- CONTRIBUTING.md: Developer onboarding guide with setup, workflow,
  code style, testing, and adding features

- TROUBLESHOOTING.md: Common issues and solutions for errors,
  model issues, tool issues, channel issues, gateway issues,
  configuration issues, and memory/database issues

- docs/api/PROTOCOL.md: Gateway JSON-RPC protocol documentation
  with connection, authentication, message format, methods,
  events, error codes, and example client implementation

- docs/api/TOOLS.md: Tools API documentation covering tool interface,
  input schema format, result format, tool patterns,
  tool registration, tool policy, execution flow, and
  builtin tools reference

- docs/deployment/PRODUCTION.md: Production deployment guide
  covering Docker deployment, systemd service, security,
  configuration, monitoring, backup & recovery, and
  performance tuning

- docs/performance/TUNING.md: Performance optimization guide
  covering context management, model routing, tool execution,
  memory & embeddings, session management, database
  performance, gateway performance, and resource usage

These files complement the existing excellent documentation
(README.md, AGENTS.md, ARCHITECTURE.md, STRUCTURE.md,
CONVENTIONS.md) to provide complete coverage for users,
developers, and operators.
2026-02-13 16:07:29 -08:00

492 lines
11 KiB
Markdown

# Contributing to Flynn
Thank you for your interest in contributing to Flynn! This guide will help you get started.
## Table of Contents
- [Quick Start](#quick-start)
- [Development Setup](#development-setup)
- [Development Workflow](#development-workflow)
- [Code Style](#code-style)
- [Testing](#testing)
- [Adding Features](#adding-features)
- [Commit Guidelines](#commit-guidelines)
- [Submitting Changes](#submitting-changes)
- [Getting Help](#getting-help)
## Quick Start
```bash
# Clone the repository
git clone <repo-url>
cd flynn
# Install dependencies
pnpm install
# Build the project
pnpm build
# Run the daemon
pnpm start
```
## Development Setup
### Prerequisites
- **Node.js** >= 22.0.0
- **pnpm** (package manager)
- **Docker** (optional, for sandbox features)
### Installation
```bash
# Install dependencies
pnpm install
# Verify TypeScript compiles
pnpm typecheck
# Run linter
pnpm lint
# Run tests
pnpm test
```
### Development Commands
| Command | Description |
|---------|-------------|
| `pnpm build` | Compile TypeScript to `dist/` |
| `pnpm dev` | Run daemon with watch mode (tsx watch) |
| `pnpm start` | Start production build |
| `pnpm tui` | Minimal TUI (readline) |
| `pnpm tui:fs` | Fullscreen TUI (React/Ink) |
| `pnpm test` | Run vitest in watch mode |
| `pnpm test:run` | Run tests once (CI) |
| `pnpm lint` | Run ESLint |
| `pnpm typecheck` | TypeScript check (no emit) |
### Running a Single Test File
```bash
pnpm test:run src/path/to/file.test.ts
```
### Configuration for Development
Create a development config:
```bash
cp config/default.yaml ~/.config/flynn/config.yaml
# Edit config with your API keys and settings
```
## Development Workflow
### Branching Strategy
1. **Main branch**: `main` - stable production code
2. **Feature branches**: `feature/description` - new features
3. **Bugfix branches**: `bugfix/description` - bug fixes
4. **Refactor branches**: `refactor/description` - code improvements
### Feature Development
1. Create a feature branch from `main`
```bash
git checkout -b feature/my-new-feature
```
2. Make your changes
3. Build and test
```bash
pnpm build
pnpm test
pnpm lint
pnpm typecheck
```
4. Commit your changes (see [Commit Guidelines](#commit-guidelines))
5. Push and create a pull request
### Committing Changes
Before committing, ensure:
- All tests pass: `pnpm test:run`
- Linting passes: `pnpm lint`
- Type checking passes: `pnpm typecheck`
- Build succeeds: `pnpm build`
```bash
git add .
git commit -m "feat: add my new feature"
```
## Code Style
Flynn follows specific conventions documented in [`.planning/codebase/CONVENTIONS.md`](.planning/codebase/CONVENTIONS.md).
### Key Guidelines
- **2-space indentation** (no tabs)
- **Single quotes** for strings
- **Trailing commas** in multiline structures
- **Semicolons** always used
- **camelCase** for functions/variables
- **PascalCase** for classes/interfaces
- **kebab-case** for source files (`my-feature.ts`)
- **PascalCase** for React components (`MyComponent.tsx`)
- Test files co-located with source: `file.test.ts` beside `file.ts`
### Import Organization
```typescript
// 1. Node.js stdlib
import { readFileSync } from 'fs';
import { execFile } from 'child_process';
// 2. Third-party packages
import Anthropic from '@anthropic-ai/sdk';
import { z } from 'zod';
// 3. Local imports (always use .js extension)
import { NativeAgent } from './agent.js';
import type { Config } from '../config/schema.js';
```
### Error Handling
```typescript
// Pattern 1: Return ToolResult with error (tools)
try {
const result = await someOperation();
return { success: true, output: result };
} catch (error) {
return {
success: false,
output: '',
error: error instanceof Error ? error.message : String(error),
};
}
// Pattern 2: Throw with descriptive message (config/setup)
if (envValue === undefined) {
throw new Error(`Environment variable ${envVar} is not set`);
}
```
## Testing
### Test Framework
Flynn uses **Vitest** for testing. Test files are co-located with source files:
```
src/
├── agent.ts
├── agent.test.ts
├── models/
│ ├── anthropic.ts
│ └── anthropic.test.ts
```
### Writing Tests
```typescript
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { MyComponent } from './my-component.js';
describe('MyComponent', () => {
beforeEach(() => {
// Setup before each test
});
afterEach(() => {
// Cleanup after each test
});
it('should do something correctly', () => {
const result = MyComponent.doSomething();
expect(result).toBe('expected-value');
});
it('should handle errors gracefully', () => {
expect(() => MyComponent.doSomethingInvalid()).toThrow();
});
});
```
### Testing Guidelines
- Test both success and failure cases
- Clean up resources (files, directories) in `afterEach` or `it` blocks
- Mock external dependencies (APIs, databases, filesystem)
- Use `describe`/`it` pattern for organization
- Keep tests focused and independent
### Running Tests
```bash
# Watch mode (during development)
pnpm test
# Run once (CI/pre-commit)
pnpm test:run
# Run specific test file
pnpm test:run src/models/anthropic.test.ts
# Run tests matching pattern
pnpm test -- --grep "anthropic"
```
## Adding Features
### Adding a New Tool
Flynn tools follow three patterns:
#### Pattern 1: Static Tool (no dependencies)
```typescript
// src/tools/builtin/my-tool.ts
import type { Tool, ToolResult } from '../types.js';
interface MyToolArgs {
input: string;
}
export const myTool: Tool = {
name: 'my.tool',
description: 'Description of what this tool does',
inputSchema: {
type: 'object',
properties: {
input: { type: 'string', description: 'Input parameter' },
},
required: ['input'],
},
execute: async (rawArgs: unknown): Promise<ToolResult> => {
const args = rawArgs as MyToolArgs;
// Implementation
return { success: true, output: 'result' };
},
};
```
#### Pattern 2: Factory Tool (needs dependency injection)
```typescript
// src/tools/builtin/memory-read.ts
import type { Tool, ToolResult } from '../types.js';
import type { MemoryStore } from '../../memory/store.js';
export function createMemoryReadTool(store: MemoryStore): Tool {
return {
name: 'memory.read',
description: 'Read from memory store',
inputSchema: {
type: 'object',
properties: {
namespace: { type: 'string', description: 'Memory namespace' },
},
required: ['namespace'],
},
execute: async (rawArgs: unknown): Promise<ToolResult> => {
const args = rawArgs as { namespace: string };
try {
const content = store.read(args.namespace);
return { success: true, output: content };
} catch (error) {
return {
success: false,
output: '',
error: error instanceof Error ? error.message : String(error),
};
}
},
};
}
```
#### Pattern 3: Multi-Factory (related tool set)
```typescript
// src/tools/builtin/index.ts
export function createMemoryTools(store: MemoryStore, hybridSearch?: HybridSearch): Tool[] {
return [
createMemoryReadTool(store),
createMemoryWriteTool(store),
createMemorySearchTool(store, hybridSearch),
];
}
```
**Registration Steps:**
1. Add export to `src/tools/builtin/index.ts`
2. Add export to `src/tools/index.ts`
3. Register in `src/daemon/index.ts` (call factory + register)
4. Add to tool profiles in `src/tools/policy.ts` if needed
5. Write tests in `src/tools/builtin/my-tool.test.ts`
### Adding a New Channel Adapter
1. Create directory: `src/channels/<platform>/`
2. Create `adapter.ts` implementing `ChannelAdapter` interface
3. Create `index.ts` re-exporting the adapter
4. Add test: `adapter.test.ts`
5. Register in `src/channels/index.ts`
6. Register in `src/daemon/index.ts`
7. Add config schema in `src/config/schema.ts`
### Adding a New Model Provider
1. Create `src/models/<provider>.ts` implementing `ModelClient` interface
2. Add export to `src/models/index.ts`
3. Add case in `src/daemon/index.ts` → `createClientFromConfig()`
4. Add to `src/config/schema.ts` → `modelConfigBaseSchema.provider` enum
5. Write tests in `src/models/<provider>.test.ts`
### Adding a New CLI Command
```typescript
// src/cli/my-cmd.ts
import { Command } from 'commander';
import { loadConfigSafe } from './shared.js';
export function registerMyCommand(program: Command) {
program
.command('my-cmd')
.description('Description of my command')
.option('-c, --config <path>', 'Config file path')
.action(async (options) => {
const configResult = await loadConfigSafe(options.config);
if (configResult.error) {
console.error(configResult.error);
process.exit(1);
}
// Implementation
});
}
```
Register in `src/cli/index.ts`:
```typescript
import { registerMyCommand } from './my-cmd.js';
// In registerCommands()
registerMyCommand(program);
```
## Commit Guidelines
### Commit Message Format
Follow conventional commits:
```
<type>(<scope>): <description>
[optional body]
[optional footer]
```
### Types
- `feat`: New feature
- `fix`: Bug fix
- `refactor`: Code refactoring (no functional change)
- `docs`: Documentation changes
- `test`: Test additions/modifications
- `chore`: Build process, dependencies, tooling
- `style`: Code style changes (formatting, semicolons, etc.)
### Examples
```
feat(tools): add image analysis tool
Implements image analysis using OpenAI Vision API.
Closes #123
fix(gateway): handle WebSocket disconnection gracefully
Prevents infinite loop when connection drops during event emission.
docs(readme): update quick start instructions
Clarify configuration steps for new users.
test(models): add Anthropic client retry tests
Verify exponential backoff and fallback behavior.
```
## Submitting Changes
### Pull Request Process
1. Ensure your branch is up to date with `main`
```bash
git fetch origin
git rebase origin/main
```
2. Push your branch
```bash
git push -u origin feature/my-new-feature
```
3. Create a pull request with:
- Clear description of changes
- Reference related issues
- Screenshots if UI changes
- Test results
- Breaking changes noted
### Code Review Checklist
Before submitting, verify:
- [ ] All tests pass (`pnpm test:run`)
- [ ] Linting passes (`pnpm lint`)
- [ ] Type checking passes (`pnpm typecheck`)
- [ ] Build succeeds (`pnpm build`)
- [ ] New features have tests
- [ ] Documentation updated (README, AGENTS.md, code comments)
- [ ] No console.log or debugger statements
- [ ] Sensitive data not committed (API keys, tokens)
- [ ] Commit messages follow format
## Getting Help
### Documentation
- **Architecture**: [`.planning/codebase/ARCHITECTURE.md`](.planning/codebase/ARCHITECTURE.md)
- **Structure**: [`.planning/codebase/STRUCTURE.md`](.planning/codebase/STRUCTURE.md)
- **Conventions**: [`.planning/codebase/CONVENTIONS.md`](.planning/codebase/CONVENTIONS.md)
- **Developer Guide**: [`AGENTS.md`](AGENTS.md)
- **User Documentation**: [`README.md`](README.md)
### Troubleshooting
See [`TROUBLESHOOTING.md`](TROUBLESHOOTING.md) for common issues and solutions.
### Questions?
- Open an issue for bugs or feature requests
- Start a discussion for questions
- Check existing issues and discussions first
---
Thank you for contributing to Flynn!