mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-22 02:03:42 +00:00
Remove obsolete DEVELOPMENT.md
This commit is contained in:
parent
c6f496441c
commit
ce637f3ea4
1 changed files with 0 additions and 339 deletions
|
|
@ -1,339 +0,0 @@
|
||||||
# coding-agent Development Guide
|
|
||||||
|
|
||||||
This document describes the architecture and development workflow for the coding-agent package.
|
|
||||||
|
|
||||||
## Architecture Overview
|
|
||||||
|
|
||||||
The coding-agent is structured into distinct layers:
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────┐
|
|
||||||
│ CLI Layer │
|
|
||||||
│ cli.ts → main.ts → cli/args.ts, cli/file-processor.ts │
|
|
||||||
└─────────────────────────────────────────────────────────────┘
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
┌─────────────────────────────────────────────────────────────┐
|
|
||||||
│ Mode Layer │
|
|
||||||
│ modes/interactive/ modes/print-mode.ts modes/rpc/ │
|
|
||||||
└─────────────────────────────────────────────────────────────┘
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
┌─────────────────────────────────────────────────────────────┐
|
|
||||||
│ Core Layer │
|
|
||||||
│ core/agent-session.ts (central abstraction) │
|
|
||||||
│ core/session-manager.ts, core/model-config.ts, etc. │
|
|
||||||
└─────────────────────────────────────────────────────────────┘
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
┌─────────────────────────────────────────────────────────────┐
|
|
||||||
│ External Dependencies │
|
|
||||||
│ @mariozechner/pi-agent (Agent, tools) │
|
|
||||||
│ @mariozechner/pi-ai (models, providers) │
|
|
||||||
│ @mariozechner/pi-tui (TUI components) │
|
|
||||||
└─────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
## Directory Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
src/
|
|
||||||
├── cli.ts # CLI entry point (shebang, calls main)
|
|
||||||
├── main.ts # Main orchestration, argument handling, mode routing
|
|
||||||
├── index.ts # Public API exports
|
|
||||||
├── config.ts # APP_NAME, VERSION, paths (getAgentDir, etc.)
|
|
||||||
|
|
||||||
├── cli/ # CLI-specific utilities
|
|
||||||
│ ├── args.ts # parseArgs(), printHelp(), Args interface
|
|
||||||
│ ├── file-processor.ts # processFileArguments() for @file args
|
|
||||||
│ ├── list-models.ts # --list-models implementation
|
|
||||||
│ └── session-picker.ts # selectSession() TUI for --resume
|
|
||||||
|
|
||||||
├── core/ # Core business logic (mode-agnostic)
|
|
||||||
│ ├── index.ts # Core exports
|
|
||||||
│ ├── agent-session.ts # AgentSession class - THE central abstraction
|
|
||||||
│ ├── bash-executor.ts # executeBash() with streaming, abort
|
|
||||||
│ ├── compaction.ts # Context compaction logic
|
|
||||||
│ ├── export-html.ts # exportSession(), exportFromFile()
|
|
||||||
│ ├── messages.ts # BashExecutionMessage, messageTransformer
|
|
||||||
│ ├── model-config.ts # findModel(), getAvailableModels(), getApiKeyForModel()
|
|
||||||
│ ├── model-resolver.ts # resolveModelScope(), restoreModelFromSession()
|
|
||||||
│ ├── session-manager.ts # SessionManager class - JSONL persistence
|
|
||||||
│ ├── settings-manager.ts # SettingsManager class - user preferences
|
|
||||||
│ ├── skills.ts # loadSkills(), skill discovery from multiple locations
|
|
||||||
│ ├── slash-commands.ts # loadSlashCommands() from ~/.pi/agent/commands/
|
|
||||||
│ ├── system-prompt.ts # buildSystemPrompt(), loadProjectContextFiles()
|
|
||||||
│ │
|
|
||||||
│ ├── oauth/ # OAuth authentication (thin wrapper)
|
|
||||||
│ │ └── index.ts # Re-exports from @mariozechner/pi-ai with convenience wrappers
|
|
||||||
│ │
|
|
||||||
│ ├── hooks/ # Hook system for extending behavior
|
|
||||||
│ │ ├── index.ts # Hook exports
|
|
||||||
│ │ ├── types.ts # HookAPI, HookContext, event types
|
|
||||||
│ │ ├── loader.ts # loadHooks() from multiple locations
|
|
||||||
│ │ ├── runner.ts # runHook() event dispatch
|
|
||||||
│ │ └── tool-wrapper.ts # wrapToolsWithHooks() for tool_call events
|
|
||||||
│ │
|
|
||||||
│ ├── custom-tools/ # Custom tool loading system
|
|
||||||
│ │ ├── index.ts # Custom tool exports
|
|
||||||
│ │ ├── types.ts # CustomToolFactory, CustomToolDefinition
|
|
||||||
│ │ └── loader.ts # loadCustomTools() from multiple locations
|
|
||||||
│ │
|
|
||||||
│ └── tools/ # Built-in tool implementations
|
|
||||||
│ ├── index.ts # Tool exports, allTools, codingTools
|
|
||||||
│ ├── bash.ts # Bash command execution
|
|
||||||
│ ├── edit.ts # Surgical file editing
|
|
||||||
│ ├── find.ts # File search by glob
|
|
||||||
│ ├── grep.ts # Content search (regex/literal)
|
|
||||||
│ ├── ls.ts # Directory listing
|
|
||||||
│ ├── read.ts # File reading (text and images)
|
|
||||||
│ ├── write.ts # File writing
|
|
||||||
│ ├── path-utils.ts # Path resolution utilities
|
|
||||||
│ └── truncate.ts # Output truncation utilities
|
|
||||||
|
|
||||||
├── modes/ # Run mode implementations
|
|
||||||
│ ├── index.ts # Re-exports InteractiveMode, runPrintMode, runRpcMode, RpcClient
|
|
||||||
│ ├── print-mode.ts # Non-interactive: process messages, print output, exit
|
|
||||||
│ │
|
|
||||||
│ ├── rpc/ # RPC mode for programmatic control
|
|
||||||
│ │ ├── rpc-mode.ts # runRpcMode() - JSON stdin/stdout protocol
|
|
||||||
│ │ ├── rpc-types.ts # RpcCommand, RpcResponse, RpcSessionState types
|
|
||||||
│ │ └── rpc-client.ts # RpcClient class for spawning/controlling agent
|
|
||||||
│ │
|
|
||||||
│ └── interactive/ # Interactive TUI mode
|
|
||||||
│ ├── interactive-mode.ts # InteractiveMode class
|
|
||||||
│ │
|
|
||||||
│ ├── components/ # TUI components
|
|
||||||
│ │ ├── assistant-message.ts # Agent response rendering
|
|
||||||
│ │ ├── bash-execution.ts # Bash output display
|
|
||||||
│ │ ├── compaction.ts # Compaction status display
|
|
||||||
│ │ ├── custom-editor.ts # Multi-line input editor
|
|
||||||
│ │ ├── dynamic-border.ts # Adaptive border rendering
|
|
||||||
│ │ ├── footer.ts # Status bar / footer
|
|
||||||
│ │ ├── hook-input.ts # Hook input dialog
|
|
||||||
│ │ ├── hook-selector.ts # Hook selection UI
|
|
||||||
│ │ ├── model-selector.ts # Model picker
|
|
||||||
│ │ ├── oauth-selector.ts # OAuth provider picker
|
|
||||||
│ │ ├── queue-mode-selector.ts # Message queue mode picker
|
|
||||||
│ │ ├── session-selector.ts # Session browser for --resume
|
|
||||||
│ │ ├── show-images-selector.ts # Image display toggle
|
|
||||||
│ │ ├── theme-selector.ts # Theme picker
|
|
||||||
│ │ ├── thinking-selector.ts # Thinking level picker
|
|
||||||
│ │ ├── tool-execution.ts # Tool call/result rendering
|
|
||||||
│ │ ├── user-message-selector.ts # Message selector for /branch
|
|
||||||
│ │ └── user-message.ts # User message rendering
|
|
||||||
│ │
|
|
||||||
│ └── theme/
|
|
||||||
│ ├── theme.ts # Theme loading, getEditorTheme(), etc.
|
|
||||||
│ ├── dark.json
|
|
||||||
│ ├── light.json
|
|
||||||
│ └── theme-schema.json
|
|
||||||
|
|
||||||
└── utils/ # Generic utilities
|
|
||||||
├── changelog.ts # parseChangelog(), getNewEntries()
|
|
||||||
├── clipboard.ts # copyToClipboard()
|
|
||||||
├── fuzzy.ts # Fuzzy string matching
|
|
||||||
├── mime.ts # MIME type detection
|
|
||||||
├── shell.ts # getShellConfig()
|
|
||||||
└── tools-manager.ts # ensureTool() - download fd, etc.
|
|
||||||
```
|
|
||||||
|
|
||||||
## Key Abstractions
|
|
||||||
|
|
||||||
### AgentSession (core/agent-session.ts)
|
|
||||||
|
|
||||||
The central abstraction that wraps the low-level `Agent` with:
|
|
||||||
- Session persistence (via SessionManager)
|
|
||||||
- Settings persistence (via SettingsManager)
|
|
||||||
- Model cycling with scoped models
|
|
||||||
- Context compaction
|
|
||||||
- Bash command execution
|
|
||||||
- Message queuing
|
|
||||||
- Hook integration
|
|
||||||
- Custom tool loading
|
|
||||||
|
|
||||||
All three modes (interactive, print, rpc) use AgentSession.
|
|
||||||
|
|
||||||
### InteractiveMode (modes/interactive/interactive-mode.ts)
|
|
||||||
|
|
||||||
Handles TUI rendering and user interaction:
|
|
||||||
- Subscribes to AgentSession events
|
|
||||||
- Renders messages, tool executions, streaming
|
|
||||||
- Manages editor, selectors, key handlers
|
|
||||||
- Delegates all business logic to AgentSession
|
|
||||||
|
|
||||||
### RPC Mode (modes/rpc/)
|
|
||||||
|
|
||||||
Headless operation via JSON protocol over stdin/stdout:
|
|
||||||
|
|
||||||
- **rpc-mode.ts**: `runRpcMode()` function that listens for JSON commands on stdin and emits responses/events on stdout
|
|
||||||
- **rpc-types.ts**: Typed protocol definitions (`RpcCommand`, `RpcResponse`, `RpcSessionState`)
|
|
||||||
- **rpc-client.ts**: `RpcClient` class for spawning the agent as a subprocess and controlling it programmatically
|
|
||||||
|
|
||||||
The RPC mode exposes the full AgentSession API via JSON commands. See [docs/rpc.md](docs/rpc.md) for protocol documentation.
|
|
||||||
|
|
||||||
### SessionManager (core/session-manager.ts)
|
|
||||||
|
|
||||||
Handles session persistence:
|
|
||||||
- JSONL format for append-only writes
|
|
||||||
- Session file location management
|
|
||||||
- Message loading/saving
|
|
||||||
- Model/thinking level persistence
|
|
||||||
|
|
||||||
### SettingsManager (core/settings-manager.ts)
|
|
||||||
|
|
||||||
Handles user preferences:
|
|
||||||
- Default model/provider
|
|
||||||
- Theme selection
|
|
||||||
- Queue mode
|
|
||||||
- Thinking block visibility
|
|
||||||
- Compaction settings
|
|
||||||
- Hook/custom tool paths
|
|
||||||
|
|
||||||
### Hook System (core/hooks/)
|
|
||||||
|
|
||||||
Extensibility layer for intercepting agent behavior:
|
|
||||||
- **loader.ts**: Discovers and loads hooks from `~/.pi/agent/hooks/`, `.pi/hooks/`, and CLI
|
|
||||||
- **runner.ts**: Dispatches events to registered hooks
|
|
||||||
- **tool-wrapper.ts**: Wraps tools to emit `tool_call` and `tool_result` events
|
|
||||||
- **types.ts**: Event types (`session`, `tool_call`, `tool_result`, `message`, `error`)
|
|
||||||
|
|
||||||
See [docs/hooks.md](docs/hooks.md) for full documentation.
|
|
||||||
|
|
||||||
### Custom Tools (core/custom-tools/)
|
|
||||||
|
|
||||||
System for adding LLM-callable tools:
|
|
||||||
- **loader.ts**: Discovers and loads tools from `~/.pi/agent/tools/`, `.pi/tools/`, and CLI
|
|
||||||
- **types.ts**: `CustomToolFactory`, `CustomToolDefinition`, `CustomToolResult`
|
|
||||||
|
|
||||||
See [docs/custom-tools.md](docs/custom-tools.md) for full documentation.
|
|
||||||
|
|
||||||
### Skills (core/skills.ts)
|
|
||||||
|
|
||||||
On-demand capability packages:
|
|
||||||
- Discovers SKILL.md files from multiple locations
|
|
||||||
- Provides specialized workflows and instructions
|
|
||||||
- Loaded when task matches description
|
|
||||||
|
|
||||||
See [docs/skills.md](docs/skills.md) for full documentation.
|
|
||||||
|
|
||||||
## Development Workflow
|
|
||||||
|
|
||||||
### Running in Development
|
|
||||||
|
|
||||||
Start the watch build in the monorepo root to continuously rebuild all packages:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Terminal 1: Watch build (from monorepo root)
|
|
||||||
npm run dev
|
|
||||||
```
|
|
||||||
|
|
||||||
Then run the CLI with tsx in a separate terminal:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Terminal 2: Run CLI (from monorepo root)
|
|
||||||
npx tsx packages/coding-agent/src/cli.ts
|
|
||||||
|
|
||||||
# With arguments
|
|
||||||
npx tsx packages/coding-agent/src/cli.ts --help
|
|
||||||
npx tsx packages/coding-agent/src/cli.ts -p "Hello"
|
|
||||||
|
|
||||||
# RPC mode
|
|
||||||
npx tsx packages/coding-agent/src/cli.ts --mode rpc --no-session
|
|
||||||
```
|
|
||||||
|
|
||||||
The watch build ensures changes to dependent packages (`pi-agent`, `pi-ai`, `pi-tui`) are automatically rebuilt.
|
|
||||||
|
|
||||||
### Type Checking
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# From monorepo root
|
|
||||||
npm run check
|
|
||||||
```
|
|
||||||
|
|
||||||
### Building
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Build all packages
|
|
||||||
npm run build
|
|
||||||
|
|
||||||
# Build standalone binary
|
|
||||||
cd packages/coding-agent
|
|
||||||
npm run build:binary
|
|
||||||
```
|
|
||||||
|
|
||||||
## Adding New Features
|
|
||||||
|
|
||||||
### Adding a New Slash Command
|
|
||||||
|
|
||||||
1. If it's a UI-only command (e.g., `/theme`), add handler in `interactive-mode.ts` `setupEditorSubmitHandler()`
|
|
||||||
2. If it needs session logic, add method to `AgentSession` and call from mode
|
|
||||||
|
|
||||||
### Adding a New Tool
|
|
||||||
|
|
||||||
1. Create tool in `core/tools/` following existing patterns
|
|
||||||
2. Export from `core/tools/index.ts`
|
|
||||||
3. Add to `allTools` and optionally `codingTools`
|
|
||||||
4. Add description to `toolDescriptions` in `core/system-prompt.ts`
|
|
||||||
|
|
||||||
### Adding a New Hook Event
|
|
||||||
|
|
||||||
1. Add event type to `HookEvent` union in `core/hooks/types.ts`
|
|
||||||
2. Add emission point in relevant code (AgentSession, tool wrapper, etc.)
|
|
||||||
3. Document in `docs/hooks.md`
|
|
||||||
|
|
||||||
### Adding a New RPC Command
|
|
||||||
|
|
||||||
1. Add command type to `RpcCommand` union in `rpc-types.ts`
|
|
||||||
2. Add response type to `RpcResponse` union in `rpc-types.ts`
|
|
||||||
3. Add handler case in `handleCommand()` switch in `rpc-mode.ts`
|
|
||||||
4. Add client method in `RpcClient` class in `rpc-client.ts`
|
|
||||||
5. Document in `docs/rpc.md`
|
|
||||||
|
|
||||||
### Adding a New Selector
|
|
||||||
|
|
||||||
1. Create component in `modes/interactive/components/`
|
|
||||||
2. Use `showSelector()` helper in `interactive-mode.ts`:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
private showMySelector(): void {
|
|
||||||
this.showSelector((done) => {
|
|
||||||
const selector = new MySelectorComponent(
|
|
||||||
// ... params
|
|
||||||
(result) => {
|
|
||||||
// Handle selection
|
|
||||||
done();
|
|
||||||
this.showStatus(`Selected: ${result}`);
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
done();
|
|
||||||
this.ui.requestRender();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
return { component: selector, focus: selector.getSelectList() };
|
|
||||||
});
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
The package uses E2E tests only (no unit tests by design). Tests are in `test/`:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Run all tests
|
|
||||||
npm test
|
|
||||||
|
|
||||||
# Run specific test pattern
|
|
||||||
npm test -- --testNamePattern="RPC"
|
|
||||||
|
|
||||||
# Run RPC example interactively
|
|
||||||
npx tsx test/rpc-example.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
## Code Style
|
|
||||||
|
|
||||||
- No `any` types unless absolutely necessary
|
|
||||||
- No inline dynamic imports
|
|
||||||
- Use `showStatus()` for dim status messages
|
|
||||||
- Use `showError()` / `showWarning()` for errors/warnings
|
|
||||||
- Keep InteractiveMode focused on UI, delegate logic to AgentSession
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue