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.25.0,undici,esbuild,@biomejs/biome2.5.0,lint-staged17,@types/node,@types/vscode, and other transitive bumps tracked through the lockfile. Addedclipboardy ^5.3.1for/copy.
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.27.0...v1.28.0