diff --git a/packages/coding-agent/DEVELOPMENT.md b/packages/coding-agent/DEVELOPMENT.md index ad7c1487..e979d2ee 100644 --- a/packages/coding-agent/DEVELOPMENT.md +++ b/packages/coding-agent/DEVELOPMENT.md @@ -28,7 +28,7 @@ The coding-agent is structured into distinct layers: ▼ ┌─────────────────────────────────────────────────────────────┐ │ External Dependencies │ -│ @mariozechner/pi-agent-core (Agent, tools) │ +│ @mariozechner/pi-agent (Agent, tools) │ │ @mariozechner/pi-ai (models, providers) │ │ @mariozechner/pi-tui (TUI components) │ └─────────────────────────────────────────────────────────────┘ @@ -41,13 +41,16 @@ 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 @@ -57,34 +60,72 @@ src/ │ ├── 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 (Anthropic, etc.) -│ │ ├── anthropic.ts -│ │ ├── storage.ts -│ │ └── index.ts -│ └── tools/ # Tool implementations -│ ├── bash.ts, edit.ts, find.ts, grep.ts, ls.ts, read.ts, write.ts -│ ├── truncate.ts # Output truncation utilities -│ └── index.ts # Tool exports, allTools, codingTools +│ │ +│ ├── oauth/ # OAuth authentication +│ │ ├── index.ts # OAuth exports +│ │ ├── anthropic.ts # Anthropic OAuth (Claude Pro/Max) +│ │ ├── github-copilot.ts # GitHub Copilot OAuth +│ │ └── storage.ts # Token persistence +│ │ +│ ├── 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 (editor, selectors, etc.) -│ │ ├── assistant-message.ts -│ │ ├── bash-execution.ts -│ │ ├── custom-editor.ts -│ │ ├── footer.ts -│ │ ├── model-selector.ts -│ │ ├── session-selector.ts -│ │ └── ... (other selectors) +│ │ +│ ├── 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 @@ -94,8 +135,8 @@ src/ └── utils/ # Generic utilities ├── changelog.ts # parseChangelog(), getNewEntries() ├── clipboard.ts # copyToClipboard() - ├── config.ts # APP_NAME, VERSION, paths (getAgentDir, etc.) ├── fuzzy.ts # Fuzzy string matching + ├── mime.ts # MIME type detection ├── shell.ts # getShellConfig() └── tools-manager.ts # ensureTool() - download fd, etc. ``` @@ -111,6 +152,8 @@ The central abstraction that wraps the low-level `Agent` with: - Context compaction - Bash command execution - Message queuing +- Hook integration +- Custom tool loading All three modes (interactive, print, rpc) use AgentSession. @@ -130,7 +173,7 @@ Headless operation via JSON protocol over stdin/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. +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) @@ -147,6 +190,35 @@ Handles user preferences: - 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 @@ -173,7 +245,7 @@ npx tsx packages/coding-agent/src/cli.ts -p "Hello" npx tsx packages/coding-agent/src/cli.ts --mode rpc --no-session ``` -The watch build ensures changes to dependent packages (`pi-agent-core`, `pi-ai`, `pi-tui`) are automatically rebuilt. +The watch build ensures changes to dependent packages (`pi-agent`, `pi-ai`, `pi-tui`) are automatically rebuilt. ### Type Checking @@ -207,13 +279,19 @@ npm run build:binary 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` +5. Document in `docs/rpc.md` ### Adding a New Selector