docs: add README and AGENTS.md documentation
This commit is contained in:
@@ -0,0 +1,87 @@
|
|||||||
|
# Flynn AGENTS.md
|
||||||
|
|
||||||
|
## Build, Lint, and Test Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build
|
||||||
|
pnpm build # Compile TypeScript to dist/
|
||||||
|
|
||||||
|
# Development
|
||||||
|
pnpm dev # Run daemon with watch mode
|
||||||
|
pnpm tui # Run TUI in minimal mode (readline)
|
||||||
|
pnpm tui:fs # Run TUI in fullscreen mode (React/Ink)
|
||||||
|
pnpm tui:dev # Run TUI with watch mode
|
||||||
|
|
||||||
|
# Run
|
||||||
|
pnpm start # Start production build
|
||||||
|
|
||||||
|
# Testing
|
||||||
|
pnpm test # Run tests in watch mode
|
||||||
|
pnpm test:run # Run tests once (no watch)
|
||||||
|
|
||||||
|
# Linting and Type Checking
|
||||||
|
pnpm lint # Run ESLint
|
||||||
|
pnpm typecheck # Run TypeScript compiler (no emit)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Code Style Guidelines
|
||||||
|
|
||||||
|
### Imports
|
||||||
|
|
||||||
|
- Use `.js` extensions for imports (e.g., `import { readFileSync } from 'fs';`)
|
||||||
|
- Use `type` keyword for type-only imports: `import type { Config } from './schema.js';`
|
||||||
|
- Group imports: stdlib → third-party → local
|
||||||
|
- Export all public APIs from `index.ts`
|
||||||
|
|
||||||
|
### Naming Conventions
|
||||||
|
|
||||||
|
- **Classes/Interfaces/Types**: PascalCase (`AnthropicClient`, `NativeAgentConfig`)
|
||||||
|
- **Functions**: camelCase (`loadConfig`, `expandEnvVars`)
|
||||||
|
- **Private fields**: camelCase with underscore (`_client`, `_model`)
|
||||||
|
- **Files**: camelCase for .ts files, PascalCase for .tsx files
|
||||||
|
- **Test files**: `*.test.ts` suffix
|
||||||
|
|
||||||
|
### TypeScript Configuration
|
||||||
|
|
||||||
|
- `tsconfig.json` uses strict mode
|
||||||
|
- Target: ES2022
|
||||||
|
- Module resolution: NodeNext
|
||||||
|
- Module format: NodeNext
|
||||||
|
- Enables `declaration`, `declarationMap`, and `sourceMap` for all builds
|
||||||
|
|
||||||
|
### Error Handling
|
||||||
|
|
||||||
|
- Throw errors with descriptive messages
|
||||||
|
- Check for undefined/null with context: `throw new Error('Environment variable ${envVar} is not set')`
|
||||||
|
- In stream handlers, wrap errors in try-catch and yield error events
|
||||||
|
- Use `instanceof Error` for error type checking: `error instanceof Error ? error.message : 'Unknown error'`
|
||||||
|
- Catch errors and convert to appropriate error types with context
|
||||||
|
|
||||||
|
### React/Ink Patterns
|
||||||
|
|
||||||
|
- Use `useCallback` for event handlers to prevent unnecessary re-renders
|
||||||
|
- Use `useRef` for mutable values that don't trigger re-renders
|
||||||
|
- Define interface props explicitly
|
||||||
|
- Event handlers receive `(inputChar: string, key: KeyInfo)` as arguments
|
||||||
|
|
||||||
|
### Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
src/
|
||||||
|
├── config/ # YAML config + validation
|
||||||
|
├── models/ # Model providers + router
|
||||||
|
├── session/ # SQLite persistence
|
||||||
|
├── hooks/ # Confirmation engine
|
||||||
|
├── daemon/ # Lifecycle management
|
||||||
|
├── frontends/ # Telegram bot, TUI
|
||||||
|
└── backends/native/ # Agent implementation
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
- Use Vitest for testing
|
||||||
|
- Follow `describe`/`it` pattern
|
||||||
|
- Use `expect()` for assertions
|
||||||
|
- Test both success and failure cases
|
||||||
|
- Clean up test resources (files, dirs) in `afterEach` or `it` cleanup blocks
|
||||||
|
- Mock file system and environment variables when needed
|
||||||
@@ -0,0 +1,205 @@
|
|||||||
|
# Flynn
|
||||||
|
|
||||||
|
Self-hosted personal AI assistant with Telegram and Terminal interfaces.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **Multi-Frontend**: Telegram bot + Terminal UI (minimal & fullscreen modes)
|
||||||
|
- **Multi-Model**: Anthropic Claude, OpenAI, Ollama with intelligent routing
|
||||||
|
- **Model Switching**: Switch between cloud/local models on demand
|
||||||
|
- **Session Persistence**: SQLite-backed conversation history
|
||||||
|
- **Fallback Chains**: Automatic failover when primary model fails
|
||||||
|
- **Hook Engine**: Confirmation system for sensitive operations
|
||||||
|
- **Session Transfer**: Move conversations between frontends
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install dependencies
|
||||||
|
pnpm install
|
||||||
|
|
||||||
|
# Copy and configure
|
||||||
|
cp config/default.yaml ~/.config/flynn/config.yaml
|
||||||
|
# Edit config with your API keys and Telegram bot token
|
||||||
|
|
||||||
|
# Build and run
|
||||||
|
pnpm build
|
||||||
|
pnpm start
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Config location: `~/.config/flynn/config.yaml` (or set `FLYNN_CONFIG`)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
telegram:
|
||||||
|
bot_token: "your-telegram-bot-token"
|
||||||
|
allowed_chat_ids: [123456789] # Your Telegram user ID
|
||||||
|
|
||||||
|
models:
|
||||||
|
default:
|
||||||
|
provider: anthropic
|
||||||
|
model: claude-opus-4-5-20251101
|
||||||
|
api_key: sk-ant-api03-...
|
||||||
|
local:
|
||||||
|
provider: ollama
|
||||||
|
model: qwen2.5:14b
|
||||||
|
fallback_chain: [local]
|
||||||
|
|
||||||
|
hooks:
|
||||||
|
confirm: [shell.*, file.write]
|
||||||
|
log: [web.*, file.read]
|
||||||
|
silent: [notify]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Model Providers
|
||||||
|
|
||||||
|
| Provider | Config |
|
||||||
|
|----------|--------|
|
||||||
|
| Anthropic | `provider: anthropic`, `api_key` or `auth_token` |
|
||||||
|
| OpenAI | `provider: openai`, `api_key`, optional `endpoint` |
|
||||||
|
| Ollama | `provider: ollama`, `model`, optional `endpoint` |
|
||||||
|
|
||||||
|
### Model Tiers
|
||||||
|
|
||||||
|
Configure multiple models for different purposes:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
models:
|
||||||
|
fast: { provider: anthropic, model: claude-sonnet-4-... }
|
||||||
|
default: { provider: anthropic, model: claude-opus-4-5-... }
|
||||||
|
complex: { provider: anthropic, model: claude-opus-4-5-... }
|
||||||
|
local: { provider: ollama, model: qwen2.5:14b }
|
||||||
|
```
|
||||||
|
|
||||||
|
## Telegram Commands
|
||||||
|
|
||||||
|
| Command | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| `/start` | Initialize bot |
|
||||||
|
| `/reset` | Clear conversation history |
|
||||||
|
| `/status` | Show current model and status |
|
||||||
|
| `/local` | Switch to local model |
|
||||||
|
| `/cloud` | Switch to cloud model |
|
||||||
|
| `/model` | Show model info and options |
|
||||||
|
|
||||||
|
## Terminal UI
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Minimal mode (readline)
|
||||||
|
pnpm tui
|
||||||
|
|
||||||
|
# Fullscreen mode (React/Ink)
|
||||||
|
pnpm tui:fs
|
||||||
|
```
|
||||||
|
|
||||||
|
### TUI Commands
|
||||||
|
|
||||||
|
| Command | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| `/help` | Show help |
|
||||||
|
| `/reset` | Clear history |
|
||||||
|
| `/status` | Show session info |
|
||||||
|
| `/fullscreen` | Switch to fullscreen mode |
|
||||||
|
| `/transfer telegram` | Transfer session to Telegram |
|
||||||
|
| `/quit` | Exit |
|
||||||
|
|
||||||
|
## Running as Service
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create systemd user service
|
||||||
|
mkdir -p ~/.config/systemd/user
|
||||||
|
|
||||||
|
cat > ~/.config/systemd/user/flynn.service << 'EOF'
|
||||||
|
[Unit]
|
||||||
|
Description=Flynn Personal AI Assistant
|
||||||
|
After=network.target ollama.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
WorkingDirectory=/path/to/flynn
|
||||||
|
ExecStart=/usr/bin/pnpm start
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
Environment=NODE_ENV=production
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Enable and start
|
||||||
|
systemctl --user daemon-reload
|
||||||
|
systemctl --user enable --now flynn
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
journalctl --user -u flynn -f
|
||||||
|
```
|
||||||
|
|
||||||
|
## Hook Engine
|
||||||
|
|
||||||
|
Control sensitive operations with pattern matching:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
hooks:
|
||||||
|
confirm: # Requires user approval via Telegram
|
||||||
|
- shell.*
|
||||||
|
- file.write
|
||||||
|
log: # Logs but doesn't block
|
||||||
|
- web.*
|
||||||
|
- file.read
|
||||||
|
silent: # Executes without notification
|
||||||
|
- notify
|
||||||
|
```
|
||||||
|
|
||||||
|
## Session Management
|
||||||
|
|
||||||
|
- Sessions persist in `~/.local/share/flynn/sessions.db`
|
||||||
|
- Session ID format: `{frontend}:{userId}` (e.g., `telegram:123456789`)
|
||||||
|
- History survives restarts
|
||||||
|
- Transfer sessions between frontends with `/transfer`
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
src/
|
||||||
|
├── index.ts # Daemon entry
|
||||||
|
├── tui.ts # TUI entry
|
||||||
|
├── config/ # YAML config + validation
|
||||||
|
├── models/ # Model providers + router
|
||||||
|
├── backends/native/ # Agent implementation
|
||||||
|
├── session/ # SQLite persistence
|
||||||
|
├── hooks/ # Confirmation engine
|
||||||
|
├── daemon/ # Lifecycle management
|
||||||
|
└── frontends/
|
||||||
|
├── telegram/ # Telegram bot
|
||||||
|
└── tui/ # Terminal UI
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Dev mode with watch
|
||||||
|
pnpm dev # Daemon
|
||||||
|
pnpm tui:dev # TUI
|
||||||
|
|
||||||
|
# Type check
|
||||||
|
pnpm typecheck
|
||||||
|
|
||||||
|
# Lint
|
||||||
|
pnpm lint
|
||||||
|
|
||||||
|
# Test
|
||||||
|
pnpm test
|
||||||
|
```
|
||||||
|
|
||||||
|
## Environment Variables
|
||||||
|
|
||||||
|
| Variable | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| `FLYNN_CONFIG` | Override config path |
|
||||||
|
| `ANTHROPIC_API_KEY` | Anthropic API key (fallback) |
|
||||||
|
| `OPENAI_API_KEY` | OpenAI API key (fallback) |
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT
|
||||||
Reference in New Issue
Block a user