How nano-collective/nanocoder works
1. What this repo is
Nanocoder is a TypeScript/Node-based terminal coding agent. The core product is a terminal UI, but the repo also contains a non-interactive CLI mode, a per-project daemon, and a VS Code extension bridge. Most of the architecture is organized around “conversation + tools + project state.”
2. Top-level runtime surfaces
There are three main hosts:
- the interactive terminal app under source/app and source/components
- the plain/non-interactive CLI flow under source/plain
- the VS Code integration under plugins/vscode and source/vscode
All three ultimately feed the same agent/conversation machinery, so the UI is a boundary, not the core engine.
3. Conversation engine is the center
The central data flow is: user input → prompt assembly → model request → streamed assistant output → tool calls → tool results → next model step.
The chat loop lives mainly in source/hooks/chat-handler, source/message-handler.ts, source/tools, and source/utils/*. The app renders this loop through Ink/React-style terminal components in source/components and source/app/components.
4. Model/provider abstraction
Model access is isolated in source/ai-sdk-client and source/client-factory.ts. This layer normalizes multiple providers and APIs, including local and remote options referenced in docs such as Ollama, OpenAI-compatible APIs, Anthropic, OpenRouter, GitHub Copilot/Codex, and others.
This is where message conversion, tool schema conversion, streaming handlers, retries, provider-specific options, TLS config, and provider factory logic live.
5. Tool execution is a separate subsystem
Agent actions are not hardcoded into the chat UI; they are modeled as tools in source/tools, with orchestration in source/tools/tool-manager.ts and source/tools/tool-registry.ts.
Tools cover file operations, shell execution, search, git actions, web search/fetching, task management, LSP diagnostics, agent delegation, and approval-gated actions. Tool results are rendered back into the conversation stream, and several helpers in source/utils handle approval queues, cancellation, result display, and path validation.
6. Project-aware context building
Nanocoder spends a lot of effort on preparing context from the local workspace. source/init, source/utils/file-*, source/utils/gitignore-loader.ts, source/utils/file-tree.ts, and source/utils/read-tracker.ts support scanning the project, detecting languages/frameworks, and building a bounded context for the model.
Prompt assembly is split across source/app/prompts, source/utils/prompt-builder.ts, source/utils/prompt-processor.ts, and prompt templates under source/app/prompts/sections.
7. State, sessions, checkpoints, and usage
User sessions are first-class. source/session, source/services/checkpoint-manager.ts, source/usage, and source/utils/compression-* handle persistence, recovery, context compression, and usage accounting.
This means the architecture is not stateless chat; it maintains conversation history, session identifiers, checkpoint snapshots, autosave behavior, and token/usage tracking across runs.
8. Configuration and provider setup
Configuration is loaded and validated in source/config, including preferences, environment substitution, logging config, MCP config loading, and model/provider settings. Authentication helpers for provider-specific credentials live in source/auth and credential-store code under source/config.
The repo also includes setup wizards in source/wizards for bootstrapping provider and MCP configuration, which indicates onboarding is part of the architecture rather than an external setup step.
9. Daemon and event routing
The source/daemon and source/events directories form a background coordination layer. The daemon manages per-project locking, IPC, and installation, while the event system routes asynchronous sources like file watchers and schedules.
This is the boundary for background triggers: file changes, scheduled actions, and other event sources can drive agent activity without direct user input.
10. MCP, LSP, and external workspace integrations
Nanocoder integrates with external tooling through multiple adapters:
- MCP in source/mcp
- LSP in source/lsp
- VS Code server/bridge in source/vscode
- custom tools and commands in source/custom-tools and source/custom-commands
These are separate extension surfaces that feed capabilities into the same tool/agent pipeline.
11. Subagents and skills
The repo has a dedicated automation layer for reusable behaviors:
- subagents in source/subagents
- skills in source/skills
- task/scheduler flows in source/schedule and source/tools/tasks
These are higher-level orchestration constructs that sit above primitive tools. They let the system dispatch specialized workflows instead of always using the main chat loop directly.
12. Safety and control boundaries
Approval, cancellation, and command-injection protection are explicit concerns. Relevant code lives in source/security, source/utils/tool-approval.ts, source/utils/tool-cancellation.ts, and approval-policy helpers in source/tools.
The architecture treats shell/file operations as privileged actions that must pass through validation and policy layers before execution.
13. Support code and product packaging
The repo is packaged for multiple distribution channels: npm, Homebrew (Formula/), Nix (flake.nix), and a VS Code extension artifact under assets/ and plugins/vscode. The .devcontainer, GitHub workflows, and scripts support development, release automation, and badge/update generation.
These are not part of the runtime core, but they matter for diagramming the delivery boundaries around the product.
14. How to diagram it
A good architecture diagram would place the conversation loop in the center, with four major spokes:
- User interfaces: terminal app, non-interactive CLI, VS Code
- Model providers: AI SDK/provider adapters
- Tooling/workspace: file/git/shell/MCP/LSP/custom tools
- State/control: sessions, checkpoints, daemon, config, approvals
That captures the repo’s main structure without flattening it into a generic CLI app.
Main entry points: tool-manager.ts Tool Manager · useChatHandler.tsx Chat Loop · cli.tsx CLI · ai-sdk-client.ts AI Client
Components 22
Runtime Surfaces
Interactive, non-interactive, and editor-facing entrypoints.
- CLI · Main command-line entrypoint and mode router.
source/cli.tsx - Terminal App · Interactive terminal host and app shell.
source/app/App.tsx - Plain Mode · Headless/non-interactive conversation flow.
source/plain/conversation.ts - VS Code Bridge · Editor-side bridge and server integration.
source/vscode/vscode-server.ts
Agent Core
Conversation loop, model access, tools, prompts, and context assembly.
- Chat Loop · Streaming conversation state, handler orchestration, and tool-loop control.
source/hooks/chat-handler/useChatHandler.tsx - Message Router · Routes user, assistant, and tool messages through the agent loop.
source/message-handler.ts - Prompt Builder · Builds prompts from templates, project context, and mode-specific sections.
source/utils/prompt-builder.ts - Project Context · Scans repositories, detects frameworks, and builds bounded context.
source/init/project-analyzer.ts - AI Client · Model/provider normalization, streaming, retries, and tool schema conversion.
source/ai-sdk-client/ai-sdk-client.ts - Client Factory · Selects and configures provider-specific clients.
source/client-factory.ts - Tool Manager · Registers, dispatches, and sequences tool execution.
source/tools/tool-manager.ts - Tool Registry · Defines available tools and their capabilities.
source/tools/tool-registry.ts - File Tools · Read, write, search, and edit file-oriented operations.
source/tools/file-ops/index.ts - Shell & Git · Command execution plus git inspection and mutation tools.
source/tools/execute-bash.tsx
State & Control
Sessions, config, daemon, events, usage, and safety boundaries.
- Sessions · Session history, persistence, autosave, and resume support.
source/session/session-manager.ts - Checkpoints · Snapshot, restore, and compaction support for long-running work.
source/services/checkpoint-manager.ts - Config · Preferences, provider settings, MCP config, env substitution, and validation.
source/config/index.ts - Daemon & Events · Per-project daemon, IPC, file watchers, schedules, and event routing.
source/daemon/daemon.ts - Approvals & Safety · Approval gates, cancellation, and command-injection protection.
source/security/command-injection.spec.ts
External Integrations
MCP, LSP, VS Code bridge, custom tools, and subagents.
- Web/MCP/LSP · Web fetch/search, MCP adapters, and language-server diagnostics.
source/tools/web-search.tsx - Subagents & Skills · Reusable higher-level behaviors and task-oriented orchestration.
source/subagents/subagent-executor.ts - VS Code Plugin · Extension package and transport layer for editor integration.
plugins/vscode/src/extension.ts
Connections 28
- CLI → Terminal App: interactive · CLI launches the terminal UI for interactive sessions.
- CLI → Plain Mode: headless · CLI can run the non-interactive conversation flow.
- CLI → VS Code Bridge: bridge · CLI surfaces editor-related entrypoints and helpers.
- Terminal App → Chat Loop: drives · The terminal UI feeds user input into the chat loop.
- Plain Mode → Chat Loop: reuses · Headless mode shares the same conversation machinery.
- VS Code Bridge → VS Code Plugin: hosts · VS Code server/bridge connects to the extension package.
- VS Code Plugin → Chat Loop: prompts · Editor prompts enter the shared chat loop.
- Chat Loop → Message Router: routes · Conversation state delegates message sequencing and dispatch.
- Message Router → Prompt Builder: assembles · Input is turned into a model prompt.
- Prompt Builder → Project Context: adds context · Project analysis and file context inform prompt construction.
- Chat Loop → AI Client: requests · The loop sends prompts and consumes streamed model output.
- AI Client → Client Factory: creates · Provider-specific clients are selected and configured through a factory.
- AI Client → Tool Manager: tool schema · Model tool definitions are normalized for execution.
- Chat Loop → Tool Manager: invokes · Assistant tool calls are executed through the tool manager.
- Tool Manager → Tool Registry: selects · Requested tool names are resolved against the registry.
- Tool Manager → File Tools: file ops · File-oriented actions are dispatched to file tools.
- Tool Manager → Shell & Git: shell/git · Shell and git actions are dispatched to execution tools.
- Tool Manager → Web/MCP/LSP: external · Web, MCP, and LSP capabilities plug into the same tool path.
- Tool Manager → Approvals & Safety: gated by · Privileged actions must pass approval and safety checks.
- Chat Loop → Sessions: persists · Conversation state is stored and resumed across runs.
- Sessions → Checkpoints: snapshots · Sessions can be checkpointed and restored.
- Config → Client Factory: configures · Provider and TLS settings feed client setup.
- Config → Daemon & Events: enables · Runtime settings and project metadata shape daemon behavior.
- Daemon & Events → Chat Loop: triggers · Background events can enqueue or start agent work.
- Daemon & Events → Sessions: coordinates · Daemon-side execution is tied to project/session state.
- Subagents & Skills → Chat Loop: extends · Specialized workflows build on the shared conversation engine.
- Subagents & Skills → Tool Manager: uses · Higher-level workflows dispatch primitive tools underneath.
- Approvals & Safety → Tool Manager: polices · Tool execution is constrained by policy and cancellation.