Scope: 474 commits, 756 files, +75,701 / -6,843 lines, 168 pending changesets (36 minor, ~130 patch, a handful CI-only).
Baseline: tsc --noEmit, biome check, knip, pnpm run test:ava and pnpm run build are all green, and node dist/cli.js --version runs. The ten findings in RELEASE-REVIEW.md have been fixed and committed; the boxes below that reference them are now regression checks rather than known bugs.
How to use this: work top to bottom, tick each box. Anything marked [blocker] should gate the release; everything else is a quality check. Most checks need a real provider configured, so set one up first (/provider, or agents.config.json).
-
pnpm install && pnpm run buildsucceeds from a cleannode_modules -
node dist/cli.js --versionprints the new version -
node dist/cli.js --helplistsarchitectin the--modevalues, and listsconfig,completion,skills,review,daemon -
pnpm run test:avais green [blocker] -
pnpm run test:types,pnpm run test:lint,pnpm run test:knipare green - Packed tarball smoke:
npm packthen run--versionfrom the unpacked tarball (therelease-pack-smokeCI step does this; confirm it ran) -
schemas/agents.config.schema.jsonis present in the publishedfileslist andpnpm run generate:schemaproduces no diff
Interactive sessions now run on the alternate screen by default. This is the single change most likely to generate support noise, so test it on more than one terminal.
- Launch
nanocoderwith no flags - it enters the alternate screen (your scrollback is untouched, the app repaints the whole window) - The prompt box is never pushed off-screen by a long turn; the transcript clips at the top instead
- PgUp / PgDn scroll the transcript
- Mouse wheel scrolls the transcript three rows per tick (not prompt history)
- Resize the terminal mid-session - the frame repaints cleanly, no torn borders
- Exit cleanly (
/exit, Ctrl+C twice) - the terminal is restored: alternate screen off, mouse reporting off, alternate-scroll (DECSET 1007) restored - Kill the process hard (
kill -9from another shell) and confirm how bad the terminal is left;resetshould fix it -
--no-alt-screenreturns to inline mode; finished messages land in real scrollback -
/settings→ "Alternate Screen" toggle works and persists -
--no-mousedisables wheel scrolling and restores native click-drag selection -
/settings→ "Mouse Wheel Reporting" toggle works - In fullscreen with mouse on, Shift+drag (Option+drag in iTerm2) still selects text
-
nanocoder run "...", non-TTY and piped output never enter the alternate screen - Test on at least: macOS Terminal, iTerm2, and one Linux terminal (gnome-terminal / kitty / alacritty), plus tmux
- At 80x24 the welcome screen fits: the last menu item and the tip are both visible
- At >=90 columns the full
NANOCODERblock wordmark renders; below that theNCmonogram - Version line, centered quick-action menu, and branch/directory line all present and centered
- On a tall terminal the whole block is vertically centered
- The subtitle is the project description, not "local-first coding agent"
- The boot summary shows the working directory plus git branch, not the config file's directory
- On a narrow terminal the boot summary keeps provider/model/mode on line one and drops workspace/branch underneath
- Paste a 3-line block - it arrives as one placeholder and does not submit partway through
- The placeholder reads
[Paste #1: 3 lines], not a char count - Paste a long single line - label falls back to
[Paste #N: X chars] - Paste the same text twice - both copies survive into the prompt
- Paste with the cursor in the middle of existing text - the placeholder captures the pasted text, not a slice from the end
- Create two pastes, delete the first, paste a third - the second placeholder is intact (no id reuse)
- Backspace deletes the character before the cursor (this was broken on essentially every terminal)
- Forward Delete still deletes forward
- Undo/redo (readline editing) behaves after a fast burst of typing + undo
-
@filemention inserted then deleted with Backspace removes atomically, no orphan - Resume an old session whose history predates placeholders - a restored paste expands to its content, not its
[Paste #N]label - Press
?in an empty prompt - the keyboard shortcuts overlay opens;?or Esc closes it - Type a character first, then
?- it inserts literally - Ctrl+T toggles the task list; the status-bar badge yields space on a narrow terminal rather than squeezing the session name
- Shift+Tab cycles through normal → auto-accept → yolo → plan → architect (confirm the exact cycle matches
--help) -
--mode architectworks;nanocoder completion zshoffersarchitectas a value - Architect auto-executes file-mutating tools, then opens a review gate before the turn ends
- Revert deletes files the turn created, not just reverting edits
- Revert covers
lsp_format_documentand custom file tools, not onlywrite_file/string_replace - Escape keeps the changes (does not silently revert) and the footer says so
- Revert & Revise sends the instructions you typed, verbatim
- The composer is hidden while the gate is open - keystrokes cannot reach two components, and the gate cannot be bypassed
- After a revert, the model is told its changes are gone (next turn does not edit against a stale view)
- Checkpoints are released once the gate resolves (check the checkpoint list does not grow one per turn)
Configure a nanocoder.hooks block in agents.config.json and exercise each event.
-
session-startoutput is injected as context on the next chat prompt -
session-startcontext is not consumed by a slash command or a!bash passthrough -
user-prompt-submitexiting non-zero denies the prompt, stdout goes back as the reason -
pre-tool-useexiting non-zero denies the tool before any confirmation prompt renders -
post-tool-useoutput is folded into the tool result, including when the tool failed -
pre-compactfires on/compactand on auto-compact -
session-endfires and uses the shorter default timeout - A hook that hangs past its timeout is killed with its whole process tree and skipped, session continues
- Hooks run from the project root even after the agent has
cd'd elsewhere -
matchPathsscopes a hook to the file a tool touched:{"matchTools":["write_file","string_replace"],"matchPaths":["**/*.{ts,tsx}"],"command":"npx prettier --write \"$NANOCODER_FILE\""} - A path-scoped hook does not fire for
execute_bash(no file) - A root-anchored pattern (
src/**) fires whether the model wrotesrc/a.tsor the absolute path - Hooks fire on every surface: TUI,
run,--plain, ACP, subagents (the tool hooks) and TUI +run/--plain(session/prompt hooks) -
/doctorlists the project's wired hooks -
nanocoder.hooksis accepted by the JSON schema (no "unknown key" in the editor) - A hook printing non-ASCII output (emoji, CJK) in large volume renders correctly (fixed, finding 4)
- A hook that traps SIGTERM is gone a second after its timeout, not left running (fixed, finding 5)
-
nanocoder skills add owner/reposhallow-clones, strips.git, lints, and shows a trust prompt - The trust prompt names every tool with its declared approval policy and every event subscription
- Declining installs nothing
- A bundle containing a symlink is refused
- A bundle whose path resolves outside the clone (symlinked subdir) is refused
- Installing over an existing skill requires
--force - A bare name resolves through the index;
NANOCODER_SKILLS_INDEX/--indexoverride it -
--subdirescaping the clone is refused - A local checkout path installs; a local git repo goes through the clone path (uncommitted files do not leak in)
-
--refwith a commit SHA works (falls back to init+fetch+checkout) -
--ref '--upload-pack=...'is rejected, and the command in it does not run (fixed, finding 2)
-
nanocoder daemon startrefuses in an untrusted directory -
--trust-directorybypasses for one run without persisting;NANOCODER_TRUST_DIRECTORY=1persists -
nanocoder daemon status/logs/stopall work -
daemon logson a large log returns the tail without loading the whole file -
daemon logson a log holding one very long line still returns content (not a sliver) -
daemon logswith multi-byte content returns the intended window size - Deeply nested project (socket path past 104 bytes on macOS): the daemon falls back to a hashed socket under the temp dir, and
daemon startreports the path it actually bound - A
file.changedsubscription withdocs/**fires on Windows (path separators normalized) - A root-scoped pattern
*.mddoes not matchsub/a.md - A brace pattern
*.{ts,tsx}fires - An unbalanced brace stays literal instead of throwing
- Two subscriptions sharing one cron expression: unregistering one keeps the other firing
-
confirm: trueon a subscription dispatches inplanmode, notheadless - An unsupported
skill:<name>subscription target errors clearly at load - The
triggeredRunCompletenotification fires after a daemon-triggered run
-
string_replacewith$,$$,$&,$`,$'in the replacement writes those characters literally - The same for
diff_edit - The bytes on disk match the diff that was approved (terminal and ACP)
-
string_replace/diff_edit/write_filerefuse a PDF or DOCX path with a named reason -
write_fileoverwriting an existing file shows a real added/removed diff in the confirmation preview - The same diff appears in the post-execution result, including in auto-accept / yolo
-
write_fileto a brand-new file still shows the syntax-highlighted dump - A
write_fileoverwrite deep in a large file skips long unchanged stretches and still shows the edit
-
write_file,string_replace,diff_editand MCP tools cap at 20 lines with… (+N more lines · /expand n) - When the cap cuts a diff, the note says how many hidden lines are edits
-
/expand <n>prints one result in full, including one folded into a compact tally -
/expandwith no argument lists recent results
-
find_filesmatches./src/**/*.tsand./package.json(leading./stripped) -
./*.tsxbehaves exactly like*.tsx -
search_file_contentsshowsfile:linehits under the match count, capped at 20 lines - A failed search reports the failure instead of returning empty results
-
.nanocoderignorekeeps files out of directory listings, file search and the explorer -
read_fileandexecute_bashdeliberately ignore.nanocoderignore - Checkpoints deliberately ignore
.nanocoderignore(hidden files still snapshotted and restored) - A large ignored directory does not crowd real files out of results
- On a machine with no
rgbinary available, search fails with a clear error rather than silently returning nothing
- A command exiting non-zero is reported as failed in
--plain --jsonoutput - The same command shows as failed over ACP (Zed, VS Code), not "completed"
- The model still receives the same plain text
- Noisy stderr no longer swallows stdout - each stream gets its own budget and truncation marker
- Multi-byte UTF-8 output across a chunk boundary is not garbled
- A compound command displays on separate lines
-
git/ghneeding credentials fails after 60s rather than hanging the session -
showAgentBashOutputpreference (/settings→ Behavior) shows agent command output on the card, compact or not, including failures -
!commandyou type yourself always shows output regardless of the preference
-
nanocoder.sandbox: trueon macOS: writes outside the project + temp dir are denied, network is denied - On Linux with bubblewrap: same
- On Linux without bubblewrap, or without unprivileged user namespaces: a clear error, not a silent fall-through to unsandboxed
- On Windows: clear "not supported" error
-
cdinside a sandboxed command still updates the session cwd - Compilers /
mktemp/npmthat need a writable temp dir still work
-
http://localhost/...,http://foo.localhost/,http://127.0.0.1/,http://[::1]/,http://169.254.169.254/,http://metadata.google.internal/are all refused -
http://2130706433/andhttp://0x7f000001/are refused (URL normalization folds them to 127.0.0.1) -
http://localhost./(trailing dot) is refused -
http://localhost.example.com/is allowed (real host that merely contains the string) - A public URL redirecting to
http://169.254.169.254/is rejected at the hop, not followed - The rejection happens in yolo / headless / subagent runs too, not only where the validator runs
- The truncation warning shows a character count
-
lsp_format_documentformats through the language server and honours.editorconfigindent -
read_filewithmetadata_only: truerenders the metadata layout with a "(metadata only)" marker and a token count from the full file -
metadata_onlyon a directory or symlink still renders the metadata layout -
list_directorywith no path hides dotfiles - Custom tool
cwdresolving outside the project (absolute,${HOME},../, in-repo symlink) fails withCustom tool cwd escapes the project directory - A missing custom-tool
cwdfalls back to the project root - A custom tool that backgrounds a long-lived child is fully killed at its timeout, and the call settles
- A custom tool with huge output does not exhaust memory; stdout and stderr each get their own budget
- Custom tools work on Windows (
cmd.exe /d /s /c) - A tool call whose arguments fail schema validation is never auto-approved; the approval prompt renders with the validation error
- An MCP call with a wrong argument type is rejected locally before reaching the server
-
"enabled": falseon a server actually prevents connection - A server's
alwaysAllowlist applies in normal mode only and cannot override plan mode - Plan mode hides MCP tools that are not annotated
readOnlyHint - Headless / daemon-triggered runs execute MCP tools unattended without "denied by the user"
-
readOnlyHintdoes not skip a confirmation prompt in normal mode -
readOnlyHintdoes not skip an ACP checkpoint or join a parallel batch -
@fuzzy-search lists connected servers' resources alongside local filenames; selecting one inlines its content -
/mcp:<server>:<prompt>fetches the prompt fresh and sends it as the next turn, with positional args filled in - A server declaring neither resources nor prompts contributes none, no error
- Disconnecting MCP keeps workspace custom tools, skill/bundle tools, and their
approval/read_onlymetadata -
web_searchstays absent when no Brave Search key is configured - Project-level
.mcp.jsonwith a hardcoded credential warns; one using$API_KEYdoes not -
/settings mcpoffers the You.com template; empty API key builds the keyless free profile - Re-editing a wizard-built config (e.g.
you-paid) re-opens the original template's form and keeps the bearer token
-
nanocoder.retriesinagents.config.jsonis honoured:maxRepeatedToolCalls(3),maxEmptyTurns(2),maxMalformedRetries(2),maxTruncatedTurns(2) - Hitting the repeated-tool-call limit interactively asks whether to continue or stop
- Non-interactive runs hard-stop
-
--plainapplies the caps and hard-stops with a clear error - Setting a limit to
0restores fail-fast - A call to a nonexistent tool counts toward the repeated-call streak
- A subagent loop applies
maxRepeatedToolCallsand names the setting on stop - A
--plainrun whose reply was cut off at the output-token limit is asked to continue, and does not exit0with a half sentence - A run whose whole deliverable was a tool call does not exit
0having written nothing - Verify with a strict provider that the now-retained unknown-tool
tool_callsentry does not trigger a 400 - seeRELEASE-REVIEW.mdfinding 11 (accepted risk, not fixed)
- Auto-compact runs on
--plain, ACP and subagent loops, not just the TUI - Auto-compact in the TUI actually fires (it silently no-opped after the shared-helper refactor)
- Subagents honour
sessions.maxMessages - Display-only text (
_Cancelled by user._,**Error:** ..., mode toasts, VS Code slash-command replies, ACP revert notices) renders in chat but is not sent to the provider - A compacted session is not told it had errored
- Context-usage estimates and the auto-compact threshold count only what the provider receives
-
--context-max 10kgand/context-max 128kbare rejected, not silently parsed as 10 / 128 - A value large enough to overflow to
Infinityis rejected - Anthropic prompt caching:
/usageand the per-response indicator price cache reads/writes at their own rates and show the cached token count -
"promptCaching": falseon the provider config opts out -
maxOutputTokenson a provider entry raises the ceiling;/tune's max-tokens control works again - On
sdkProvider: "anthropic"with a non-Claude model id, replies are no longer cut at 4096 - The
Nano (low-end hardware)preset'smaxTokens: 2048actually applies - Two providers serving the same model name report different token counts (provider is in the cache key)
- The summariser's
... [truncated N chars]notice fits inside the budget rather than overshooting it
- With scrubbing on, a
cat .envtool result is scrubbed before it leaves the machine - A
git diffcarrying a key is scrubbed -
structuredContentfromlsp_get_diagnostics/write_tasksis scrubbed leaf by leaf - Assistant
tool_callsarguments are scrubbed, including on replay in later turns - Paths and URLs stay in the clear
- A truncation boundary never lands mid-placeholder
- Checkpoint a workspace containing a PNG /
.vsix/ sqlite file, restore it, andcmpthe bytes - they must be identical - A checkpoint that dropped files (unreadable, or over
MAX_CHECKPOINT_FILES) names them at restore time - A file above the workspace is refused for snapshot and reported through
skipped - In a
git inited repo with no commits,git add .then checkpoint - files are captured, not skipped -
git checkout --orphancase likewise -
/checkpoint loadshows a windowed, filterable list; typing filters, the window scrolls, it shrinks on a short terminal -
timeline.jsonsurvives a mid-save kill (write a large timeline,kill -9, reopen) - readers see the complete old or new index -
/resumefilters sessions by keyword; Backspace edits, arrows and Enter pick, Esc cancels - Session selector with no sessions dismisses only on Escape
- The
savingindicator appears in the status line on autosave -
.nanocoder/tasks.jsonis no longer written; task state is session-scoped;/clearstarts a fresh list; resuming restores tasks - Two concurrent sessions do not share one task list
- Automatic session titles: a thin opening prompt gets a generated descriptive name after the first tool-running turn
- A manual rename is never overwritten
-
sessions.smartTitles: falseturns it off;sessions.titleModel/titleProviderpoint it elsewhere - Existing sessions get a one-time retitle on next autosave (expect a visible history reshuffle)
-
nanocoder config listshows every setting, its value, and the source file -
nanocoder config show <key>shows the default and the values it beat -
nanocoder config difflists only what your files change, plus "Ignored values" - Verify the block-override behaviour it documents: set
autoCompact.thresholdin the project file andautoCompact.notifyUserglobally - the globalnotifyUsermust appear under "Ignored values" -
threshold: 200displays as95(capped) - API keys show as
<redacted> - All three accept
--json -
nanocoder completion bash|zsh|fishprints a script; a missing/unknown shell fails with usage -
eval "$(nanocoder completion zsh)"then tab-complete a subcommand and--modevalues -
/repomapbuilds a map with a spinner, no LLM round-trip;/repomap --tokens 4096widens it - Python docstring contents are not reported as symbols
- A repo with exactly
maxFilesindexable files is not reported as truncated -
/statsshows 7d / 3m / all-time (←/→), cumulative chart, peak day, streak, top provider·model pairs -
/reviewandnanocoder reviewproduce a review of the branch diff / a PR -
/copy codein the terminal copies the last fenced block; says "No code blocks found in the last response." when there are none -
/tipshows a tip;/tip <text>narrows; consecutive runs do not repeat -
/exploreropens without crashing, and picking files inserts them as@mentions on exit -
/exportauto-names the file descriptively;~and paths outside the project root are refused with a specific reason - Exported markdown with tool output containing inner code fences renders correctly (dynamic fence length)
-
/helpdoes not crash -
/doctorreports the real version, not0.0.0 -
/statusGit line shows the(default)marker; the boot summary does not -
/helpwith leading whitespace runs rather than being sent to the model, and does not fireuser-prompt-submit -
/init --preset react|nextjs|rustseedsAGENTS.md, context ignores and a/checkcommand skill, preserving existing files -
{{args}}in a custom command with no declared parameters receives the raw arguments - A custom command argument containing
$',$`,$&or$$reaches the model literally - seeRELEASE-REVIEW.mdfinding 3 - An unreadable subdirectory under
.nanocoder/commands/logs a warning and the scan continues
-
--model=value,--provider=value,--vscode-port=value,--context-max=valueare honoured and stripped from the prompt afterrun -
--mouse/--no-mouseare stripped from arunprompt -
nanocoder run --prompt-file <path>reads the prompt from a file and takes precedence over a positional prompt - A missing/unreadable
--prompt-fileexits with a message rather than running an empty prompt - A ~300 KiB prompt via
--prompt-filespawns on Linux (the argv form fails withE2BIG) - A startup with a missing / malformed
package.jsonfalls back to versionunknowninstead of crashing
- macOS: a title or message containing newlines, quotes, backslashes or Unicode renders correctly
- Windows: same, with backticks and quotes
-
notifications.bellwrites BEL for enabled events; works over SSH and inside tmux (needsmonitor-bell) - BEL is skipped when stdout is not a TTY
-
/settings→ Notifications shows a row fortriggeredRunComplete, and toggling any switch does not drop it - Preferences are read from the top-level
notificationsandpastekeys (notnanocoder.notifications/nanocoder.paste)
- Syntax highlighting follows
selectedThemein markdown code blocks,string_replacediff context,write_filepreview, and the explorer preview -
"syntaxTheme": "dracula"innanocoder-preferences.jsonpoints code at that palette while the UI stays put - An unknown
syntaxThemefalls back toselectedThemerather than dropping styling - A markdown table with many columns fits the terminal and does not break its borders; one too wide is left as raw markdown
- On an 80-column terminal the status bar ellipsises cleanly rather than being cut mid-word ("auto-accept mode o")
- The live compact tool-activity summary shows at most 5 tool rows then
+N more - The streaming reasoning trace is fast in a long session; collapsed (the default) costs almost nothing
- A long conversation in fullscreen does not get progressively slower
- Cycling modes fast with Shift+Tab does not stack identical
[mode → model]toasts; returning to normal posts nothing - In inline mode a prompt does not appear twice in scrollback when streaming starts
- Escape to recall an in-flight prompt in inline mode leaves the bubble in scrollback
- Long user messages (>40 words / >300 chars) collapse for display; the original is recallable from input history
- Every interactive surface (session selector, IDE selector, explorer, plan review bar, question prompt, tool confirmation) has the same rounded titled box at the same width
- The transcript and mode indicator line up with the prompt's left border
-
professionalTonein/settings→ Behavior applies immediately: the completion note loses its adjective and the TONE section appears without a mode/model switch - Under the
nanotool profile the TONE section uses the short variant
- Ask the model to dispatch several subagents at once, each needing tool approval - prompts queue and present one at a time, every caller settles
- Answering a prompt twice quickly (double Enter, Enter then Escape) does not silently approve the next queued tool
- Escape during a batch of queued approvals frees the turn cleanly
- Cancelling a turn with approvals still queued settles them as denied and clears the prompts (fixed, finding 8)
- Queued prompts resume after a slash command and after manual
/compact - Two concurrent sessions writing usage data do not corrupt the file
-
/memoryrecall works in subagent and daemon runs; a repo memory file caps at 500 entries -
/settings→ Advanced → Semantic Memory toggle works and defaults on - Run two nanocoder processes against the same repo writing memories concurrently - no lost writes, no corrupt JSON (fixed, finding 6)
- A memory write that takes longer than 10s keeps its lock instead of being overwritten by the other process (fixed, finding 6)
-
nanocoder --acpworks from Zed - The companion WebSocket refuses an upgrade with no
Authorizationheader - It refuses an upgrade carrying any
Originheader (try connecting from a browser tab) - It binds an ephemeral port by default and writes
<configDir>/vscode-server.jsonwith mode 0600 - The extension reads the discovery file for port and token
-
--vscode-portstill works and still writes the discovery file -
nanocoder.serverTokenlets a remote/SSH user paste the token manually - A stale discovery file (dead PID) is ignored
- Two concurrent CLIs do not clobber each other's discovery file on shutdown
-
ask_userwith 5 or 6 options succeeds over ACP - A sub-agent tool call raises a
session/request_permissionand is not silently denied - Sub-agent cards are prefixed and titled with the sub-agent, no id collision with top-level
- Known limits still present: the approval slot is process-wide (two concurrent sessions cross wires), an approved sub-agent call is marked
completedon approval rather than on completion, and sub-agent approvals ignore the session mode andalwaysAllow - Overlapping ACP prompts do not corrupt turn state
- Built-in slash-command replies are kept in persisted history for replay; command-only sessions are not saved
- Each turn's thoughts, tool calls, edit cards and task plan group into one collapsible work summary; the final answer stays visible
- The summary reports completed / stopped / failed duration and reopens for pending approvals
- A turn cancelled before any thought or tool call shows no duration indicator (not
0s) - Composer: model on the input row, approval mode on the gear, provider + mode in a Configuration popover, all button-style dropdowns
- Mode selector sits on the composer row with accessible labels
- Add Provider: dynamic provider and SDK preset dropdowns, 23 templates matching the CLI, multiple custom model names, theme CSS tokens present
- Created/modified files appear as dashed chips above the composer as edits land; clicking opens the file
- Chips survive sending a message, dismiss individually and via "Clear N changed files", scroll at fixed height
- A deleted file loses its chip; a rename moves it
-
diff_editreports as an edit over ACP;file_opreports delete / move / edit rather than a generic tool call - Action timeline: click a prior mutating step and revert workspace + conversation to that point
- The timeline does not snapshot its own before-images, skips (rather than records) a checkpoint when the workspace scan is truncated, leaves binaries alone, reverts a whole assistant turn, validates paths read back from the index
- "Retry" on an assistant turn truncates history at the matching user turn and drops timeline checkpoints inside it; no duplicate user bubble
-
nanocoder.showTokenUsagedefaults off; turning it on restores token + cost footers - Reopening a saved chat restores token/cost footers (sessions without usage metadata load unchanged)
- Slash autocomplete:
/test,/explain,/docinsert an editable template;/clear,/copyrun as before; the menu only opens on a line-leading slash - Welcome screen shows on a fresh panel and hides on session load / first message
- Subagent activity card shows
1.9k tokens, not1k - Message footer hides while streaming
- Auto-scroll does not yank you to the bottom while reading back; it does force-scroll on run finish and session load
- Theme colors render (Tailwind v4
@themeblock) - Editor-tab drag and drop, MCP settings button opening
.mcp.json, and the denied-edit status icon all work -
pnpm run build:vscodeproducesassets/nanocoder-vscode.vsix
- Windows: models cache writes to the real home dir, not a literal
~folder - Windows: custom tools spawn
cmd.exe /d /s /c - Windows:
file.changedsubscriptions fire - Windows: notifications handle special characters
- Windows: the OS sandbox errors clearly rather than pretending to work
- Linux ARM: search works on a ripgrep build without PCRE2
- Containers: a workspace mounted at
/passes path-containment checks (file tools andsearch_file_contentsdo not reject every path) - macOS: deeply nested project socket path fallback (section 4)
- Fresh install in an empty directory: trust prompt appears before any
agents.config.json/.mcp.jsonis read or any stdio MCP server is spawned - Decline trust: nothing is read, nothing is spawned
-
--trust-directoryskips the gate; initialization still runs exactly once afterwards - A full end-to-end task on each of: Ollama, OpenRouter, Anthropic, a generic OpenAI-compatible endpoint
- The same task through
nanocoder run,--plain,--acp, and a daemon-triggered skill