Releases: Nano-Collective/nanocoder
nanocoder v1.28.0
What's Changed
-
Added Agent Client Protocol (ACP) support. Nanocoder can now run as an ACP agent (
nanocoder --acp), exposing its conversation, tool-calling, and permission flows over the protocol so it can be driven by ACP-compatible editors and clients (Zed and others). Newsource/acp/module covers the agent, server, session, conversation loop, content conversion, capability negotiation, and permission handling. Thanks to @Avtrkrb. Closes #529. Follow-up work added the missing ACP docs, kept the parallel tool-execution loop in sync with the plain shell, and madeNANOCODER_MAX_TURNSconfigurable (with a raised default) so long ACP and plain-mode runs are not cut short. -
Consolidated the built-in tool surface from 33 tools down to 19 and added automatic tool profiling. Tasks collapse from four tools into a single TodoWrite-style
write_tasks(replace-whole-list, no IDs for the model to juggle); file ops merge delete/move/copy/create_directory into onefile_op; git shrinks from eleven tools to six (status/diff/log/add/commit/pr) with rarer operations going throughexecute_bash. A newautotune profile - now the default - infersfull/minimal/nanofrom the model's parameter count, so small local models automatically get the slim tool set and prompt while large/cloud models are unchanged. The resolved profile re-resolves live on model switch and is surfaced in the input indicator (e.g.tune: nano (auto))./usageand the context indicator now rebuild from the live tune/mode/model with the profile-filtered tool count, so usage and context reporting are trustworthy. Roughly 6.3k lines removed. -
Added structured tool results and single-source validation. Tool arguments are now type-checked against each tool's JSON schema at the execution boundary (
schema-validate.ts), so malformed model output returns a clear field-level error the model can self-correct from, instead of being coerced at the render layer. Validation runs through the singlewithValidationseam shared by both the native and XML-fallback execution paths, ahead of any per-tool validator. Approval policy is likewise centralised and the old global mode context removed, so the current development mode (including a mid-run switch) is honoured consistently across the main loop and subagents. -
Added session resume with full history replay. Resuming a saved session now replays the message and tool-call history into the chat view via a new
session-history-renderer, so you pick up exactly where you left off with the conversation visible rather than an empty screen. Companion fixes resolved an autosave race, history-truncation, and resume edge cases, with regression coverage. Thanks to @akramcodez. Closes #545. -
Added the
/copycommand to copy the most recent assistant response to the system clipboard. Cross-platform viaclipboardy(pbcopy / xclip / clip.exe), with a clear warning when there is no assistant message and a surfaced error when the clipboard write fails. -
Added read-before-edit guards and tool-call loop detection for local models.
string_replaceandwrite_filenow require the file to have been read first, and a tool-signature tracker detects a model repeating the same tool call in a tight loop. Both make smaller local models materially safer to run unattended. -
Added a skill linter (
/skills check <name>and acheck_skilltool) that validates a bundle from disk with the same parsers the loader uses, so a PASS means it will load. It is wired into/skills createso the model verifies and self-corrects what it generates, and it lints member template bodies (unsupported mustache tags, unbalanced or unclosed sections, placeholders referencing undeclared parameters), not just frontmatter. Also added optional command arguments: inline defaults (name=default) and conditional sections ({{# name }},{{^ name }}) in command bodies, plus inverted-section support in custom-tool templates via a shared section engine. Fixed subagents ignoring the development mode (the executor capturednormalonce at startup and never updated it). -
Added Atlas Cloud as a first-class provider and sponsor, with a wizard onboarding template and a dedicated provider docs page.
-
Added the Requesty provider (https://requesty.ai) as a first-class OpenAI-compatible provider, mirroring the OpenRouter integration with a name matcher, app-attribution headers, a wizard onboarding template, and docs. Thanks to @Thibaultjaigu. Closes #589.
-
Added API-reported context usage with an estimate fallback. The
ctx: NN%indicator now reflects provider-accurate token counts when the model reports them (captured from the final step'susage, not the tool-loop-summedtotalUsage), falling back to client-side estimation otherwise. Estimated figures are marked with a leading~(ctx: ~42%); API-reported figures render bare. Thanks to @JimStenstrom. Refs #381. Follow-up work anchored the API figure across turns, counted real tool definitions in the auto-compact gate, and added a tiktoken-based generic fallback tokenizer for more accurate counts on models without a native tokenizer. -
Added git branch display in the boot summary and
/statuspanel, with a narrower-terminal-friendly rendering. Thanks to @ragini-pandey. Closes #539. -
Reworked provider model discovery UX in the wizard, surfacing real discovery errors instead of silently falling back, and showing model names in the selection list with long labels truncated by ellipsis. Thanks to @akramcodez and @Dhirenderchoudhary. Closes #554.
-
Added arrow-key navigation and highlighting for slash-command completion. The completion menu now navigates with the arrow keys, with the double-submit-on-select bug fixed (TextInput ignores Enter; UserInput handles select-then-submit behind a guard flag) and
customCompletionrestored. Thanks to @rakshith1928. Closes #578. -
Added a force-compact-and-retry fallback. When the LLM server rejects a request for exceeding its context window, nanocoder now compacts and nudges the conversation to continue instead of failing outright. Thanks to @lordoski. Closes #546.
-
Added timeout, output limits, and abort support to the bash executor, with regression tests covering the executor lifecycle. Thanks to @akramcodez. Closes #547.
-
Custom display: failed tool results condense to a one-liner in compact mode. Generic
Error:/Validation failed:results now render as a short red line (e.g.write_file failed.) in compact display mode, while the model still receives the full error in history and non-compact mode still shows it in full. -
Improved
ask_userprompt rendering: dropped the leading?from the header, fixed spacing and the hanging indent, added arrow-key navigation, and normalised object-shaped options to readable strings (preferring a label over a value id). -
Improved
@-file-mention handling: mention placeholders are kept in the chat instead of being expanded inline, and large-file inlining is capped to avoid blowing up the prompt. -
Fix: Copilot GPT-5 reasoning streams are now handled correctly via an
@ai-sdk/openaipatch and chat-handler changes, so reasoning content streams properly instead of breaking the response. Thanks to @EntropyParadigm. Closes #577. -
Fix: propagate
AbortSignalto streaming bash execution, so cancelling a turn actually stops a long-running streamed command. Thanks to @Dhirenderchoudhary. Closes #550. -
Fix: prevent silent overwrite of corrupted config files. A corrupted
agents.config.jsonno longer gets silently clobbered; the wizard now honours theprojectDirprop for config-path resolution and the infinite render loop on theexistingProvidersdefault param is resolved, all with regression coverage. Thanks to @Dhirenderchoudhary. Closes #551, #552. -
Fix:
read_filereturns an empty marker instead of throwing on empty files, including range and metadata-only reads, with theEMPTY_FILE_MARKERconstant extracted (later renamedEMPTY_CONTENT_MARKER) and tests for files containing only a newline. Thanks to @ragini-pandey. Closes #530. -
Fix: prevent orphaned tool results from breaking LLM compaction. A tool-aware boundary in the converter and summariser stops a recent-tail slice from splitting a tool-call group, which previously produced empty model output after compaction.
-
Fix:
/key no longer scrolls the chat view to the bottom. Thanks to @itsishant. Closes #590. -
Fix: close the chokidar watcher if daemon startup throws, and move the daemon stop-handler setup before resources start so a failed lockfile write calls
stop()and cleans up. Thanks to @OMEE-Y and @rakshith1928. Closes #553, #557. -
Fix: replaced a stray
console.loginmessage-queue.tsxwith the structured logger. Thanks to @A-S-Manoj. Closes #588. -
Fix: added subagent context window overrides so delegated agents can run with a different context limit than the main session, and resolve provider names case-insensitively with custom CA bundle support for provider TLS. Thanks to @zerone0x.
-
Added a
tmp >=0.2.6override to resolve a path-traversal advisory in a transitive dependency. Thanks to @ragini-pandey. -
Large refactor and dead-code sweep: unified tool-call ID generation, extracted a shared
useWizardFormhook, consolidated session-override managers, added message-factory helpers, deduped config loaders / git exec / command dispatch / conversation-loop flush, extractedStyledSelectInputandmakeSimpleToolFormatter, and deleted several dead modules and orphaned exports (includingfetch-local-modelsorphaned by an earlier removal). -
Updated the Nanocoder Battlemap competitive comparison and refreshed the README and docs.
-
Dependency updates:
ai6.0.174 -> 6.0.193,@ai-sdk/openai,@ai-sdk/openai-compatible,@ai-sdk/anthropic,@agentclientprotocol/sdk0.22.1 -> 0...
nanocoder v1.27.0
What's Changed
-
Added Skills, a unified extension primitive that brings commands, subagents, and tools under a single ergonomic surface. Two forms over one primitive: single-file (a
.mdin.nanocoder/commands|agents|tools/, fully backwards-compatible with the existing flat dirs) and bundle (a directory under.nanocoder/skills/<name>/withskill.yamlplus optionalcommands/,agents/,tools/subdirs). Bundles are for multi-piece features that need to ship and version together: a bundle's subagent automatically gets its sibling tools, scoped tools are hidden from the global tool list (default for bundles, opt-in for single-file), and bundle commands auto-namespace (commands/status.mdin bundlegitinvokes as/git:status). New/skillsslash command lists everything loaded, and bundled members fan out into the existingCustomCommandLoader,SubagentLoader, andToolManager.registryso downstream consumers keep using their familiar registries. Closes #515. -
Added event-triggered skill runs via a new per-project daemon. Skill members can declare
subscribe:blocks in frontmatter (or a bundle manifest) and the daemon wakes them onfile.changedandschedule.cronevents. The daemon (nanocoder daemon <start|stop|status|logs>) runs as a long-lived background process with a lockfile, Unix-socket IPC, and installers for launchd (macOS) and systemd user units (Linux). The interactive TUI never starts event sources, so file watching and cron only run when you opt in. Triggered runs execute in a new internal headless mode (noask_user, no foreground confirmations) which supersedes the legacyschedulermode. Per-subscriptionconfirm: trueopts intoplanmode instead. Backpressure caps per-subscription concurrency and trailing-debouncesfile.changedby 500ms so chatty save loops don't pile up. -
Removed the legacy
source/schedule/module (runner,storage,index,types). Schedules are now expressed asschedule.cronsubscriptions on a skill member and dispatched by the daemon. The olduseSchedulerModehook,scheduler-viewcomponent, and the.nanocoder/schedules.json/.nanocoder/schedules/*.mdstorage layout are gone. The/schedulecommand has been trimmed and refocused around the new model. Closes #524. -
Added Custom Tools: markdown-defined, model-callable tools that sit between custom commands (prompt injection only) and MCP servers (full external process). Drop a
.mdinto.nanocoder/tools/(project) or~/.config/nanocoder/tools/(personal), declare parameters in YAML frontmatter (with JSON Schema-styletype,required,pattern,maxLength, etc.), and write a shell command body using{{ name }}and{{# section }}template placeholders. All substitutions are shell-quoted to prevent injection. Includesapproval(always/never) andread_onlyflags that participate in mode policy: plan mode requiresapproval=never && read_only=true, scheduler/headless requiresapproval=never. New/tools create <name>scaffolds a template and asks the model to help fill it in. Project tools shadow personal ones byname, and they register into the sameToolManagerregistry as built-ins and MCP tools so/tools, subagents, and mode filtering see them through a single unified registry. Closes #520. -
Added LLM-based context compaction as the default
/compactstrategy. The active model writes a structured markdown summary of the compressible segment (Context / Decisions / Files modified / Tools used / Open questions) using a dedicated summariser prompt, replacing the older messages with one synthetic summary while recent messages are kept verbatim. Higher fidelity than mechanical truncation at the cost of one extra round-trip. Newstrategyfield inautoCompactconfig (llmdefault,mechanicallegacy), new CLI flags (--llm,--mechanical,--strategy <name>), and automatic fallback to mechanical compression on LLM failure (network error, empty response, summary larger than original). Auto-compact uses the same strategy. -
Added OpenRouter request configuration via a dedicated
openrouterblock on the provider config. Forwards OpenRouter-specific request body fields (providerrouting rules,reasoning,plugins,modelsfallback list,service_tier,route,user, etc.) on every request - always-on transport/routing concerns, not gated by/tune. Provider is detected by name (case-insensitive).tune.modelParameters.reasoningEffortpopulatesopenrouter.reasoning.effortwhen unset; explicit values on the provider config always win. Closes #519. -
Added config lint at startup. Surfaces common misconfigurations as warnings before they cause silent failures - e.g. an
openrouterblock on a provider that is not OpenRouter, unknown fields, type mismatches. Includes a full test suite. Closes #523. -
Reworked OpenRouter model selection in the provider wizard. Replaced the previous list with a paginated, searchable
ModelSelectionList(12 visible items, page navigation, multi-select with running counter, select-all, error state). Makes browsing OpenRouter's hundreds of models actually usable from the wizard. Closes #516. -
Added unified Session Service for key generation and session infrastructure. Consolidates the various ad-hoc keying strategies scattered across commands, handlers, and tool result display into one place. Touched 50 files across handlers, commands, hooks, and the chat handler, removing duplicated key-derivation logic and shrinking
useAppStateby ~38 lines. Fully closes #229. -
Added the Nanocoder Battlemap - a long-form competitive comparison doc covering Nanocoder against Claude Code, OpenAI Codex CLI, Gemini CLI, Aider, OpenCode, Crush, and Pi across twelve axes (license, pricing, local-model support, MCP, extensibility, tool-calling, subagents, surface, plain mode, stars, contributors, telemetry). Honest where Nanocoder leads, honest where it does not. Closes #423.
-
Made code blocks copyable without ASCII artifacts. Reworked the markdown parser and
AssistantMessagerendering so fenced code blocks render as plain selectable text without surrounding box borders that previously got copied into the clipboard. Thanks to @aravindinduri. -
Fix: streaming OOM on long responses.
StreamingMessagewas callingwrapWithTrimmedContinuations()on the entire growing assistant message on every ~150ms flush, allocating per-line arrays proportional to the full message size. A ~37k-token (~150 KB) response would overwhelm GC and crash the 4 GB Node heap. Now slices the message to a bounded tail (MAX_LINES * textWidth * 4chars, snapped to a newline boundary) before wrapping, so per-render work is constant in the visible window rather than linear in total streamed content. Thanks to @abhishekDeshmukh74. Closes #526. -
Fix: performance entry buffer OOM in long sessions. React 19's
react-reconciler(dev build) callsperformance.measure/performance.markon every render, and Node's built-in fetch (undici) pushes a resource-timing entry per HTTP request. Both write to the same global buffer, which nanocoder never drained. Over long subagent-heavy sessions the buffer accumulated millions of entries until V8 thrashed in mark-compact GC and crashed withIneffective mark-compacts near heap limit. Fix installs an unref'd 30s interval that callsperformance.clearMarks()/performance.clearMeasures()in the Ink render path. Thanks to @ragini-pandey. Closes #521. -
Fix: auto-compact ignored the per-provider
contextWindowoverride. The auto-compact threshold was computed against the model's default context window even when the provider config narrowed it, causing compaction to fire late (or not at all) on providers configured with a smaller usable window. Closes #525. -
Fix: surface real provider errors instead of
[object Object]. The error parser now extracts meaningful messages from AI SDK errors (status codes, body excerpts, nestedresponseBodyfields) before they reach the UI, so model and API failures show up as actionable text instead of an opaque stringified object. -
Fix: removed dead MCP server hosts from the wizard templates.
remote.mcpservers.organd a handful of other defunct discovery endpoints were still listed inmcp-templates.tsand would silently fail when selected. Companion dead-URL guard inmcp-clientprevents the wizard from surfacing entries it cannot reach. -
Fix: markdown parser regressions in fenced code extraction. Indented fenced code blocks (e.g. inside list items) now extract correctly, fenced blocks nested inside blockquotes are no longer split out (they belong to the quote), and indented list continuations are preserved as list text instead of being misparsed as indented code. Removed indented-code extraction from the shared markdown parser entirely - only fenced blocks split out for copyable rendering.
-
Fix: tightened the task management section of the system prompt to reduce over-eager task list creation on small jobs.
-
Minor: nudged the system prompt to avoid markdown tables in output. Tables render poorly in the terminal even though the markdown converter supports them, so the model is now steered toward bullet lists or short prose.
-
Fix: Nix packaging - reproducible pnpm 11 builds via
pkgs.pnpm_11now that nixpkgs PR #505103 has landed. Drops the version-override scaffolding, thechmod +x pnpm.cjspostInstall hack, and themanage-package-manager-versionsreplaceStringspatch from the previous release. Also documents and works around an upstreamfetch-pnpm-depsshell bug (export VAR valuewithout=) that caused non-deterministicv11/index.dbwrites whenside-effects-cachefell back to true. Re-enables theupdate-nix.ymlworkflow. Closes #511. -
Audit/security: updated
pnpm-workspace.yamlauditConfigandminimumReleaseAgeExcludeentries to align with the versions resolved ...
nanocoder v1.26.1
What's Changed
-
Bumped
@nanocollective/get-mdto^1.4.0, which makesnode-llama-cppan optional peer dependency. Drops the entirenode-llama-cpptransitive — including ~500 MB of platform-specific native binaries (CUDA, Vulkan, Metal, ARM variants) that pnpm fetched eagerly regardless of host — from the install graph and the Nix closure. Thefetch_urltool (the only consumer of get-md) uses the standard HTML→Markdown path which doesn't need the LLM converter, so there's no functional change. -
Patched
flake.nixfor pnpm 11 compat. Overrides nixpkgs's bundled pnpm (currently 10.x) to pnpm 11.0.9 to matchpackageManager, then handles two pnpm-11-specific quirks:chmod +xonbin/pnpm.cjs(a Corepack-compat shim shipped without the execute bit by upstream) and areplaceStringspatch onfetchPnpmDeps'sinstallPhaseto skip the now-rejectedpnpm config set manage-package-manager-versions falseglobal write. Unblocks theupdate-nix.ymlworkflow that's been failing onERR_PNPM_LOCKFILE_CONFIG_MISMATCH.
Installation
npm install -g @nanocollective/nanocoderUsage
nanocoderFull Changelog: v1.26.0...v1.26.1
nanocoder v1.26.0
What's Changed
-
BREAKING: Removed redundant
nanocoderTools.alwaysAllowsetting. It duplicated the top-levelalwaysAllowwith no extra behaviour. Move any entries fromnanocoderTools.alwaysAllowto the top-levelalwaysAllowarray inagents.config.json. The deprecatedagents.config.example.jsonhas also been removed. -
Added nano mode — a third tool profile under
/tunedesigned for the smallest open-weights models or low-end hardware running larger models locally. Strictly more aggressive thanminimal: dropsfind_files,list_directory, andagent; trimsCORE PRINCIPLESandCODING PRACTICES; uses ≤4-lineTASK APPROACH,FILE OPERATIONS, andCONSTRAINTSsections; replaces the verboseSYSTEM INFORMATIONblock with a single-line## SYSTEMline; and omitsAGENTS.mdfrom the prompt by default. Brings the system prompt from ~500–700 tokens (minimal) down to ~150–250 tokens. Includes a new "Nano (low-end hardware)" preset and an Include AGENTS.md toggle. -
Added reasoning trace support. Reasoning content from models (Codex GPT-5, DeepSeek-R1-style, Anthropic extended thinking, etc.) now streams in real time, renders as a collapsible
Thoughtblock above the response, persists across history, and is included in logs. Toggle expansion withCtrl+R, configure default expansion via the new Display Settings panel, and pin per-session via the tuneexpandedReasoningoption.<think>tags are now stripped on the native tool-calling path so reasoning never leaks into rendered output. Thanks to @Daniel5055. Closes #457. -
Added refined non-interactive mode. A new
--plainflag streams output suitable for CI pipelines, scripts, and pipes — no Ink rendering, no interactive prompts, deterministic exit codes, and proper handling of stdin/stdout. Includes a dedicatednon-interactive-shellcomponent and full test coverage for the plain transport. -
Reworked VS Code extension integration. Removed the "Ask Nanocoder" command in favour of a more natural flow: highlighted text and the currently focused file are automatically pulled into Nanocoder as context. Backed by a rewritten extension protocol, a simplified extension entrypoint, a new
useVSCodeServerhook, and tighter UI hooks for the development mode indicator and chat input. -
Added
/renamecommand for renaming the current chat session. Accessible from the chat input and reflected in the development mode indicator. Thanks to @lordoski. -
Added
defaultModeconfig option for interactive sessions. Set a starting mode (normal,auto-accept,yolo,plan) inagents.config.jsoninstead of always launching in normal mode. Thanks to @lordoski. -
Added custom system prompt support via
agents.config.json. Define a project-level system prompt that replaces or augments the built-in prompt sections, with full validation and prompt-builder integration. Closes #487. -
Added per-provider and per-model context window overrides in
agents.config.jsonviacontextWindowandcontextWindows[model]. New resolution order: session override (/context-max,--context-max) → provider model override → provider default →NANOCODER_CONTEXT_LIMIT→ models.dev / Ollama fallback./usage, status bar, auto-compact, and context reporting all use the active provider config consistently. Closes #455. -
Added subagent context window overrides so delegated agents can run with a different context limit than the main session. Thanks to @zerone0x.
-
Added
disabledToolsconfig option inagents.config.jsonto disable specific built-in tools project-wide. Honoured by both the main agent and subagents. -
Added
--trust-directoryCLI flag to bypass the first-run directory trust prompt for automation. Yolo mode now also skips file path validators in line with its "auto-accept everything" semantics. -
Added JSON tool fallback mode for non-tool-calling open-weights models (Qwen, Kimi, GLM). The tune menu now cycles through Native ON / OFF (XML) / OFF (JSON), with
formatToolsForJSONPrompt()embedding literal JSON Schema and a JSON branch in the tool-call parser. Native path also gains JSON/XML hallucination recovery:parseToolCalls()is run against text content when the SDK reports notool_calls, andstripEmbeddedToolCallText()removes echoed tool-call text so Ghost Echo no longer leaks into the UI or history. Reference #500. -
Added
<function=...>format to the tool-call parser for models that emit OpenAI-style function tags. -
Added Display Settings panel under
/settings("Tool Results and Thinking") with two new toggles: Show Thinking by default (Ctrl+R) and Expand Tool Results by default (Ctrl+O), persisted tonanocoder-preferences.json. Thanks to @cleyesode. Closes #499. -
Added 12+ new themes to the bundled theme set.
-
Removed the in-repo release content generator workflow. Release content is now generated from another repo via ContentForest.
-
Bumped CI and devcontainer toolchain to Node.js 22 + pnpm 11 across
pr-checks.yml,release.yml,update-badges.yml, and.devcontainer/Dockerfile.engines.noderaised to>=22, with apackageManagerfield (pnpm@11.x.x) added topackage.jsonso Corepack pins the pnpm version automatically for both contributors and CI — no more drift, no per-workflowversion:lines.CONTRIBUTING.md/docs/getting-started/installation.md/.devcontainer/README.mdupdated to match. Fixes thenode:sqliteERR_UNKNOWN_BUILTIN_MODULEcrash hit by pnpm 11 on Node 20 runners. -
Migrated pnpm config from
package.jsontopnpm-workspace.yamlfor pnpm 11 compatibility:overrides,patchedDependencies, and the newallowBuildsblock now live in the workspace file. While migrating, audited and removed all 16 existing version overrides — every one was redundant under current dependency resolution (each transitive resolved to a version already exceeding the override's floor), and removing them leftpnpm auditoutput unchanged. -
Major spring-clean refactor across the codebase. Extracted shared
oauth-logincommand from the duplicatedcodex-loginandcopilot-loginflows; introduced shareditem-selectorcomponent used bymodel-selectorandprovider-selector; centralisedtool-needs-approvallogic; moved AI SDK error-handling specs into a dedicated subdirectory; tightened logging method factory; and trimmed redundant code paths inconversation-loop,subagent-executor, and the plain shell. -
Refactored
App.tsxand added missing test coverage for the app container and chat input components. -
Refactored settings theme selector UX. Replaced the scrollable
SelectInputwith arrow-key navigation, real-time theme preview, and a "Theme Name [n/N]" position indicator. Preferences are only persisted on Enter. -
Updated the system prompt to encourage subagent use more proactively for complex multi-step tasks.
-
Strip leading and trailing whitespace from assistant messages so blank lines and stray newlines from the model no longer push content around in the UI.
-
Fix: Empty model responses now trigger a capped auto-continue instead of crashing or burning tokens forever. Empty-response retry notices are coalesced into a single live counter so the chat history stays readable.
-
Fix: Surface context-size failures explicitly instead of silently retrying empty responses. Thanks to @zerone0x. Closes #501.
-
Fix: Persist compressed messages across recursive conversation turns. Auto-compact now also resets the streaming token count after compression, with regression coverage to keep it stable. Thanks to @lordoski. Closes #480.
-
Fix: Throw stream errors immediately during streaming instead of swallowing them and ending the response cleanly. Thanks to @alexbrjo.
-
Fix: Cap malformed-XML retries to prevent OOM when a model gets stuck emitting broken tool-call XML in a tight loop. Reference #500.
-
Fix: Stale
lastProviderafter running the config wizard mid-session — the next/providerinvocation picked up the old value. Includes regression coverage. Thanks to @electricwolfemarshmallowhypertext. Closes #477. -
Fix: Inaccurate tok/s reporting in the streaming status line.
-
Fix: File search, content search, and
@mentionautocomplete now work cross-platform. Replaced Unix-onlyfind/grep/whichshell-outs with pure Node.js implementations honouring.gitignoreandDEFAULT_IGNORE_DIRS, restored the 30s search timeout viaAbortSignal, and added Windows path normalisation. Thanks for the cross-platform report (#469). -
Fix: Read file tool description corrected.
-
Fix: Type
MCPTool.inputSchemaasJSONSchema7instead ofany, withisPlainObjectguard at the MCP protocol boundary so malformed server schemas resolve toundefinedrather than flowing through the system as a trusted type. Thanks to @ragini-pandey. Closes #467. -
Fix: Apply
caCertPathTLS configuration to Anthropic and Google providers (previously only OpenAI-compatible providers honoured it), with cert path validation. Companion fix for custom CA bundle support across all providers. Thanks to @zerone0x. Closes #491 (#380). -
Fix: Reject ambiguous provider names with case-insensitive duplicates (e.g. both
Ollamaandollamadefined). Provider names are now resolved case-insensitively throughout. Thanks to @zerone0x. Closes #488. -
Fix: Quoted custom command arguments (double, single, and backtick) are now parsed as a single parameter so multi-word values survive tokenisation. Closes #478.
-
Fix: Missing margin on the live sub-agent progress component.
-
Fix:
git_prtool still required approval in yolo mode. -
Fix:
bashmode no longer passes the currently selected file when not relevant. -
Fix: Incorrect passing of system prompt in some chat-handler paths.
-
Fix: Default missing
subagent_typeanddescriptionparameters on theagenttool to safe values to prevent a UI crash when the model omits them. -
Fix: Mo...
nanocoder v1.25.2
What's Changed
- Fixed Nix package: copy
themes.jsonand prompt section files into the Nix store sonix runno longer crashes at startup - Fixed Nix package: corrected wrapper script heredoc indentation that broke the shebang line
If there are any problems, feedback or thoughts please drop an issue or message us through Discord! Thank you for using Nanocoder.
Installation
npm install -g @nanocollective/nanocoderUsage
nanocoderFull Changelog: v1.25.1...v1.25.2
nanocoder v1.25.1
What's Changed
- Removed rogue document from
docs/
If there are any problems, feedback or thoughts please drop an issue or message us through Discord! Thank you for using Nanocoder.
Installation
npm install -g @nanocollective/nanocoderUsage
nanocoderFull Changelog: v1.25.0...v1.25.1
nanocoder v1.25.0
What's Changed
-
Added yolo mode — a new development mode that auto-accepts every tool without exception, including bash commands and destructive git operations (hard reset, force delete, stash drop/clear). Cycles between normal → auto-accept → yolo → plan via Shift+Tab. The status bar turns red when yolo mode is active.
-
Added subagents — isolated child conversations that the LLM can delegate work to. Ships with two built-in agents: Explore (read-only codebase investigation) and Reviewer (code review with actionable feedback). Subagents are defined as markdown files with YAML frontmatter specifying name, description, model, and allowed tools. User-defined subagents can be placed in
.nanocoder/agents/. Managed via the/agentscommand (show,create). Thanks to @BRIJESHKR for the initial subagent implementation. Closes #414. -
Added concurrent subagent execution. The LLM can launch multiple subagents in parallel, each with independent tool sets and live in-place progress rendering via the
AgentProgresscomponent. -
Added subagent tool approval matching main agent behaviour. Subagent write tools prompt for approval and bash always prompts unless in
alwaysAllow. Theagenttool itself no longer requires approval since internal tools have their own gates. -
Redesigned the system prompt into a modular, composable architecture. The monolithic
main-prompt.mdhas been replaced with individual section files undersource/app/prompts/sections/(identity, core principles, coding practices, file editing, tool rules, diagnostics, task management, etc.). The newprompt-builderassembles the prompt dynamically based on the current mode — normal, auto-accept, plan, and scheduler each get a tailored prompt with only the sections and tools relevant to that mode. Includes agenerate-system-promptsscript for offline token counting and prompt inspection. -
Made plan mode useful. Plan mode now enforces read-only tools at the policy level — all mutation tools (write, bash, git commit/push, task management) are blocked, leaving only exploration tools (read, search, find, list, git log/diff/status). The dedicated plan mode system prompt instructs the LLM to investigate thoroughly and produce a structured plan with summary, files to modify, step-by-step approach, dependencies/risks, and open questions — instead of trying to execute changes.
-
Added
/tunecommand for per-session prompt and tool customization. Includes a tune selector UI (Ctrl+T) with tool profiles (full, minimal), adisableNativeToolstoggle for forcing XML fallback, and aggressive compact mode. Tune state persists for the session and is reflected in the mode indicator. -
Centralized tool policy into
ToolManagerso prompt-time tool filtering and runtime approval use the same source of truth. Extractedtool-registry.tsfor cleaner separation of tool definitions from policy logic. -
Added ChatGPT Codex as a provider with OAuth device flow authentication (
/codex-login), streaming response support via a dedicatedStreamingMessagecomponent, and Codex-specific credential management. Includes provider template and setup wizard integration. -
Migrated
web_searchtool from Brave Search scraping to the official Brave Search API. Now requires awebSearch.apiKeyinagents.config.jsonundernanocoderTools. Removes thecheerioscraping dependency. -
Added
/setup-configcommand that lists all config files (project and globalagents.config.json,.mcp.json,nanocoder-preferences.json) with their paths and opens the selected one in your editor. -
Added configurable paste threshold for single-line paste handling, with tests for the configurable placeholder threshold. The threshold is a user preference in
nanocoder-preferences.json. Changed the default config file for paste settings fromagents.config.jsontonanocoder-preferences.json. Thanks to @grenkoca. -
Added live in-place task list display. Task progress now updates in place instead of appending repeated static lists to the conversation.
-
Improved tool output truncation across all tools. Every tool formatter now respects terminal width for cleaner output, including
execute_bash, file ops, git tools,search_file_contents, andweb_search. -
Redesigned the provider setup wizard with a unified model fetcher that auto-detects API compatibility (OpenAI-compatible, Ollama, Anthropic, Google) and fetches available models from the provider's endpoint. Simplified the provider step UI and added MiniMax and Kimi provider templates.
-
Fix:
alwaysAllowconfig not being respected forexecute_bash. Three interconnected bugs prevented it from working: top-levelalwaysAllowwas never loaded fromagents.config.json,isNanocoderToolAlwaysAllowedonly checkednanocoderTools.alwaysAllownot the top-level list, andnonInteractiveAlwaysAllowsetneedsApprovalon AI SDK tools but the conversation loop evaluated it from the original registry entries. Closes #431. -
Fix:
dimColormaking text inaccessible to reading on some screens. Closes #440. -
Fix: Tasks now clear when running
/clearcommand. -
Fix: Prevent edit flow from resolving MiniMax/Kimi to Anthropic template.
-
Fix: Set correct default model for MiniMax provider.
-
Fix:
/usageand context percentage showing stale system prompt length. AddedsetLastBuiltPromptand fixeduseContextPercentageoverwriting cache. -
Added debug logging to 15 silent catch blocks in git utilities that were swallowing errors invisibly. Operational catches now log at debug level for easier diagnosis while boolean probes (e.g.
isGitAvailable,branchExists) remain intentionally silent. Thanks to @ragini-pandey. Closes #452. -
Security: Address semgrep security finding in console.error. Thanks to @BRIJESHKR.
-
Security: Fixed vulnerable packages. Thanks to @BRIJESHKR.
-
Security: Replaced
exec()withexecFile()in VS Code extension installer to prevent command injection. Removes shell interpretation from CLI discovery and extension status checks. Thanks to @ragini-pandey. -
Added
/creditscommand showing project contributors (auto-generated from git history viapnpm run build:credits) and dependency versions. -
Added desktop notifications for tool confirmations, question prompts, and generation completions. Supports macOS (
terminal-notifierwith osascript fallback), Linux (notify-send), and Windows (PowerShell). Configurable per-event innanocoder-preferences.jsonand in/settingswith custom messages and optional sound. Includes a "Notifications" settings menu for preference management. -
Added CLI quality metrics framework (
benchmarks/measure.ts,benchmarks/report.ts) tracking correctness, performance (module count, boot time, bundle size), stability (tool/command counts, help text hash), and health (test counts, vulnerabilities). -
Reduced startup time by parallelizing and deferring non-critical initialization. LLM client and subagent init run in parallel on the critical path; update checks, MCP servers, and LSP servers now initialize in the background without blocking chat. Replaced the full Status box with a lightweight one-line
BootSummarycomponent. -
Fix: Scheduler mode memory leak — chat messages and components now clear before each scheduled job execution, preventing memory accumulation across repeated runs.
-
Fix: Updated agent documentation (
AGENTS.md,CLAUDE.md) with current project structure (766 files across 97 directories), added missing directory mappings, removed deprecated references, and documented the lazy-loading command system. -
Fix: Improved Ollama timeout handling for slow local models. Timeout errors are now detected case-insensitively, and IPv6 loopback addresses are correctly resolved. Thanks to @ragini-pandey.
-
Dependency updates
If there are any problems, feedback or thoughts please drop an issue or message us through Discord! Thank you for using Nanocoder.
Installation
npm install -g @nanocollective/nanocoderUsage
nanocoderFull Changelog: v1.24.1...v1.25.0
nanocoder v1.24.1
What's Changed
-
Added
--context-maxCLI flag for setting the context limit from the command line, complementing the existing/context-maxcommand andNANOCODER_CONTEXT_LIMITenv variable. -
Removed time from the system prompt to keep the KV cache more stable across requests. Thanks to @initialxy. Closes #415.
-
Task tool results are no longer displayed as compacted results during ensuring task progress remains visible in the conversation.
-
User input now uses the same text wrapping as assistant messages for a more consistent chat appearance.
-
Improved
search_file_contentstool robustness.
If there are any problems, feedback or thoughts please drop an issue or message us through Discord! Thank you for using Nanocoder.
Installation
npm install -g @nanocollective/nanocoderUsage
nanocoderFull Changelog: v1.24.0...v1.24.1
nanocoder v1.24.0
What's Changed
-
BREAKING: Removed legacy
~/.agents.config.jsonconfig file support. Nanocoder no longer checks the home directory for a dot-prefixed config file. If you are still using this path, move your config to the platform-specific directory:~/Library/Preferences/nanocoder/agents.config.json(macOS),~/.config/nanocoder/agents.config.json(Linux), or%APPDATA%\nanocoder\agents.config.json(Windows). -
BREAKING: Removed legacy
~/.nanocoder-preferences.jsonpreferences file support. Preferences are now only loaded from the platform-specific directory (e.g.~/Library/Preferences/nanocoder/nanocoder-preferences.jsonon macOS) or a project-levelnanocoder-preferences.jsonin your working directory. To migrate, move your existing file:mv ~/.nanocoder-preferences.json ~/Library/Preferences/nanocoder/nanocoder-preferences.json -
BREAKING: Removed deprecated array format for MCP server configuration. Only the object format is now supported:
{ "mcpServers": { "serverName": { ... } } }. If you are using the array format in.mcp.json, convert each array entry to an object key using the server name. -
BREAKING: Removed
agents.config.jsonfallback for MCP server loading. Global MCP servers must now be configured in~/.config/nanocoder/.mcp.json(Linux),~/Library/Preferences/nanocoder/.mcp.json(macOS), or%APPDATA%\nanocoder\.mcp.json(Windows). Provider configuration still usesagents.config.json. -
BREAKING: Removed
authandreconnectfields from MCP server configuration. Theauthfield was never functional (both HTTP and WebSocket transports logged warnings that it was unsupported). Thereconnectfield was never implemented. Useheadersfor HTTP authentication instead (e.g."headers": { "Authorization": "Bearer $TOKEN" }). -
Added
/resumecommand for restoring previous chat sessions. Sessions are automatically saved and can be resumed from an interactive selector. Sessions are filtered by the current project directory by default, with an--allflag to show all sessions. Thanks to @yashksaini-coder. -
Added
--providerand--modelCLI flags for non-interactive provider and model specification, allowing CI/CD scripts and automation to skip the setup wizard. Closes #394. Thanks to @james2doyle. -
Added
NANOCODER_PROVIDERSenvironment variable support for configuring providers without config files, useful for Docker containers and CI environments. Closes #307. Thanks to @kaustubha07. -
Added GitHub Copilot as a provider template with OAuth device flow authentication and
/copilot-logincommand. Thanks to @yashksaini-coder. -
Added MLX Server provider template for local Apple Silicon inference. Closes #318.
-
Added parallel tool execution allowing the model to run multiple independent tool calls concurrently for faster task completion.
-
Added compact mode toggle via
Ctrl+Lin chat input to collapse the conversation view. -
Added VS Code fork support for IDE integration (Cursor, Windsurf, VSCodium, etc.). Thanks to @kapsner.
-
Added Aurora Borealis theme.
-
Added notice when the model falls back to XML tool calls, informing users they can switch to a model with native tool calling support.
-
Adopted AI SDK human-in-the-loop pattern for tool approval. Tool confirmation now uses the SDK's built-in
tool-approval-request/tool-approval-responseflow instead of manual tool-call splitting, improving reliability and reducing code complexity. -
Simplified tool processing by removing double XML parsing and the JSON tool call parser. Tool call parsing now happens in a single place and only on the XML fallback path for non-tool-calling models.
-
Restructured documentation into a Nextra-compatible
docs/folder structure with nested sections for getting-started, configuration, and features. The README is now a concise landing page linking to the full docs. -
Refactored app-utils into focused handler files, extracted shared utilities, unified mode state, and stubbed commands for cleaner architecture.
-
Fix:
alwaysAllowfield in MCP server configuration was silently dropped during config loading due to a missing field mapping. MCP tools configured withalwaysAllownow correctly skip confirmation prompts as documented. -
Fix: Provider timeouts are now respected in non-interactive mode. Thanks to @kaustubha07. Closes #402.
-
Fix: Non-interactive mode no longer exits prematurely when the prompt or response contains the word "error".
-
Fix: Invalid CLI arguments no longer trigger the setup wizard. Thanks to @james2doyle.
-
Fix: Installation detector no longer falsely reports Homebrew on macOS when
HOMEBREW_PREFIXis set but Nanocoder was installed via npm. Closes #392. -
Fix: Preserve draft message when navigating through history with arrow keys.
-
Fix:
fetch_urldisplay now truncates to fit terminal width. -
Fix: Validation failures no longer incorrectly prompt for tool confirmation.
-
Fix: Various error message and
execute_bashformatter improvements. -
Fix: Safe process metrics refactored into shared module to prevent duplicate declarations. Thanks to @cleyesode.
-
Security: Package audit failures resolved.
-
Dependency updates:
ai6.0.116,@ai-sdk/anthropic3.0.58,@ai-sdk/google3.0.33,@ai-sdk/openai-compatible2.0.30,@modelcontextprotocol/sdk1.27.1,undici7.24.0,cheerio1.2.0,dotenv17.3.1,wrap-ansi10.0.0.
If there are any problems, feedback or thoughts please drop an issue or message us through Discord! Thank you for using Nanocoder.
Installation
npm install -g @nanocollective/nanocoderUsage
nanocoderFull Changelog: v1.23.0...v1.24.0
nanocoder v1.23.0
What's Changed
-
Added
ask_usertool for interactive question prompts. The LLM can now present the user with a question and selectable options during a conversation, returning their answer to guide the next step. Uses a global question-queue to bridge the tool's suspended Promise with the Ink UI component. -
Added per-project cron scheduler for running AI tasks on a schedule. Schedule files live in
.nanocoder/schedules/as markdown prompts with YAML frontmatter, managed via the/schedulecommand (create,add,remove,list,logs,start). Includes cron expression parsing, sequential job queue with deduplication, dedicated scheduler mode with auto-accept, and run history logging. -
Added centralized graceful shutdown system. A
ShutdownManagernow coordinates cleanup of all services (VS Code server, MCP client, LSP manager, health monitor, logger) on exit, preventing orphaned child processes and dangling connections. Configurable viaNANOCODER_DEFAULT_SHUTDOWN_TIMEOUTenv variable. Closes #239. -
Added file operation tools:
delete_file,move_file,create_directory, andcopy_file. Reorganized existing file tools into afile-ops/directory group. -
Added readline keybind support to text input. Replaces
ink-text-inputwith a customTextInputcomponent supporting Ctrl+W (delete word), Ctrl+U (kill to start), Ctrl+K (kill to end), Ctrl+A/E (jump to start/end), and Ctrl+B/F (move char). Closes #354. -
Added
/context-maxcommand andNANOCODER_CONTEXT_LIMITenv variable for manual context length override on models not listed on models.dev. Resolution order: session override > env variable > models.dev > null. Closes #379. -
Added
/idecommand matching the--vscodeflag for toggling VS Code integration from within a session. -
Added persistent context percentage display in the mode indicator, replacing the previous context checker component.
-
Added
includeandpathparameters tosearch_file_contentstool for scoping searches to specific file patterns and directories. -
Added Kanagawa theme.
-
Refactored the skills system into custom commands, eliminating redundant parsers, loaders, and test suites. Commands gain optional skill-like fields (
tags,triggers,estimated-tokens,resources) for auto-injection and relevance scoring. The/skillscommand is removed and its functionality absorbed into/commandswith new subcommands (show,refresh). Thanks to @yashksaini-coder for the initial skills implementation in PR #370. -
V2 type-safe tool system overhaul with defensive parsing. Implements a three-tiered defense system for handling chaotic LLM outputs, preventing crashes from non-string responses and enabling robust self-correction. Includes universal type safety with
ensureString(), response normalization, confidence system inversion, ghost echo deduplication, and AI SDK contract fixes. Local LLM experience is now significantly more stable. Thanks to @cleyesode. Closes #362. -
Fix: XML parser now uses optimistic matching for consistency with the JSON parser. Thanks to @cleyesode.
-
Fix: Bash tool now emits progress immediately on stdout/stderr data instead of waiting for the 500ms timer, so fast-completing commands show streaming output.
-
Fix: Recognize
127.0.0.1as a local server URL and tighten error classification. Ollama users configuring127.0.0.1instead oflocalhostno longer experience misleading connection errors. Replaced broadconnectsubstring match with specific error codes to prevent misclassifying "disconnect"/"reconnect". Closes #366. -
Fix: Skip loading git tools when not inside a git repository.
-
Fix: Strip ANSI escape codes before running regex matching in tool formatters.
-
Fix: Gap in layout during auto-compact.
-
Fix: Hardened
write_filevalidation and MCP client type safety. -
Fix: Use local
TextInputcomponent instead of the missingink-text-inputpackage. -
Fix(mcp): Use Python-based
mcp-server-fetchinstead of non-existent npm package. -
Security: Semgrep and audit fixes.
-
Dependency updates:
ai6.0.95,@ai-sdk/anthropic3.0.46,@ai-sdk/google3.0.30,undici7.22.0,sonic-boom4.2.1.
If there are any problems, feedback or thoughts please drop an issue or message us through Discord! Thank you for using Nanocoder. 🙌
Installation
npm install -g @nanocollective/nanocoderUsage
nanocoderFull Changelog: v1.22.5...v1.23.0