diff --git a/README.md b/README.md index 6f5a859..550e995 100644 --- a/README.md +++ b/README.md @@ -306,7 +306,22 @@ In practice, that means you can start small, branch out when a task gets bigger, ## Documentation -The root README is the quick-start guide. Use the docs folder for deeper detail: +Full user-facing documentation lives in [`docs/documentation/`](docs/documentation/index.md): + +| Page | Description | +|---|---| +| [Getting Started](docs/documentation/getting-started.md) | Installation, first run, and initial configuration | +| [Commands](docs/documentation/commands.md) | Complete CLI command and flag reference | +| [Interactive Mode](docs/documentation/interactive-mode.md) | TUI, REPL, slash commands, keyboard shortcuts | +| [Configuration](docs/documentation/configuration.md) | Config files, TOML format, and environment variables | +| [Providers](docs/documentation/providers.md) | LLM provider setup — MiniMax, Anthropic, OpenAI, OpenRouter | +| [Tools](docs/documentation/tools.md) | All agent tools — file ops, search, shell, web, and more | +| [Sessions](docs/documentation/sessions.md) | Session lifecycle, persistence, resume, and management | +| [Permissions](docs/documentation/permissions.md) | Approval system, permission modes, and safe mode | +| [Skills](docs/documentation/skills.md) | Skill discovery, installation, and authoring | +| [Advanced](docs/documentation/advanced.md) | Sub-agents, MCP servers, hooks, orchestration, and IPC | + +Internal design docs: - [Product Requirements](docs/prd.md) - [Tech Stack](docs/tech-stack.md) diff --git a/docs/documentation/advanced.md b/docs/documentation/advanced.md new file mode 100644 index 0000000..af2151c --- /dev/null +++ b/docs/documentation/advanced.md @@ -0,0 +1,423 @@ +# Advanced + +Sub-agents, MCP integration, lifecycle hooks, orchestration, memory, and IPC. + +## Sub-Agents + +nca can spawn child agent sessions to handle tasks in parallel. The parent agent uses the `spawn_subagent` tool to delegate work. + +### How Sub-Agents Work + +``` +Parent Session +├── spawn_subagent(task: "write tests for auth") +│ └── Child Session (new session ID) +│ ├── Inherits conversation context summary +│ ├── Runs in isolated git worktree (optional) +│ ├── Uses bypass-permissions (no interactive prompts) +│ ├── Executes the task autonomously +│ └── Returns result to parent +└── Continues with child's output +``` + +### Spawning + +The agent calls `spawn_subagent` with: + +```json +{ + "task": "Write comprehensive tests for the authentication module", + "focus_files": ["src/auth.rs", "src/auth/middleware.rs"], + "use_worktree": true +} +``` + +### Git Worktrees + +When `use_worktree` is true (default), the child session runs in an isolated git worktree: + +- Worktree path: `/.nca/worktrees/` +- Branch: `nca/` (created from current `HEAD`) +- Changes in the worktree don't affect the parent's working directory + +### Child Session Behavior + +- **Permissions:** `bypass-permissions` (no interactive approval needed) +- **Approvals:** Auto-deny handler (no blocking waits) +- **Context:** Inherits a summary of the parent's last ~10 messages +- **Timeout:** 600 seconds (10 minutes) +- **Lineage:** Parent and child session IDs are cross-referenced in metadata + +### Viewing Sub-Agents + +``` +/agents # List child sessions in interactive mode +``` + +```bash +nca sessions --search "child" # Find sub-agent sessions via CLI +``` + +### Sub-Agent Events + +| Event | Description | +|-------|-------------| +| `ChildSessionSpawned` | Child session created | +| `ChildSessionCompleted` | Child session finished | +| `ChildSessionActivity` | Intermediate activity from child | + +--- + +## MCP Servers + +nca supports the [Model Context Protocol](https://modelcontextprotocol.io/) for integrating external tool servers. + +### Configuration + +Add MCP servers in your config: + +```toml +[[mcp.servers]] +name = "filesystem" +command = "npx" +args = ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"] +enabled = true + +[[mcp.servers]] +name = "database" +command = "npx" +args = ["-y", "@modelcontextprotocol/server-postgres"] +env = { DATABASE_URL = "postgresql://localhost/mydb" } +enabled = true + +[[mcp.servers]] +name = "custom" +command = "/usr/local/bin/my-mcp-server" +args = ["--port", "3000"] +cwd = "/opt/my-server" +env = { API_KEY = "secret" } +enabled = true +``` + +### MCP Server Config Fields + +| Field | Type | Default | Description | +|-------|------|---------|-------------| +| `name` | string | **required** | Server identifier (used in tool names) | +| `command` | string | **required** | Command to start the server | +| `args` | string[] | `[]` | Command arguments | +| `env` | map | `{}` | Environment variables | +| `cwd` | string | — | Working directory | +| `enabled` | bool | `true` | Whether the server is active | + +### How MCP Tools Appear + +MCP tools are exposed with the naming convention: + +``` +mcp____ +``` + +For example, a server named `database` with a tool `query` becomes `mcp__database__query`. + +### Listing MCP Servers + +```bash +nca mcp # CLI +nca mcp --json # JSON output +``` + +``` +/mcp # Interactive mode +``` + +### Safe Mode + +By default, MCP tools are **not available** in safe mode. To allow them: + +```toml +[mcp] +expose_in_safe_mode = true +``` + +--- + +## Lifecycle Hooks + +Hooks let you run shell commands at various points in the session lifecycle. + +### Available Hook Points + +| Hook | When It Fires | +|------|---------------| +| `session_start` | Session begins | +| `session_end` | Session ends | +| `pre_tool_use` | Before a tool executes | +| `post_tool_use` | After a tool succeeds | +| `post_tool_failure` | After a tool fails | +| `approval_requested` | When user approval is needed | +| `subagent_start` | When a sub-agent is spawned | +| `subagent_stop` | When a sub-agent completes | + +### Configuration + +```toml +[[hooks.session_start]] +command = "echo 'Session started' >> /tmp/nca.log" +blocking = false + +[[hooks.pre_tool_use]] +command = "my-audit-script --tool $NCA_TOOL_NAME" +matcher = "execute_bash" # Only fire for bash tool +blocking = true # Wait for completion before proceeding + +[[hooks.session_end]] +command = "notify-send 'nca session ended'" +blocking = false +``` + +### Hook Fields + +| Field | Type | Default | Description | +|-------|------|---------|-------------| +| `command` | string | **required** | Shell command to execute | +| `matcher` | string | `""` | Regex pattern to filter when the hook fires | +| `blocking` | bool | `false` | Whether to wait for the hook to complete | + +--- + +## Persistent Memory + +The memory system stores notes that persist across sessions. + +### CLI Commands + +```bash +nca memory # List all notes +nca memory list --json # JSON output +nca memory add "prefer async/await patterns" # Add a note +nca memory add "uses PostgreSQL" --kind note # With type +``` + +### Interactive Commands + +``` +/memory # List notes +/memory always use anyhow for error handling # Add a note +``` + +### Configuration + +```toml +[memory] +file_path = ".nca/memory.json" # Storage location +max_notes = 128 # Maximum number of notes +``` + +### How Memory Works + +- Notes are stored as JSON in the workspace +- Notes are included in the agent's context on each turn +- The agent can reference stored notes for consistency across sessions +- Notes are workspace-scoped (stored in `.nca/memory.json`) + +--- + +## Orchestration + +nca can be driven by external orchestrators (CI systems, automation scripts, custom tooling) via environment variables and structured output. + +### Orchestration Environment Variables + +Set these to inject orchestration context into the session: + +```bash +export NCA_ORCH_NAME="github-actions" +export NCA_ORCH_RUN_ID="run-123" +export NCA_ORCH_TASK_ID="task-456" +export NCA_ORCH_TASK_REF="PR-42" +export NCA_ORCH_PARENT_RUN_ID="parent-run-789" +export NCA_ORCH_CALLBACK_URL="https://my-ci/callback" +export NCA_ORCH_META_REPO="my-org/my-repo" +export NCA_ORCH_META_BRANCH="feature/auth" +``` + +Orchestration metadata is: +- Stored in session state +- Injected into the system prompt +- Available to hooks + +### Headless Execution + +For CI/automation, combine orchestration with non-interactive flags: + +```bash +nca run \ + --prompt "run tests and report results" \ + --permission-mode bypass-permissions \ + --json \ + --stream ndjson +``` + +### NDJSON Event Stream + +Use `--stream ndjson` to get machine-readable events: + +```bash +nca run --prompt "fix the build" --stream ndjson | while read -r event; do + echo "$event" | jq '.event_type' +done +``` + +Each line is a JSON object with: +- `id` — monotonic event ID +- `ts` — timestamp +- Event-specific fields (message content, tool calls, approvals, etc.) + +--- + +## IPC Protocol + +Running sessions expose a Unix domain socket for external control. + +### Socket Location + +``` +$XDG_RUNTIME_DIR/nca/.sock +# Fallback: +/tmp/nca/.sock +``` + +### Protocol + +Newline-delimited JSON over Unix domain socket. + +**Server → Client (events):** + +Events are broadcast as `EventEnvelope` objects: + +```json +{"id": 1, "ts": "2026-04-02T10:30:00Z", "event": {"type": "MessageReceived", ...}} +{"id": 2, "ts": "2026-04-02T10:30:01Z", "event": {"type": "ToolCallStarted", ...}} +``` + +**Client → Server (commands):** + +```json +{"type": "SendMessage", "content": "continue with the refactoring"} +{"type": "ApproveToolCall", "call_id": "abc123"} +{"type": "DenyToolCall", "call_id": "abc123"} +{"type": "AnswerQuestion", "question_id": "q1", "answer": "option-a"} +{"type": "Cancel"} +{"type": "Shutdown"} +``` + +### Event Types + +| Event | Description | +|-------|-------------| +| `SessionStarted` | Session initialized | +| `SessionEnded` | Session finished (with reason) | +| `MessageReceived` | User or assistant message | +| `TokensStreamed` | Streaming token delta | +| `CostUpdated` | Token usage update | +| `ToolCallStarted` | Tool execution began | +| `ToolCallCompleted` | Tool execution finished | +| `ApprovalRequested` | Waiting for user approval | +| `ApprovalResolved` | Approval decision made | +| `QuestionRequested` | Agent asking user a question | +| `QuestionResolved` | Question answered | +| `ChildSessionSpawned` | Sub-agent created | +| `ChildSessionCompleted` | Sub-agent finished | +| `ChildSessionActivity` | Sub-agent intermediate activity | +| `ContextWarning` | Context window getting full | +| `ContextCompaction` | Context was compacted | +| `BusyStateChanged` | Agent state changed (Thinking, Streaming, Idle) | +| `Checkpoint` | Session checkpoint saved | +| `Error` | Error occurred | + +--- + +## Custom Instructions + +nca loads instructions from multiple sources, merged in order: + +### Loading Order + +1. **Built-in system prompt** — nca's core behavior rules (disable with `harness.built_in_enabled = false`) +2. **`AGENTS.md`** — project-level instructions in the workspace root +3. **`.ncarc`** — nca-specific project instructions (configurable path) +4. **`.nca/instructions.md`** — personal local instructions (gitignored) +5. **Skills** — available skills listed for on-demand invocation +6. **Orchestration context** — injected when orchestration env vars are present + +### `AGENTS.md` + +Placed in the workspace root. Compatible with other AI tools (Claude Code, etc.): + +```markdown +## Project Rules + +- Use axum for HTTP servers +- All errors must use thiserror +- Write tests for every public function +``` + +### `.ncarc` + +nca-specific project instructions: + +```markdown +## Stack + +- Rust + Tokio async runtime +- PostgreSQL via sqlx +- Redis via deadpool-redis + +## Conventions + +- Module names are snake_case +- Error types end with Error +- Tests live in the same file as the code +``` + +### `.nca/instructions.md` + +Personal instructions (add to `.gitignore`): + +```markdown +## My Preferences + +- I prefer verbose variable names +- Always add doc comments to public items +- Use `tracing` for logging, not `log` +``` + +--- + +## Auto-Research + +nca includes an auto-research feature for automated investigation: + +```bash +nca autoresearch once [--workspace ] +``` + +This runs a single automated research pass on a program or topic, generating structured output in the workspace. + +--- + +## Doctor Command + +Run diagnostics to verify your setup: + +```bash +nca doctor +``` + +Checks: +- Configuration file validity +- API key availability for configured providers +- Provider connectivity +- Required tool dependencies (git, rg) +- File system permissions diff --git a/docs/documentation/commands.md b/docs/documentation/commands.md new file mode 100644 index 0000000..a723167 --- /dev/null +++ b/docs/documentation/commands.md @@ -0,0 +1,371 @@ +# Commands + +Complete reference for all `nca` CLI commands, subcommands, and flags. + +## Global Usage (No Subcommand) + +```bash +nca [OPTIONS] +``` + +When invoked without a subcommand, nca starts an interactive session. Behavior depends on flags: + +| Flag | Short | Type | Default | Description | +|------|-------|------|---------|-------------| +| `--prompt` | `-p` | string | — | Run a one-shot prompt and exit | +| `--safe` | `-s` | flag | false | Start in read-only safe mode | +| `--resume` | `-r` | flag | false | Resume the most recent session | +| `--no-resume` | — | flag | false | Force a new session (skip auto-resume) | +| `--run` | — | flag | false | Start interactive run mode | +| `--model` | — | string | — | Override the default model | +| `--enable-thinking` | `-t` | flag | false | Enable extended thinking/reasoning | +| `--thinking-budget` | — | u32 | 5120 | Token budget for extended thinking | +| `--max-tokens` | — | u32 | 8192 | Max response tokens | +| `--verbose` | `-v` | flag | false | Verbose debug logging | +| `--json` | — | flag | false | Output structured JSON (for CI) | +| `--stream` | — | enum | `human` | Stream format: `human`, `ndjson`, or `off` | +| `--no-tui` | — | flag | false | Use line-oriented REPL instead of full-screen TUI | +| `--permission-mode` | — | enum | — | Permission mode (see [Permissions](./permissions.md)) | +| `--max-turns` | — | u32 | — | Max agent turns per run | + +### Examples + +```bash +# Start interactive TUI session +nca + +# One-shot prompt +nca -p "refactor the error handling in src/lib.rs" + +# Safe mode (read-only analysis) +nca -s + +# Resume last session +nca -r + +# Force new session +nca --no-resume + +# Use a specific model +nca --model "claude-3-7-sonnet-latest" + +# Enable thinking with custom budget +nca -t --thinking-budget 10000 + +# CI-friendly JSON output +nca -p "list all TODO comments" --json + +# NDJSON event stream +nca -p "fix the tests" --stream ndjson + +# Line REPL (no full-screen TUI) +nca --no-tui + +# Bypass all permission prompts +nca --permission-mode bypass-permissions +``` + +--- + +## Subcommands + +### `nca run` + +Run a one-shot task with explicit stream control. + +```bash +nca run --prompt "..." [OPTIONS] +``` + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `--prompt` | string | **required** | The task to execute | +| `--stream` | enum | `human` | Stream format: `human`, `ndjson`, `off` | +| `--model` | string | — | Override model | +| `--json` | flag | false | Structured JSON output | +| `--safe` | flag | false | Read-only mode | +| `--permission-mode` | enum | — | Permission mode | + +```bash +nca run --prompt "add input validation" --stream ndjson +nca run --prompt "analyze code quality" --safe --json +``` + +--- + +### `nca spawn` + +Launch a background session that runs without interactive input. + +```bash +nca spawn --prompt "..." [OPTIONS] +``` + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `--prompt` | string | **required** | The task to execute | +| `--model` | string | — | Override model | +| `--safe` | flag | false | Read-only mode | +| `--json` | flag | false | Structured JSON output | +| `--permission-mode` | enum | `accept-edits` | Permission mode | + +```bash +nca spawn --prompt "write comprehensive tests for the auth module" +nca spawn --prompt "document all public APIs" --model "MiniMax-M2.7" +``` + +--- + +### `nca sessions` + +List and filter saved sessions. + +```bash +nca sessions [OPTIONS] +``` + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `--json` | flag | false | JSON output | +| `--status` | enum | — | Filter by status: `running`, `completed`, `cancelled`, `failed` | +| `--since-hours` | u32 | — | Show sessions from the last N hours | +| `--search` | string | — | Search sessions by text | +| `--limit` | usize | 20 | Max number of sessions to show | + +```bash +nca sessions +nca sessions --status running +nca sessions --since-hours 24 --limit 5 +nca sessions --search "auth" --json +``` + +--- + +### `nca resume` + +Resume a previously saved session. + +```bash +nca resume [OPTIONS] +``` + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `--prompt` | string | — | Send a follow-up prompt after resuming | +| `--model` | string | — | Override model for this session | +| `--safe` | flag | false | Resume in read-only mode | +| `--stream` | enum | `human` | Stream format | +| `--no-tui` | flag | false | Use line REPL | +| `--permission-mode` | enum | — | Permission mode | + +```bash +nca resume abc123 +nca resume abc123 --prompt "continue where you left off" +nca resume abc123 --model "claude-3-7-sonnet-latest" +``` + +--- + +### `nca logs` + +Stream or dump the event log for a session. + +```bash +nca logs [OPTIONS] +``` + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `--follow` | flag | false | Follow the log in real-time (like `tail -f`) | +| `--json` | flag | false | Raw JSON output | + +```bash +nca logs abc123 +nca logs abc123 --follow +nca logs abc123 --json +``` + +--- + +### `nca attach` + +Attach to a running session's output stream. + +```bash +nca attach [--json] +``` + +--- + +### `nca status` + +Show metadata for a session. + +```bash +nca status [--json] +``` + +--- + +### `nca cancel` + +Cancel a running session. + +```bash +nca cancel [--json] +``` + +--- + +### `nca skills` + +Manage agent skills. + +```bash +nca skills [--json] # List all discovered skills +nca skills list [--json] # Same as above +nca skills add [OPTIONS] +nca skills remove [OPTIONS] +nca skills update [NAME] # Update one or all skills +``` + +**`nca skills add`:** + +| Flag | Short | Type | Default | Description | +|------|-------|------|---------|-------------| +| `--skill` | `-s` | string[] | all | Specific skills to install (repeatable) | +| `--global` | `-g` | flag | false | Install globally to `~/.nca/skills/` | + +**`nca skills remove`:** + +| Flag | Short | Type | Default | Description | +|------|-------|------|---------|-------------| +| `--global` | `-g` | flag | false | Remove from global skills | + +```bash +nca skills +nca skills add https://github.com/user/skill-repo -s rust-patterns +nca skills remove rust-patterns --global +nca skills update +``` + +--- + +### `nca mcp` + +List configured MCP (Model Context Protocol) servers. + +```bash +nca mcp [--json] +``` + +--- + +### `nca memory` + +Manage persistent memory notes. + +```bash +nca memory [--json] # List memory notes +nca memory list [--json] # Same as above +nca memory add [--kind ] +``` + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `--kind` | string | `note` | Type of memory entry | + +```bash +nca memory +nca memory add "prefer async/await over thread spawning" +nca memory add "API uses bearer token auth" --kind note +``` + +--- + +### `nca models` + +List available models for the current provider. + +```bash +nca models [--json] +``` + +--- + +### `nca doctor` + +Run diagnostic checks on your configuration. + +```bash +nca doctor [--json] +``` + +Checks API key availability, provider connectivity, config file validity, and tool dependencies. + +--- + +### `nca config` + +Display the current runtime configuration. + +```bash +nca config [--json] +``` + +--- + +### `nca completion` + +Generate shell completion scripts. + +```bash +nca completion +``` + +Supported shells: `bash`, `zsh`, `fish`, `power-shell`, `elvish`. Default: `bash`. + +--- + +### `nca index` + +Manage the CLI index cache (used for agent self-awareness of available commands). + +```bash +nca index build [--json] +nca index show [--json] +``` + +--- + +### `nca autoresearch` + +Run automated research on a program/topic. + +```bash +nca autoresearch once [--workspace ] +``` + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `--workspace` | path | current directory | Workspace for research output | + +--- + +## Stream Modes + +The `--stream` flag controls output format: + +| Mode | Description | +|------|-------------| +| `human` | Terminal-friendly output with colors, markdown rendering, and TUI support (default) | +| `ndjson` | Newline-delimited JSON events — one event per line, for machine consumption | +| `off` | Minimal output — final result only | + +## Exit Codes + +| Code | Meaning | +|------|---------| +| 0 | Success | +| 1 | General error (provider failure, config issue, etc.) | +| non-zero | Task failure or cancellation | diff --git a/docs/documentation/configuration.md b/docs/documentation/configuration.md new file mode 100644 index 0000000..85bac9d --- /dev/null +++ b/docs/documentation/configuration.md @@ -0,0 +1,305 @@ +# Configuration + +nca uses a layered TOML configuration system with environment variable overrides. + +## Config File Locations + +| File | Scope | Description | +|------|-------|-------------| +| `~/.nca/config.toml` | Global | User-wide defaults | +| `/.nca/config.local.toml` | Workspace | Project-specific overrides | + +Settings merge in order: **defaults → global → workspace → environment variables**. Later sources override earlier ones. + +## Full Configuration Reference + +### `[provider]` — LLM Provider Settings + +```toml +[provider] +default = "minimax" # "minimax" | "openrouter" | "anthropic" | "openai" + +[provider.minimax] +api_key_env = "MINIMAX_API_KEY" # Environment variable to read +api_key = "" # Or set directly (not recommended) +base_url = "https://api.minimax.io/anthropic" +model = "MiniMax-M2.7" +temperature = 0.7 + +[provider.openai] +api_key_env = "OPENAI_API_KEY" +base_url = "https://api.openai.com" +model = "gpt-4o-mini" +temperature = 0.7 + +[provider.anthropic] +api_key_env = "ANTHROPIC_API_KEY" +base_url = "https://api.anthropic.com" +model = "claude-3-7-sonnet-latest" +temperature = 1.0 + +[provider.openrouter] +api_key_env = "OPENROUTER_API_KEY" +base_url = "https://openrouter.ai/api" +model = "openai/gpt-4o-mini" +temperature = 0.7 +site_url = "" # Optional referrer URL +app_name = "" # Optional app name header +``` + +### `[model]` — Model Settings + +```toml +[model] +default_model = "MiniMax-M2.7" +max_tokens = 8192 +enable_thinking = false +thinking_budget = 5120 + +[model.aliases] +# Built-in aliases (pre-configured): +# default → MiniMax-M2.7 +# minimax → MiniMax-M2.7 +# m2.7 → MiniMax-M2.7 +# coding → MiniMax-M2.7 +# reasoning → MiniMax-M2.7 +# openai → gpt-4o-mini +# gpt4o → gpt-4o +# claude → claude-3-7-sonnet-latest +# openrouter → openai/gpt-4o-mini + +# Add your own: +fast = "gpt-4o-mini" +smart = "claude-3-7-sonnet-latest" +``` + +### `[permissions]` — Permission System + +```toml +[permissions] +mode = "default" # "default" | "plan" | "accept-edits" | "dont-ask" | "bypass-permissions" + +# Pattern-based allow/deny lists (supports wildcards) +allow = [] # e.g., ["execute_bash:cargo *", "write_file:src/*"] +deny = [] # e.g., ["execute_bash:rm *", "delete_path:*"] +ask = [] # Force ask for specific patterns +``` + +See [Permissions](./permissions.md) for full details on each mode. + +### `[session]` — Session Management + +```toml +[session] +history_dir = ".nca/sessions" # Relative to workspace +max_turns_per_run = 128 # Max agent turns per session run +max_tool_calls_per_turn = 200 # Max tool calls in a single turn +checkpoint_interval = 5 # Save checkpoint every N turns +last_session_file = ".nca/.last_session" +auto_compact_on_finish = false # Auto-summarize when session ends +``` + +### `[harness]` — System Prompt and Instructions + +```toml +[harness] +built_in_enabled = true # Include nca's built-in system prompt +project_instructions_path = ".ncarc" # Project instructions file +local_instructions_path = ".nca/instructions.md" # Local (personal) instructions +skill_directories = [".nca/skills", ".claude/skills"] # Skill discovery paths +``` + +### `[mcp]` — Model Context Protocol + +```toml +[mcp] +expose_in_safe_mode = false # Allow MCP tools in safe/read-only mode + +[[mcp.servers]] +name = "my-server" +command = "npx" +args = ["-y", "@my/mcp-server"] +env = { API_KEY = "..." } +cwd = "/optional/working/directory" +enabled = true +``` + +### `[memory]` — Persistent Memory + +```toml +[memory] +file_path = ".nca/memory.json" +max_notes = 128 +auto_compact_on_finish = false + +[memory.context] +context_window_target = 0 # 0 = auto-detect from provider +auto_detect_context_window = true +query_provider_models_api = true # Fetch model limits from provider API +max_retained_messages = 50 +auto_summarize_threshold = 75 # Percentage of context window used before summarizing +enable_auto_summarize = true +``` + +### `[hooks]` — Lifecycle Hooks + +```toml +# Shell commands that run at various lifecycle points +[hooks] +session_start = [] +session_end = [] +pre_tool_use = [] +post_tool_use = [] +post_tool_failure = [] +approval_requested = [] +subagent_start = [] +subagent_stop = [] +``` + +Each hook is an object with: + +```toml +[[hooks.session_start]] +command = "echo 'session started'" +matcher = "" # Optional regex to match on +blocking = false # If true, waits for completion +``` + +### `[web]` — Web Request Settings + +```toml +[web] +timeout_secs = 15 +max_fetch_chars = 25000 +default_search_limit = 5 +user_agent = "nca/0.5 (+https://github.com/user/native-cli-ai)" +``` + +### `[ui]` — Interface Settings + +```toml +[ui] +editor = "" # External editor command (e.g., "vim", "code --wait") +theme = "" # UI theme (optional) +hide_tips = false # Hide usage tips +scroll_speed = 3 # Scroll speed in TUI +onboarding_completed = false +``` + +--- + +## Environment Variables + +Environment variables override config file values. + +### Provider Selection and Keys + +| Variable | Description | +|----------|-------------| +| `NCA_DEFAULT_PROVIDER` | Override default provider (`minimax`, `openrouter`, `anthropic`, `openai`) | +| `NCA_MODEL` | Override the active model | +| `MINIMAX_API_KEY` | MiniMax API key | +| `MINIMAX_BASE_URL` | MiniMax API base URL | +| `MINIMAX_MODEL` | MiniMax model name | +| `OPENAI_API_KEY` | OpenAI API key | +| `OPENAI_BASE_URL` | OpenAI-compatible base URL | +| `OPENAI_MODEL` | OpenAI model name | +| `ANTHROPIC_API_KEY` | Anthropic API key | +| `ANTHROPIC_BASE_URL` | Anthropic API base URL | +| `ANTHROPIC_MODEL` | Anthropic model name | +| `OPENROUTER_API_KEY` | OpenRouter API key | +| `OPENROUTER_BASE_URL` | OpenRouter base URL | +| `OPENROUTER_MODEL` | OpenRouter model name | +| `OPENROUTER_SITE_URL` | OpenRouter site URL header | +| `OPENROUTER_APP_NAME` | OpenRouter app name header | + +### Runtime Behavior + +| Variable | Description | +|----------|-------------| +| `NCA_EDITOR` | Override external editor command | +| `NCA_EDITOR_MODE` | Set to `vi` or `vim` for vi keybindings in REPL | +| `NCA_MEMORY_PATH` | Override memory file path | +| `NCA_WEB_TIMEOUT_SECS` | Override web request timeout | +| `NCA_WEB_MAX_FETCH_CHARS` | Override max characters for web fetches | +| `NCA_DEBUG_REQUEST` | Enable debug logging for MiniMax requests | +| `NCA_SKIP_CONTEXT_API` | Set to `1` to skip provider model API queries | +| `NCA_CONTEXT_API_CACHE_TTL_SECS` | Cache TTL for model context API | +| `XDG_RUNTIME_DIR` | IPC socket directory (fallback: `/tmp/nca/`) | + +### Orchestration (CI/Automation) + +| Variable | Description | +|----------|-------------| +| `NCA_ORCH_NAME` | Orchestrator name | +| `NCA_ORCH_RUN_ID` | Orchestration run identifier | +| `NCA_ORCH_TASK_ID` | Task identifier | +| `NCA_ORCH_TASK_REF` | Task reference | +| `NCA_ORCH_PARENT_RUN_ID` | Parent run ID | +| `NCA_ORCH_CALLBACK_URL` | Callback URL for orchestrator | +| `NCA_ORCH_META_*` | Arbitrary metadata (prefix stripped, key lowercased) | + +--- + +## Example Configurations + +### Minimal Setup + +```toml +# ~/.nca/config.toml +[provider] +default = "minimax" + +[provider.minimax] +api_key = "your-key-here" +``` + +### Multi-Provider Setup + +```toml +# ~/.nca/config.toml +[provider] +default = "minimax" + +[provider.minimax] +api_key_env = "MINIMAX_API_KEY" + +[provider.anthropic] +api_key_env = "ANTHROPIC_API_KEY" + +[provider.openai] +api_key_env = "OPENAI_API_KEY" + +[model.aliases] +fast = "gpt-4o-mini" +smart = "claude-3-7-sonnet-latest" +default = "MiniMax-M2.7" +``` + +### CI/Automation Setup + +```toml +# .nca/config.local.toml (in the project) +[permissions] +mode = "bypass-permissions" + +[session] +max_turns_per_run = 50 +auto_compact_on_finish = true +``` + +### Workspace with Custom Instructions and MCP + +```toml +# .nca/config.local.toml +[harness] +project_instructions_path = ".ncarc" +local_instructions_path = ".nca/instructions.md" + +[[mcp.servers]] +name = "database" +command = "npx" +args = ["-y", "@modelcontextprotocol/server-postgres"] +env = { DATABASE_URL = "postgresql://localhost/mydb" } +enabled = true +``` diff --git a/docs/documentation/getting-started.md b/docs/documentation/getting-started.md new file mode 100644 index 0000000..0caf11c --- /dev/null +++ b/docs/documentation/getting-started.md @@ -0,0 +1,146 @@ +# Getting Started + +## Prerequisites + +- **Rust toolchain** — install via [rustup](https://rustup.rs/) (edition 2024, stable channel) +- **Git** — required for session worktrees and version control integration +- **ripgrep (`rg`)** — used by the `search_code` tool for fast code search +- **An LLM API key** — MiniMax (default), Anthropic, OpenAI, or OpenRouter + +## Installation + +### Build from Source + +```bash +git clone https://github.com/madebyaris/native-cli-ai.git +cd native-cli-ai + +# Build optimized release binary +cargo build --release + +# Install to your PATH +cp target/release/nca /usr/local/bin/ +``` + +The release profile is optimized for size and speed (`opt-level = 3`, `lto = "thin"`, `strip = true`). + +### Verify Installation + +```bash +nca doctor +``` + +This runs configuration checks and reports any issues with your setup. + +## Initial Setup + +### 1. Set an API Key + +The fastest way to get started is to export your API key: + +```bash +# MiniMax (default provider) +export MINIMAX_API_KEY="your-key-here" + +# Or use another provider +export ANTHROPIC_API_KEY="your-key-here" +export OPENAI_API_KEY="your-key-here" +export OPENROUTER_API_KEY="your-key-here" +``` + +To persist the key, add it to your shell profile (`~/.zshrc`, `~/.bashrc`) or store it in the config file: + +```toml +# ~/.nca/config.toml +[provider.minimax] +api_key = "your-key-here" +``` + +### 2. First Run + +Navigate to any project directory and launch nca: + +```bash +cd ~/my-project +nca +``` + +On first launch, nca runs an **onboarding flow** that helps you: +- Select your default LLM provider +- Enter your API key +- Confirm basic settings + +After onboarding, you enter the interactive TUI where you can start chatting with the agent. + +### 3. One-Shot Mode + +For quick tasks without entering the interactive session: + +```bash +nca -p "explain the architecture of this project" +nca -p "add a health check endpoint to the API" +``` + +## Directory Structure + +nca creates a `.nca/` directory in your workspace for local state: + +``` +my-project/ +├── .nca/ +│ ├── config.local.toml # Workspace-specific config overrides +│ ├── instructions.md # Local instructions for the agent +│ ├── .last_session # Pointer to the most recent session +│ ├── memory.json # Persistent memory notes +│ ├── sessions/ # Session state and event logs +│ │ ├── .json # Session state snapshot +│ │ └── .events.jsonl # Event log (NDJSON) +│ ├── worktrees/ # Git worktrees for sub-agents +│ └── skills/ # Local skill definitions +├── .ncarc # Project-level instructions +├── AGENTS.md # Agent instructions (also used by other AI tools) +└── ... +``` + +Global config lives at `~/.nca/config.toml`. + +## Custom Instructions + +You can guide the agent's behavior with instruction files, loaded in this order: + +1. **Built-in system prompt** — nca's default behavior rules +2. **`AGENTS.md`** — project-level instructions (compatible with other AI tools) +3. **`.ncarc`** — project-level nca-specific instructions +4. **`.nca/instructions.md`** — personal local instructions (gitignored) + +Example `.ncarc`: + +```markdown +## Project Context + +This is a REST API built with Axum. Use PostgreSQL for data storage. +Always run `cargo test` after making changes. +Prefer the `anyhow` crate for error handling. +``` + +## Shell Completions + +Generate shell completions for your shell: + +```bash +# Bash +nca completion bash > /etc/bash_completion.d/nca + +# Zsh +nca completion zsh > ~/.zsh/completions/_nca + +# Fish +nca completion fish > ~/.config/fish/completions/nca.fish +``` + +## Next Steps + +- [Commands](./commands.md) — full CLI reference +- [Interactive Mode](./interactive-mode.md) — TUI features, slash commands, shortcuts +- [Configuration](./configuration.md) — detailed config options +- [Providers](./providers.md) — set up LLM providers diff --git a/docs/documentation/index.md b/docs/documentation/index.md new file mode 100644 index 0000000..8658467 --- /dev/null +++ b/docs/documentation/index.md @@ -0,0 +1,78 @@ +# nca — Native CLI AI + +A native-first, Rust-powered AI coding assistant that runs entirely in the terminal. Zero JavaScript dependencies, sub-100ms startup, and a full agent loop for code generation, file editing, command execution, and project understanding. + +## What is nca? + +**nca** (native-cli-ai) is a terminal-native AI coding agent comparable to Claude Code and OpenAI Codex CLI — built from scratch in Rust. It provides: + +- **Interactive REPL** with multi-turn conversation, full-screen TUI, and agent profiles +- **One-shot mode** for scripting and CI pipelines +- **Session management** with spawn, resume, attach, and structured logs +- **Tool execution** — file operations, code search, shell commands, web research, and more +- **Sub-agent spawning** with isolated git worktrees for parallel task delegation +- **Multiple LLM providers** — MiniMax, Anthropic, OpenAI, and OpenRouter +- **Permission system** — from fully interactive approval to bypass mode for automation +- **MCP integration** — connect external tool servers via Model Context Protocol +- **Skills system** — discoverable, loadable instruction packs that extend agent behavior + +## Quick Start + +```bash +# Build from source +cargo build --release + +# Install to PATH +cp target/release/nca /usr/local/bin/ + +# Set up your API key +export MINIMAX_API_KEY="your-key-here" + +# Start interactive session +nca + +# Or run a one-shot task +nca -p "add error handling to src/main.rs" +``` + +## Documentation + +| Page | Description | +|------|-------------| +| [Getting Started](./getting-started.md) | Installation, first run, and initial configuration | +| [Commands](./commands.md) | Complete CLI command and flag reference | +| [Interactive Mode](./interactive-mode.md) | TUI, REPL, slash commands, keyboard shortcuts | +| [Configuration](./configuration.md) | Config files, TOML format, and environment variables | +| [Providers](./providers.md) | LLM provider setup — MiniMax, Anthropic, OpenAI, OpenRouter | +| [Tools](./tools.md) | All agent tools — file ops, search, shell, web, and more | +| [Sessions](./sessions.md) | Session lifecycle, persistence, resume, and management | +| [Permissions](./permissions.md) | Approval system, permission modes, and safe mode | +| [Skills](./skills.md) | Skill discovery, installation, and authoring | +| [Advanced](./advanced.md) | Sub-agents, MCP servers, hooks, orchestration, and IPC | + +## Architecture + +nca is a Rust workspace with five crates: + +``` +nca +├── nca-common Shared types, config, events, session metadata +├── nca-core Agent loop, LLM providers, tool protocol, harness +├── nca-runtime Session lifecycle, IPC, persistence, worktrees, supervision +├── nca-cli Terminal UX — TUI, REPL, streaming, onboarding +└── nca-autoresearch Automated research capabilities +``` + +Single binary output: `nca`. No runtime dependencies beyond a working terminal and network access for LLM calls. + +## Design Principles + +1. **Terminal-native** — every interaction works in a standard terminal, no mouse required +2. **Predictable** — the agent shows what it intends to do before doing it +3. **Interruptible** — Esc or Ctrl+C cleanly cancels any in-flight operation +4. **Transparent** — token costs, tool calls, and model responses are always visible +5. **Fast** — sub-100ms startup, <10ms local tool execution, <200ms session resume + +## License + +MIT — see [repository](https://github.com/madebyaris/native-cli-ai) for details. diff --git a/docs/documentation/interactive-mode.md b/docs/documentation/interactive-mode.md new file mode 100644 index 0000000..f18634c --- /dev/null +++ b/docs/documentation/interactive-mode.md @@ -0,0 +1,251 @@ +# Interactive Mode + +nca provides a rich interactive experience with a full-screen TUI (Terminal User Interface) and a fallback line-oriented REPL. + +## TUI vs REPL + +| Mode | When Used | Features | +|------|-----------|----------| +| **TUI** (default) | Terminal is a TTY, `--stream human`, no `--no-tui` | Full-screen, scrollable output, command palette, modals, mouse support | +| **Line REPL** | `--no-tui` flag, or non-TTY stdin/stdout | Simple line-by-line input/output, still supports slash commands | + +Force line REPL mode: + +```bash +nca --no-tui +``` + +## Input Modes + +### Regular Text + +Type your message and press **Enter** to send it to the agent. + +### Shell Commands (`!`) + +Prefix with `!` to run a shell command directly. The output is captured and fed into the conversation context. + +``` +! cargo test +! git log --oneline -5 +! ls -la src/ +``` + +### File Mentions (`@`) + +Type `@` followed by a path to inline-reference a file. nca performs fuzzy file search and auto-completion. + +``` +Can you review @src/main.rs and @src/lib.rs? +``` + +In the TUI, pressing `@` opens a file picker with fuzzy search. Use `Tab` to navigate matches and `Enter` to select. + +### Multiline Input (`\`) + +End a line with `\` to continue input on the next line: + +``` +Write a function that \ +takes a vector of strings \ +and returns the longest one. +``` + +### Slash Commands (`/`) + +Type `/` to access slash commands. In the TUI, this opens an inline autocomplete menu. + +--- + +## Slash Commands + +### General + +| Command | Description | +|---------|-------------| +| `/help` | Show help with all commands and keyboard shortcuts | +| `/status` | Display session status (ID, model, agent profile, permission mode) | +| `/clear` | Clear the screen | +| `/exit`, `/quit`, `/q` | Exit the session | +| `/new` | Start a new session | +| `/export` | Export the current session to markdown | +| `/stop` | Cancel the current agent turn | + +### Agent Profiles + +| Command | Description | +|---------|-------------| +| `/agent [profile]` | Show or switch agent profile | +| `/plan ` | Run a planning-oriented turn (read-only analysis) | +| `/review ` | Run a code review turn | +| `/fix ` | Run a bug-fix turn | +| `/test ` | Run a validation/testing turn | + +Available agent profiles: + +| Profile | Description | +|---------|-------------| +| `@build` | Default full-access agent for development work | +| `@plan` | Read-only agent for analysis and planning | +| `@review` | Focused code review agent | +| `@fix` | Bug diagnosis and fix agent | +| `@test` | Testing and validation agent | + +### Model and Provider + +| Command | Description | +|---------|-------------| +| `/models` | Browse and select models (opens picker in TUI) | +| `/model [name]` | Set the active model for the session | +| `/connect` | Open the provider connection picker | +| `/provider [name]` | Show or set the default LLM provider | +| `/apikey ` | Store an API key for a provider | + +### Session and Context + +| Command | Description | +|---------|-------------| +| `/compact` | Compact session context (summarize and trim history) | +| `/thinking` | Toggle thinking/reasoning visibility | +| `/sessions` | List and switch between sessions | +| `/agents` | List child sub-agent sessions | +| `/logs` | View session event log | +| `/attach` | Attach to a session | +| `/diff` | Show recent file changes | +| `/cost` | Show token usage and costs | +| `/stats` | Show session statistics | + +### Tools and Configuration + +| Command | Description | +|---------|-------------| +| `/skills` | List discovered skills | +| `/memory [text]` | Show memory notes, or add a note | +| `/mcp` | List MCP servers | +| `/permissions [mode]` | Show or set permission mode | +| `/permission-bypass` | Toggle permission bypass | +| `/config` | Show runtime configuration | +| `/doctor` | Run configuration diagnostics | +| `/settings` | Show settings | + +### Editor + +| Command | Description | +|---------|-------------| +| `/editor [seed]` | Open an external editor to compose a message | +| `/set-editor ` | Persist the editor command (e.g., `vim`, `code --wait`) | + +### Images + +| Command | Description | +|---------|-------------| +| `/image` | Manage staged image attachments | + +### Other + +| Command | Description | +|---------|-------------| +| `/undo` | Undo last file change | +| `/redo` | Redo last undone change | +| `/auto-answer` | Auto-answer agent questions with suggested answer | + +--- + +## Keyboard Shortcuts + +### General Navigation + +| Shortcut | Action | +|----------|--------| +| `Enter` | Send message | +| `Esc` | Cancel current agent turn / close modal | +| `Ctrl+C` | Cancel request | +| `Ctrl+L` | Clear screen | +| `Ctrl+Q` | Exit | +| `Mouse wheel` | Scroll output | +| `End` | Jump to bottom of transcript (on empty input) | + +### Agent and Model + +| Shortcut | Action | +|----------|--------| +| `Tab` | Cycle agent profile (build → plan → review → fix → test) | +| `F2` | Cycle through recent models (forward) | +| `Shift+F2` | Cycle through recent models (backward) | + +### Command Palette and Pickers + +| Shortcut | Action | +|----------|--------| +| `Ctrl+P` | Open command palette | +| `Ctrl+V` | Paste image from clipboard (TUI only) | +| `Ctrl+X M` | Switch model (model picker) | +| `Ctrl+X E` | Open external editor | +| `Ctrl+X L` | Switch session | +| `Ctrl+X N` | New session | +| `Ctrl+X C` | Compact context | +| `Ctrl+X S` | View status | +| `Ctrl+X A` | Agent profile picker | +| `Ctrl+X H` | Show help | +| `Ctrl+X Q` | Exit | + +### Within Modals and Pickers + +| Shortcut | Action | +|----------|--------| +| `↑` / `↓` | Navigate options | +| `Enter` | Select / confirm | +| `Esc` | Close modal | +| `j` / `k` | Navigate (in info modals) | + +### Agent Question Modals + +When the agent asks a structured question: + +| Shortcut | Action | +|----------|--------| +| `↑` / `↓` | Select an option | +| `Enter` | Confirm selection (or accept suggested answer on empty input) | +| `0` | Accept suggested answer | +| `1`–`n` | Select option by number | +| `c` | Type a custom answer | + +--- + +## Command Palette + +Press `Ctrl+P` to open the command palette — a searchable list of all available commands. Type to filter, use `↑`/`↓` to navigate, and `Enter` to execute. + +## Status Bar + +The TUI displays a status bar at the bottom showing: + +- Current agent profile +- Active model +- Available shortcuts hint + +``` +Tab agent Ctrl+V image Ctrl+P commands !cmd shell @path search / inline wheel scroll +``` + +## Image Attachments + +In the TUI, paste images from your clipboard with `Ctrl+V` or use the `/image` command. Images are processed through MiniMax native vision and the text description is injected into the conversation. + +## Vi Mode + +If your `NCA_EDITOR_MODE` environment variable is set to `vi` or `vim`, the REPL uses vi keybindings for line editing. + +```bash +export NCA_EDITOR_MODE=vi +``` + +## External Editor + +For composing long messages, use `/editor` to open your configured external editor. The content is sent as your message when you save and close. + +Editor resolution order: +1. `NCA_EDITOR` environment variable +2. `[ui].editor` in config +3. `EDITOR` environment variable +4. `vim` (fallback) diff --git a/docs/documentation/permissions.md b/docs/documentation/permissions.md new file mode 100644 index 0000000..7c7313c --- /dev/null +++ b/docs/documentation/permissions.md @@ -0,0 +1,192 @@ +# Permissions + +nca uses a tiered permission system to control which actions the agent can take. This ensures safety while allowing flexibility for different workflows. + +## Permission Modes + +Set the permission mode via CLI flag, config file, or interactive command. + +| Mode | Description | +|------|-------------| +| `default` | Read-only tools auto-allowed; everything else prompts for approval | +| `plan` | Read-only tools only; all writes and execution denied | +| `accept-edits` | Read-only + file edit tools auto-allowed; shell and destructive ops prompt | +| `dont-ask` | Read-only tools only; no prompts (deny anything that would need asking) | +| `bypass-permissions` | All tools auto-allowed without prompts | + +### Setting the Mode + +```bash +# CLI flag +nca --permission-mode accept-edits + +# Environment (via config) +# In config.toml: +# [permissions] +# mode = "accept-edits" + +# Interactive slash command +/permissions accept-edits +``` + +## Tool Categories + +Tools are classified into categories that determine how each permission mode handles them: + +### Read-Only Tools (always allowed in most modes) + +- `read_file` +- `list_directory` +- `search_code` +- `git_status` +- `git_diff` +- `query_symbols` +- `web_search` +- `fetch_url` +- `ask_question` + +### File-Edit Tools (allowed in `accept-edits` and above) + +- `write_file` +- `create_directory` +- `apply_patch` +- `edit_file` +- `replace_match` +- `rename_path` +- `move_path` +- `copy_path` +- `spawn_subagent` + +### Destructive Tools (always prompt in `accept-edits`) + +- `delete_path` — always requires explicit approval unless in `bypass-permissions` + +### Execution Tools (prompt in `default` and `accept-edits`) + +- `execute_bash` +- `run_validation` + +## Permission Mode Behavior Matrix + +| Tool Category | `default` | `plan` | `accept-edits` | `dont-ask` | `bypass-permissions` | +|---------------|-----------|--------|-----------------|------------|----------------------| +| Read-only | Allowed | Allowed | Allowed | Allowed | Allowed | +| File-edit | **Ask** | Denied | Allowed | Denied | Allowed | +| Destructive | **Ask** | Denied | **Ask** | Denied | Allowed | +| Execution | **Ask** | Denied | **Ask** | Denied | Allowed | +| MCP tools | **Ask** | Denied | **Ask** | Denied | Allowed | + +## Allow/Deny Lists + +Fine-tune permissions with pattern-based lists in config: + +```toml +[permissions] +mode = "default" + +# Always allow these tool+pattern combinations +allow = [ + "execute_bash:cargo *", + "execute_bash:git status", + "write_file:src/*", +] + +# Always deny these +deny = [ + "execute_bash:rm -rf *", + "execute_bash:sudo *", + "delete_path:*", +] + +# Force ask for these (even if mode would auto-allow) +ask = [ + "write_file:Cargo.toml", +] +``` + +### Pattern Format + +Patterns use the format `tool_name:description_pattern` with simple wildcard matching: + +- `*` matches any substring +- Matching is case-insensitive +- The description is derived from the tool's input (file path, command, URL, etc.) + +### Pattern Matching Examples + +```toml +# Allow all cargo commands +allow = ["execute_bash:cargo *"] + +# Allow writes only to src/ directory +allow = ["write_file:src/*"] + +# Deny any rm commands +deny = ["execute_bash:rm *"] + +# Always ask before modifying config files +ask = ["write_file:*.toml", "write_file:*.json"] +``` + +## Session-Level Approvals + +When you approve a tool call interactively, nca offers to remember the approval pattern for the rest of the session. This is stored as a session-level allow pattern and does not persist across sessions. + +For example, approving `execute_bash: cargo test` might add `execute_bash:cargo test` to the session allow list, so future `cargo test` calls proceed without prompting. + +## Approval Flow + +When a tool requires approval: + +1. The agent emits an `ApprovalRequested` event +2. In the TUI, an approval modal appears showing the tool name and parameters +3. You can: + - **Allow** — execute this tool call + - **Allow pattern** — allow this and similar future calls + - **Deny** — block this tool call +4. The agent receives the decision and continues + +### Approval Timeout + +In interactive mode, approval requests time out after **300 seconds** (5 minutes) and auto-deny. + +## Safe Mode + +Safe mode (`--safe` or `-s`) is a special restricted mode: + +```bash +nca --safe +nca -s +``` + +In safe mode: +- Only read-only tools are registered +- `execute_bash` is explicitly added to the deny list +- `spawn_subagent` is not registered +- MCP tools are only available if `mcp.expose_in_safe_mode = true` + +Safe mode is ideal for code exploration, review, and analysis without any risk of modification. + +## Headless/CI Mode + +For non-interactive usage (CI pipelines, scripts, automation): + +```bash +nca run --prompt "..." --permission-mode bypass-permissions --json +``` + +In headless mode: +- If a tool requires approval and no interactive handler is available, it **fails loudly** instead of stalling +- Use `bypass-permissions` to skip all approval prompts +- Use `accept-edits` for a middle ground (file edits allowed, shell still denied) +- The `--json` flag outputs structured results for machine consumption + +## Interactive Permission Changes + +Change the permission mode during a session: + +``` +/permissions # Show current mode +/permissions accept-edits # Switch mode +/permission-bypass # Toggle bypass mode +``` diff --git a/docs/documentation/providers.md b/docs/documentation/providers.md new file mode 100644 index 0000000..77e2c3e --- /dev/null +++ b/docs/documentation/providers.md @@ -0,0 +1,255 @@ +# Providers + +nca supports four LLM provider backends. You can switch between them at any time via config, environment variables, or the interactive `/connect` and `/provider` commands. + +## Supported Providers + +| Provider | Default Model | API Style | Description | +|----------|---------------|-----------|-------------| +| **MiniMax** | `MiniMax-M2.7` | Anthropic-compatible | Primary provider. Uses the MiniMax Anthropic-compatible endpoint. | +| **Anthropic** | `claude-3-7-sonnet-latest` | Native Anthropic | Direct Anthropic API for Claude models. | +| **OpenAI** | `gpt-4o-mini` | OpenAI Chat | Standard OpenAI chat completions API. | +| **OpenRouter** | `openai/gpt-4o-mini` | OpenAI-compatible | Aggregator providing access to 100+ models from multiple providers. | + +## MiniMax (Default) + +MiniMax is nca's primary provider, using an Anthropic-compatible API endpoint. + +### Setup + +```bash +export MINIMAX_API_KEY="your-minimax-api-key" +``` + +Or in config: + +```toml +# ~/.nca/config.toml +[provider] +default = "minimax" + +[provider.minimax] +api_key = "your-key" +base_url = "https://api.minimax.io/anthropic" +model = "MiniMax-M2.7" +temperature = 0.7 +``` + +### Features + +- Anthropic-compatible protocol (`/v1/messages` endpoint) +- Extended thinking support +- Native vision/image processing +- Streaming responses + +## Anthropic + +Direct access to Claude models via the native Anthropic API. + +### Setup + +```bash +export ANTHROPIC_API_KEY="your-anthropic-key" +``` + +```toml +[provider] +default = "anthropic" + +[provider.anthropic] +api_key_env = "ANTHROPIC_API_KEY" +base_url = "https://api.anthropic.com" +model = "claude-3-7-sonnet-latest" +temperature = 1.0 +``` + +## OpenAI + +Standard OpenAI chat completions API. + +### Setup + +```bash +export OPENAI_API_KEY="your-openai-key" +``` + +```toml +[provider] +default = "openai" + +[provider.openai] +api_key_env = "OPENAI_API_KEY" +base_url = "https://api.openai.com" +model = "gpt-4o-mini" +temperature = 0.7 +``` + +### OpenAI-Compatible Endpoints + +You can point the OpenAI provider at any OpenAI-compatible API by changing `base_url`: + +```toml +[provider.openai] +base_url = "https://my-local-llm:8080" +model = "local-model" +``` + +## OpenRouter + +Access to hundreds of models from multiple providers through a single API key. + +### Setup + +```bash +export OPENROUTER_API_KEY="your-openrouter-key" +``` + +```toml +[provider] +default = "openrouter" + +[provider.openrouter] +api_key_env = "OPENROUTER_API_KEY" +base_url = "https://openrouter.ai/api" +model = "openai/gpt-4o-mini" +temperature = 0.7 +site_url = "https://my-app.com" # Optional +app_name = "my-app" # Optional +``` + +### Model Format + +OpenRouter uses `provider/model` naming: + +``` +openai/gpt-4o +anthropic/claude-3-7-sonnet +google/gemini-2.0-flash +meta-llama/llama-3.1-70b-instruct +``` + +## Switching Providers + +### Via CLI Flag + +```bash +nca --model "claude-3-7-sonnet-latest" +``` + +### Via Environment Variable + +```bash +NCA_DEFAULT_PROVIDER=anthropic nca +NCA_MODEL=gpt-4o nca +``` + +### Via Interactive Commands + +``` +/connect # Opens provider picker UI +/provider openai # Switch default provider +/model gpt-4o # Switch model +/models # Browse available models +``` + +### Via Config + +```toml +[provider] +default = "anthropic" +``` + +## Model Aliases + +nca ships with built-in model aliases for quick switching: + +| Alias | Resolves To | +|-------|-------------| +| `default` | `MiniMax-M2.7` | +| `minimax` | `MiniMax-M2.7` | +| `m2.7` | `MiniMax-M2.7` | +| `coding` | `MiniMax-M2.7` | +| `reasoning` | `MiniMax-M2.7` | +| `openai` | `gpt-4o-mini` | +| `gpt4o` | `gpt-4o` | +| `claude` | `claude-3-7-sonnet-latest` | +| `openrouter` | `openai/gpt-4o-mini` | + +Add custom aliases in config: + +```toml +[model.aliases] +fast = "gpt-4o-mini" +smart = "claude-3-7-sonnet-latest" +local = "ollama/llama3" +``` + +Use aliases anywhere a model name is expected: + +```bash +nca --model fast +``` + +``` +/model smart +``` + +## API Key Resolution + +For each provider, the API key is resolved in this order: + +1. **`api_key`** field in config (not recommended for security) +2. **`api_key_env`** — read from the named environment variable (default and recommended) + +The default environment variable names are: + +| Provider | Variable | +|----------|----------| +| MiniMax | `MINIMAX_API_KEY` | +| Anthropic | `ANTHROPIC_API_KEY` | +| OpenAI | `OPENAI_API_KEY` | +| OpenRouter | `OPENROUTER_API_KEY` | + +You can change the environment variable name via `api_key_env` in config. + +## Extended Thinking + +Some models support extended thinking (chain-of-thought reasoning). Enable it with: + +```bash +nca -t # Enable with default budget (5120 tokens) +nca -t --thinking-budget 10000 # Custom budget +``` + +Or in config: + +```toml +[model] +enable_thinking = true +thinking_budget = 10000 +``` + +Toggle visibility in an interactive session: + +``` +/thinking +``` + +## Context Window Management + +nca auto-detects context window sizes by querying the provider's model API. This enables automatic context compaction when the conversation gets too long. + +```toml +[memory.context] +auto_detect_context_window = true +query_provider_models_api = true +max_retained_messages = 50 +auto_summarize_threshold = 75 # Trigger at 75% of context window +enable_auto_summarize = true +``` + +Disable provider API queries if needed: + +```bash +export NCA_SKIP_CONTEXT_API=1 +``` diff --git a/docs/documentation/sessions.md b/docs/documentation/sessions.md new file mode 100644 index 0000000..30698a4 --- /dev/null +++ b/docs/documentation/sessions.md @@ -0,0 +1,258 @@ +# Sessions + +nca persists every conversation as a session. Sessions can be resumed, inspected, attached to, and managed through the CLI. + +## Session Lifecycle + +``` +nca (start) → Session Created → Agent Turns → Session Ended + ↓ ↓ + .nca/sessions/.json .nca/sessions/.events.jsonl + ↓ ↓ + State snapshot Full event log +``` + +### States + +| Status | Description | +|--------|-------------| +| `running` | Session is currently active | +| `completed` | Session finished successfully | +| `cancelled` | Session was cancelled by the user | +| `failed` | Session ended with an error | + +## Session Storage + +Sessions are stored in the workspace under `.nca/sessions/`: + +``` +.nca/sessions/ +├── a1b2c3d4.json # Session state snapshot +├── a1b2c3d4.events.jsonl # Event log (NDJSON) +├── e5f6g7h8.json +├── e5f6g7h8.events.jsonl +└── ... +``` + +### State File (`.json`) + +Contains session metadata: + +- Session ID and timestamps (created, updated) +- Workspace path and working directory +- Model and provider configuration +- Session status and PID +- Socket path for IPC +- Parent/child session relationships +- Session summary +- Git branch information +- Worktree path (for sub-agent sessions) + +### Event Log (`.events.jsonl`) + +Append-only NDJSON log of every event in the session: + +- Messages sent and received +- Token usage and streaming events +- Tool call starts and completions +- Approval requests and resolutions +- Child session spawns and completions +- Context warnings and compaction events +- Errors and status changes + +Each event has a monotonic `id` and `ts` (timestamp). + +## Managing Sessions + +### List Sessions + +```bash +nca sessions # List recent sessions (default: 20) +nca sessions --limit 50 # Show more +nca sessions --status running # Filter by status +nca sessions --since-hours 24 # Last 24 hours +nca sessions --search "auth" # Search by content +nca sessions --json # JSON output +``` + +### Resume a Session + +Resume picks up a session with full conversation context: + +```bash +# Resume by ID +nca resume + +# Resume with a follow-up prompt +nca resume --prompt "continue with the tests" + +# Resume with a different model +nca resume --model "claude-3-7-sonnet-latest" + +# Resume the most recent session (shorthand) +nca -r +nca --resume +``` + +### Auto-Resume Behavior + +By default, when you run `nca` without any arguments: + +1. nca checks `.nca/.last_session` for the most recent session ID +2. If a valid recent session exists, nca **auto-resumes** it with a hint to stderr +3. If no valid session exists, a new session starts + +Override this: + +```bash +nca --no-resume # Always start fresh +nca --resume # Always resume last session +``` + +### View Session Logs + +```bash +nca logs # Dump event log +nca logs --follow # Stream in real-time +nca logs --json # Raw JSON events +``` + +### Attach to a Running Session + +```bash +nca attach # Attach to output stream +nca attach --json # JSON event stream +``` + +### Check Session Status + +```bash +nca status # Show metadata +nca status --json # JSON output +``` + +### Cancel a Running Session + +```bash +nca cancel +``` + +### Interactive Session Switching + +In the TUI, use `/sessions` to open a session picker or press `Ctrl+X L`: + +``` +/sessions # Open session picker +/new # Start a new session +``` + +## Session Context Management + +### Context Compaction + +As conversations grow, nca can summarize and compact the context to stay within the model's context window: + +``` +/compact # Manually compact context +``` + +Automatic compaction is controlled by: + +```toml +[memory.context] +auto_summarize_threshold = 75 # Trigger at 75% of context window +enable_auto_summarize = true +max_retained_messages = 50 +``` + +When auto-summarize triggers, nca: +1. Emits a `ContextWarning` event +2. Summarizes the conversation history +3. Replaces older messages with the summary +4. Emits a `ContextCompaction` event + +### Checkpointing + +Sessions are checkpointed periodically to prevent data loss: + +```toml +[session] +checkpoint_interval = 5 # Save every 5 turns +``` + +### Session Export + +Export a session to markdown: + +``` +/export +``` + +## Session Configuration + +```toml +[session] +history_dir = ".nca/sessions" # Where sessions are stored +max_turns_per_run = 128 # Max turns before session ends +max_tool_calls_per_turn = 200 # Max tools per single turn +checkpoint_interval = 5 # Checkpoint frequency +last_session_file = ".nca/.last_session" # Last session pointer +auto_compact_on_finish = false # Summarize on session end +``` + +## Background Sessions + +Use `nca spawn` to create sessions that run in the background: + +```bash +nca spawn --prompt "refactor the auth module" +``` + +Spawned sessions: +- Run without interactive input +- Default to `accept-edits` permission mode +- Can be monitored with `nca logs`, `nca attach`, `nca status` +- Can be cancelled with `nca cancel` + +## IPC (Inter-Process Communication) + +Running sessions expose a Unix domain socket for real-time event streaming and control: + +``` +$XDG_RUNTIME_DIR/nca/.sock +# or +/tmp/nca/.sock +``` + +The IPC protocol uses newline-delimited JSON: + +**Events (session → client):** `EventEnvelope` objects containing `AgentEvent` variants. + +**Commands (client → session):** +- `SendMessage` — send a user message +- `ApproveToolCall` — approve a pending tool call +- `DenyToolCall` — deny a pending tool call +- `AnswerQuestion` — answer an agent question +- `Cancel` — cancel the current operation +- `Shutdown` — shut down the session + +This enables building external UIs, monitoring dashboards, and automation scripts that interact with running sessions. + +## Parent-Child Sessions + +When the agent spawns sub-agents, a parent-child relationship is tracked: + +- Parent session records child session IDs +- Child session records parent session ID and inherited summary +- The spawn reason is stored in child metadata +- Child sessions can optionally run in isolated git worktrees + +View child sessions: + +``` +/agents # List child sessions in interactive mode +``` + +```bash +nca sessions --search "child" # Search for sub-agent sessions +``` diff --git a/docs/documentation/skills.md b/docs/documentation/skills.md new file mode 100644 index 0000000..d020a07 --- /dev/null +++ b/docs/documentation/skills.md @@ -0,0 +1,177 @@ +# Skills + +Skills are discoverable instruction packs that extend nca's agent behavior. Each skill is a `SKILL.md` file that teaches the agent how to handle specific tasks, frameworks, or workflows. + +## How Skills Work + +Skills are **not code plugins** — they are structured instruction documents that the agent loads into its context when relevant. When a skill is invoked, the agent reads the skill's `SKILL.md` and follows its instructions. + +## Skill Discovery + +nca looks for skills in configured directories: + +```toml +[harness] +skill_directories = [".nca/skills", ".claude/skills"] +``` + +Default search paths (relative to workspace): +1. `.nca/skills/` — nca-specific skills +2. `.claude/skills/` — compatible with Claude Code skills + +### Skill Structure + +Each skill is a directory containing a `SKILL.md` file: + +``` +.nca/skills/ +├── rust-patterns/ +│ └── SKILL.md +├── api-design/ +│ └── SKILL.md +└── testing/ + └── SKILL.md +``` + +## Managing Skills + +### List Skills + +```bash +nca skills # List all discovered skills +nca skills list # Same +nca skills list --json # JSON output +``` + +Or in interactive mode: + +``` +/skills +``` + +### Install Skills + +```bash +# Install from a remote source +nca skills add https://github.com/user/skill-repo + +# Install specific skills from a source +nca skills add https://github.com/user/skill-repo -s rust-patterns -s testing + +# Install globally (available in all workspaces) +nca skills add https://github.com/user/skill-repo --global +``` + +### Remove Skills + +```bash +nca skills remove rust-patterns +nca skills remove rust-patterns --global +``` + +### Update Skills + +```bash +nca skills update # Update all skills +nca skills update rust-patterns # Update a specific skill +``` + +## Using Skills + +### Automatic Discovery + +The agent's system prompt includes a list of available skills. The agent can choose to invoke relevant skills based on the task. + +### Explicit Invocation + +Ask the agent to use a skill: + +``` +Use the rust-patterns skill to review this code. +``` + +Or the agent can invoke skills programmatically via the `invoke_skill` tool. + +### Slash Command + +``` +/skills # List available skills +``` + +## Writing Skills + +### `SKILL.md` Format + +Create a `SKILL.md` file in a skill directory: + +```markdown +# Skill Name + +Brief description of what this skill does. + +## When to Use + +Describe when this skill should be activated. + +## Instructions + +Step-by-step instructions for the agent to follow. + +### Step 1: Analysis + +Analyze the codebase for... + +### Step 2: Implementation + +Apply the following patterns... + +## Examples + +### Before +\`\`\`rust +// problematic code +\`\`\` + +### After +\`\`\`rust +// improved code +\`\`\` +``` + +### Best Practices + +1. **Be specific** — give clear, actionable instructions the agent can follow +2. **Include examples** — show before/after code when applicable +3. **Define scope** — explain when the skill should and shouldn't be used +4. **Keep it focused** — one skill per concern (don't combine testing and deployment) +5. **Use structured steps** — numbered steps help the agent track progress + +## Skill Directories + +### Workspace Skills + +``` +my-project/.nca/skills/my-skill/SKILL.md +``` + +Available only in this workspace. Good for project-specific conventions. + +### Global Skills + +``` +~/.nca/skills/my-skill/SKILL.md +``` + +Available in all workspaces. Good for personal coding standards and reusable patterns. + +### Claude-Compatible Skills + +``` +my-project/.claude/skills/my-skill/SKILL.md +``` + +nca discovers skills from `.claude/skills/` by default, making it compatible with Claude Code skill conventions. + +## System Prompt Integration + +When skills are available, nca adds a skills section to the system prompt listing all discovered skills by name. The agent can then use the `invoke_skill` tool to load any skill's full instructions on demand. diff --git a/docs/documentation/tools.md b/docs/documentation/tools.md new file mode 100644 index 0000000..5655eef --- /dev/null +++ b/docs/documentation/tools.md @@ -0,0 +1,358 @@ +# Tools + +nca's agent has access to a set of built-in tools for interacting with your codebase, running commands, and searching the web. Tools are the actions the agent can take on your behalf. + +## Tool Categories + +### Read-Only Tools + +These tools are always available, including in [safe mode](./permissions.md). + +| Tool | Description | +|------|-------------| +| `read_file` | Read the contents of a file | +| `search_code` | Search code using ripgrep with structured JSON output | +| `list_directory` | List files and directories at a path | +| `git_status` | Show `git status` for the workspace | +| `git_diff` | Show `git diff` (staged or unstaged) | +| `web_search` | Search the web via DuckDuckGo | +| `fetch_url` | Fetch and extract text content from a URL | + +### Write Tools + +Available in standard mode. Requires appropriate [permissions](./permissions.md). + +| Tool | Description | +|------|-------------| +| `write_file` | Create or overwrite a file | +| `create_directory` | Create a directory (including parents) | +| `apply_patch` | Apply one or more exact string replacements to a file | +| `edit_file` | Replace a specific string in an existing file | +| `replace_match` | Precision replace using line and column coordinates | +| `rename_path` | Rename a file or directory | +| `move_path` | Move a file or directory | +| `copy_path` | Copy a file | +| `delete_path` | Delete a file or directory | + +### Execution Tools + +| Tool | Description | +|------|-------------| +| `execute_bash` | Execute a shell command in the workspace (PTY-backed) | +| `run_validation` | Run an allowlisted build/test/lint command | + +### Intelligence Tools + +| Tool | Description | +|------|-------------| +| `query_symbols` | Search for symbol definitions in the codebase | +| `ask_question` | Ask the user a structured question with options | +| `invoke_skill` | Load and follow a skill's instructions | +| `spawn_subagent` | Spawn a child agent session for parallel work | + +### MCP Tools + +Tools from configured [MCP servers](./advanced.md#mcp-servers) appear as `mcp____`. + +--- + +## Tool Reference + +### `read_file` + +Read the contents of a file in the workspace. + +**Parameters:** +- `path` (string, required) — File path relative to workspace root + +**Behavior:** Reads the file asynchronously. The path must resolve within the workspace boundary. + +--- + +### `search_code` + +Search code using ripgrep and return structured match results. + +**Parameters:** +- `pattern` (string, required) — Search pattern (regex by default) +- `path` (string, optional) — Directory to search in (default: workspace root) +- `glob` (string, optional) — File glob filter (e.g., `"*.rs"`) +- `fixed_strings` (bool, optional) — Treat pattern as literal text +- `case_sensitive` (bool, optional) — Case-sensitive matching +- `word` (bool, optional) — Match whole words only +- `context_before` (int, optional) — Lines of context before match +- `context_after` (int, optional) — Lines of context after match +- `max_results` (int, optional) — Maximum number of results + +**Behavior:** Invokes `rg` with JSON output. Search root is validated to stay within the workspace. + +--- + +### `list_directory` + +List files and directories at a given path. + +**Parameters:** +- `path` (string, optional) — Directory path (default: `.`, workspace root) + +**Behavior:** Lists entries under the given path. Directories are suffixed with `/`. + +--- + +### `git_status` + +Show the current git status for the workspace. + +**Parameters:** None (empty object `{}`) + +**Behavior:** Runs `git status --short --branch` in the workspace. + +--- + +### `git_diff` + +Show git diff for the workspace. + +**Parameters:** +- `staged` (bool, optional) — If true, show staged changes (`--cached`) + +--- + +### `web_search` + +Search the public web and return titles, URLs, and snippets. + +**Parameters:** +- `query` (string, required) — Search query +- `limit` (int, optional) — Number of results (1–10, default from config) + +**Behavior:** HTTP GET to DuckDuckGo HTML search. Results are parsed and returned as structured text. + +--- + +### `fetch_url` + +Fetch and normalize the text content of a URL. + +**Parameters:** +- `url` (string, required) — The URL to fetch + +**Behavior:** Makes an HTTP GET request, strips HTML to text content, and truncates to `max_fetch_chars` (default 25,000 characters). + +--- + +### `write_file` + +Create or overwrite a file inside the workspace. + +**Parameters:** +- `path` (string, required) — File path relative to workspace +- `content` (string, required) — File contents + +**Behavior:** Creates parent directories if needed. Path must resolve within workspace. + +--- + +### `create_directory` + +Create a directory inside the workspace. + +**Parameters:** +- `path` (string, required) — Directory path + +**Behavior:** Creates the directory and all parent directories (`mkdir -p` equivalent). + +--- + +### `apply_patch` + +Apply one or more exact string replacements to a file. + +**Parameters:** +- `path` (string, required) — File to patch +- `edits` (array, required) — List of edits, each containing: + - `old_text` (string, required) — Text to find (must not be empty) + - `new_text` (string, required) — Replacement text + - `replace_all` (bool, optional) — Replace all occurrences (default: false) + +**Behavior:** For each edit, finds the exact `old_text` string. If `replace_all` is false and multiple matches exist, the edit fails with an error. + +--- + +### `edit_file` + +Replace a specific string in an existing file. + +**Parameters:** +- `path` (string, required) — File to edit +- `old_text` (string, required) — Text to find +- `new_text` (string, required) — Replacement text +- `replace_all` (bool, optional) — Replace all occurrences + +Similar to `apply_patch` but for a single edit. + +--- + +### `replace_match` + +Precision replacement using exact file path, line number, and column. + +**Parameters:** +- `path` (string, required) — File path +- `line` (int, required) — Line number (1-based) +- `column` (int, required) — Column number (1-based) +- `old_text` (string, required) — Text to replace at the specified position +- `new_text` (string, required) — Replacement text + +**Behavior:** Anchors the replacement at a specific line and column for maximum precision. + +--- + +### `rename_path` + +Rename a file or directory within the workspace. + +**Parameters:** +- `from` (string, required) — Current path +- `to` (string, required) — New path + +--- + +### `move_path` + +Move a file or directory within the workspace. + +**Parameters:** +- `from` (string, required) — Source path +- `to` (string, required) — Destination path + +--- + +### `copy_path` + +Copy a file within the workspace. + +**Parameters:** +- `from` (string, required) — Source file +- `to` (string, required) — Destination file + +--- + +### `delete_path` + +Delete a file or directory. + +**Parameters:** +- `path` (string, required) — Path to delete +- `recursive` (bool, optional) — Required for directory deletion + +**Behavior:** Always requires explicit approval under most permission modes (classified as destructive). + +--- + +### `execute_bash` + +Execute a shell command in the workspace. + +**Parameters:** +- `command` (string, required) — The shell command to run +- `timeout_secs` (int, optional, default: 30) — Command timeout in seconds + +**Behavior:** Runs in a PTY (pseudo-terminal) for full interactive command support. Returns stdout content or status message. Exit code 0 = success. + +In safe mode, `execute_bash` is added to the deny list automatically. + +--- + +### `run_validation` + +Run a safe build, test, or lint command. + +**Parameters:** +- `command` (string, required) — The command to run +- `cwd` (string, optional, default: `.`) — Working directory +- `timeout_secs` (int, optional, default: 120) — Command timeout + +**Behavior:** Only executes commands that start with an allowlisted prefix: + +- `cargo build`, `cargo test`, `cargo check`, `cargo clippy`, `cargo fmt` +- `npm run`, `npm test`, `npx` +- `pnpm run`, `pnpm test` +- `pytest`, `python -m pytest` +- `go test`, `go build`, `go vet` +- `make` + +Other commands are rejected with an error. + +--- + +### `query_symbols` + +Search for symbol definitions (functions, structs, traits, etc.) in the codebase. + +**Parameters:** +- `query` (string, required) — Symbol name or pattern to search +- `glob` (string, optional) — File filter + +**Behavior:** Uses fast local code intelligence to find symbol definitions. Returns `path:line:text` formatted results. + +--- + +### `ask_question` + +Ask the user a structured question with predefined options. + +**Parameters:** +- `prompt` (string, required) — The question text +- `options` (array, required) — List of options with `id` and `label` +- `suggested_answer` (string, required) — Default/recommended answer +- `allow_custom` (bool, optional, default: true) — Allow freeform custom answer + +**Behavior:** Opens a modal in the TUI (or prompts in REPL) and waits for the user's selection. Blocks up to 3600 seconds. + +--- + +### `invoke_skill` + +Load a skill's full instructions by name. + +**Parameters:** +- `skill_name` (string, required) — Name of the skill to invoke + +**Behavior:** Discovers the skill's `SKILL.md` file from configured skill directories and returns its expanded content. If no match, lists available skills. + +--- + +### `spawn_subagent` + +Spawn a child agent session for parallel task delegation. + +**Parameters:** +- `task` (string, required) — Clear description of what the sub-agent should do +- `focus_files` (string[], optional) — File paths the sub-agent should focus on +- `use_worktree` (bool, optional, default: true) — Run in an isolated git worktree + +**Behavior:** Creates a new child session that inherits conversation context. The child runs with `bypass-permissions` mode and no interactive approvals. Returns a JSON response with `child_session_id`, `status`, `output`, `workspace`, `branch`, and `worktree_path`. Times out after 600 seconds. + +See [Sub-Agents](./advanced.md#sub-agents) for details. + +--- + +## Tool Execution Flow + +1. The LLM decides to call a tool and provides parameters +2. nca checks [permissions](./permissions.md) for the tool +3. If permission is `Ask`, the user is prompted for approval +4. The tool executes asynchronously +5. Results are fed back to the LLM for the next turn +6. Multiple approved tools can execute concurrently within a single turn + +## Workspace Sandbox + +All file tools enforce a workspace boundary: + +- File reads, writes, and edits must resolve to paths within the workspace root +- Shell commands (`execute_bash`) run with the workspace as the working directory +- Attempts to access paths outside the workspace are rejected with an error + +This sandbox protects against accidental or malicious file access outside your project.