Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d7d8608
fix: resume queued prompts after slash commands
mikemikimike Aug 30, 2026
762139c
fix: safely resume queued prompts after commands
mikemikimike Aug 30, 2026
f994c03
Merge upstream main to resolve PR conflicts
mikemikimike Aug 30, 2026
7af12f2
Update status badges [skip ci]
actions-user Aug 31, 2026
ddf7453
feat: migrate file search to a ripgrep-backed implementation (#928)
kishore280 Aug 31, 2026
e054837
feat(export): auto-generate descriptive filenames from first user mes…
tusharui Aug 31, 2026
4a78dd4
feat(ui): add session auto-save indicator (fixes #932) (#958)
rishu685 Aug 31, 2026
cc706f7
Feature: theme aware syntax highlighting (#959)
addyCooks Aug 31, 2026
7bbbfa4
fix(search): reject any failed ripgrep run, not just recognized ones …
will-lamerton Aug 31, 2026
e1af6d9
fix(export): name the reason a path was rejected, split writeUniqueFi…
will-lamerton Aug 31, 2026
2d35769
fix(search): prune .nanocoderignore during the walk, type the unsorte…
will-lamerton Aug 31, 2026
6387c01
fix: spawn cmd.exe with /c for custom tools on Windows (#1031)
Dhirenderchoudhary Aug 31, 2026
109df6a
feat(init): add bundled preset configurations (#1026)
raheebgill29 Aug 31, 2026
c673eff
chore: label PRs by changed path (#1068)
Dhirenderchoudhary Aug 31, 2026
77b43df
fix(init): drop the verify alias from preset check commands
will-lamerton Aug 31, 2026
01cabab
fix(vscode): migrate to Tailwind v4 @theme and add CSS verification s…
akramcodez Aug 31, 2026
9685adc
ci: fail PRs that drop coverage vs the base branch (#1101)
Dhirenderchoudhary Aug 31, 2026
645d3d5
fix(file-ops): keep replacement text literal in string_replace and di…
addyCooks Aug 31, 2026
497f1b0
fix: merge main and tighten memory retrieval (#1078)
Dhirenderchoudhary Aug 31, 2026
0f2d93b
fix(acp): route sub-agent tool approvals to the client (#1080)
rascal-sl Aug 31, 2026
3f474dd
fix(acp): stop claiming the sub-agent approval handler is session-safe
will-lamerton Aug 31, 2026
7899745
fix(subagents): preserve object tool output (#1074)
mikemikimike Aug 31, 2026
a1e8953
add fix(lsp): resolve verification promise on early process exit to p…
AniketR10 Aug 31, 2026
4143e0e
Update status badges [skip ci]
actions-user Sep 1, 2026
85f6c95
fix: guard queued prompt draining after commands
mikemikimike Sep 1, 2026
5642f22
Merge upstream main into fix/issue-1060-compact-queue
mikemikimike Sep 1, 2026
6c5d556
fix(ci): read PR label config from head revision
mikemikimike Sep 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/acp-subagent-tool-permission.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nanocollective/nanocoder": patch
---

Fixed sub-agent tool calls being denied silently under ACP. A tool call made inside a dispatched sub-agent went through the global approval slot, which no ACP code path installed a handler for, so its safe fallback denied every one without the client seeing a `session/request_permission`. Delegated work could only write by bypassing approval entirely, which was invisible to a client that gates writes. Sub-agent calls now use the same permission channel as top-level ones, announced first so the request names a known tool call, prefixed so their cards cannot collide with a top-level id, and titled with the sub-agent so the client can tell them apart. The handler is scoped to the turn that installs it, so it no longer outlives that turn holding a finished session. Two known limits remain. The approval slot is still a process-wide singleton, so while two sessions have turns in flight at once the later one's handler answers the earlier one's approvals, against the wrong session id and abort controller; closing that needs the slot keyed by session or an approval channel threaded through the sub-agent executor. And an approved sub-agent call is marked `completed` as soon as it is approved rather than when it runs, because the sub-agent layer does not report results back, so a client sees `completed` for a tool that may still fail. Note also that sub-agent approvals ignore the ACP session's mode and the configured `alwaysAllow` list, so a `yolo` or `auto-accept` session is prompted inside a sub-agent for a tool it would not be prompted for at top level. Closes #1019.
5 changes: 5 additions & 0 deletions .changeset/calm-queues-compact.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nanocollective/nanocoder": patch
---

Resume queued prompts after slash commands and manual context compaction complete. Closes #1060.
4 changes: 4 additions & 0 deletions .changeset/coverage-drop-vs-base.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
---

CI: pass fail-on-coverage-drop to the shared PR checks workflow.
5 changes: 5 additions & 0 deletions .changeset/curvy-tools-smile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nanocollective/nanocoder": patch
---

Fixed subagent tool results that return structured data without `llmContent` so the complete output is preserved for the model instead of being passed as `undefined`. Closes #1033.
5 changes: 5 additions & 0 deletions .changeset/custom-tool-windows-cmd.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@nanocollective/nanocoder': patch
---

Custom tools on Windows now spawn `cmd.exe /d /s /c` instead of `-c`, which cmd does not accept. `/d` skips AutoRun; `/s` makes quote stripping deterministic. `{{ }}` substitution stays POSIX-quoted and is not shell-safe under cmd. Closes #1028.
7 changes: 7 additions & 0 deletions .changeset/fiery-hats-pick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@nanocollective/nanocoder": minor
---

Auto-generate descriptive filenames for /export instead of generic timestamps. Closes #934

Exports are now contained to the project directory, matching read_file / write_file / string_replace: `~` is not expanded and absolute paths outside the project root are refused rather than written. Rejections name the specific cause (null byte, `~`, `..` segment, outside the root) instead of failing generically.
5 changes: 5 additions & 0 deletions .changeset/fix-literal-replacement-dollar-tokens.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nanocollective/nanocoder": patch
---

Fixed `string_replace` and `diff_edit` corrupting edits whose replacement text contains `$`. Both tools passed the model's replacement straight to `String.prototype.replace`, which treats that argument as a substitution template rather than a literal: `$$` collapsed to a single `$`, `$&` expanded to the matched text, and ``$` ``/`$'` spliced a whole half of the file into the middle of the edit. Those are ordinary characters in shell scripts, Makefiles, CI YAML and anything that builds a regex, so the bytes on disk silently diverged from the diff the user approved. Replacements are now spliced by index, so the approved preview - in the terminal and over ACP - is what lands. Closes #1057.
5 changes: 5 additions & 0 deletions .changeset/fix-tailwind-v4-vscode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nanocollective/nanocoder": patch
---

Fixed a regression where the VS Code extension webview rendered without theme colors after the Tailwind v4 upgrade by migrating custom color variables to an `@theme` block in the CSS.
5 changes: 5 additions & 0 deletions .changeset/fresh-pandas-initialize.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nanocollective/nanocoder": minor
---

Added bundled React, Next.js, and Rust project presets for `nanocoder init --preset <type>` and `/init --preset <type>`. Presets seed analyzed `AGENTS.md` guidance, stack-specific context ignores, and a `/check` command skill while preserving existing files. Closes #1008.
2 changes: 2 additions & 0 deletions .changeset/pr-path-labels.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
11 changes: 11 additions & 0 deletions .changeset/ripgrep-file-search.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@nanocollective/nanocoder": minor
---

File search (path matching and content search) is now backed by `ripgrep` instead of a hand-rolled JS walker.

Search also respects `.nanocoderignore` and binary files again, matching `list_directory` and file autocomplete.

A failed search now reports the failure instead of returning an empty result set.

`.nanocoderignore` directories are skipped during the walk rather than filtered afterwards, so a large ignored directory can no longer crowd real files out of the results.
5 changes: 5 additions & 0 deletions .changeset/semantic-memory-remaining.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nanocollective/nanocoder": patch
---

Wire semantic memory recall into subagent and daemon runs, serialize writes across manager instances and processes, and cap each repo memory file at 500 entries.
5 changes: 5 additions & 0 deletions .changeset/semantic-memory-retrieval.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nanocollective/nanocoder": patch
---

Rank recalled memories by how much of the query they cover, skip tool-call narration in reversal detection, and drop noisy `/memory propose` candidates.
5 changes: 5 additions & 0 deletions .changeset/semantic-memory-setting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nanocollective/nanocoder": minor
---

Added a dedicated Semantic Memory toggle to `/settings` under Advanced, backed by the `semanticMemoryEnabled` preference. The setting defaults on to preserve existing behavior, and can be turned off to keep agents from persisting reusable context across sessions.
5 changes: 5 additions & 0 deletions .changeset/session-autosave-indicator.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nanocollective/nanocoder": patch
---

Added a visual `saving` indicator in the CLI status line that briefly displays whenever session state is autosaved to disk. Thanks to @rishu685. Closes #932.
5 changes: 5 additions & 0 deletions .changeset/theme-aware-syntax-highlighting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nanocollective/nanocoder": minor
---

Syntax highlighting now follows your theme, and takes a `syntaxTheme` preference when you want code to keep a palette of its own. All five highlighting call sites - markdown code blocks, `string_replace` diff context, the `write_file` preview, and the file explorer preview - passed `theme: 'default'`, a string where `cli-highlight` expects a token-to-formatter map, so the option was silently dropped and every theme rendered code identically in the library's own colours. Each one now derives its token map from a theme's palette: keywords take `primary`, built-ins and declarations `tool`, strings `success`, numbers `warning`, comments `secondary`, attributes and variables `info`, and everything else the theme's body `text`. Code follows `selectedTheme` by default; setting `syntaxTheme` in `nanocoder-preferences.json` (e.g. `"syntaxTheme": "dracula"`) points code at any other theme's palette while the rest of the UI stays put, and an unknown name falls back to `selectedTheme` rather than dropping the styling. Closes #935.
28 changes: 28 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
area:tools:
- changed-files:
- any-glob-to-any-file:
- source/tools/**
- source/custom-tools/**

area:tui:
- changed-files:
- any-glob-to-any-file:
- source/hooks/**
- source/components/**
- source/app/**

area:ci:
- changed-files:
- any-glob-to-any-file:
- .github/**

area:docs:
- changed-files:
- any-glob-to-any-file:
- docs/**

area:vscode:
- changed-files:
- any-glob-to-any-file:
- plugins/vscode/**
- source/vscode/**
35 changes: 13 additions & 22 deletions .github/workflows/pr-checks.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
name: Pull Request Automated Checks

# The shared org workflow covers the checks every repo runs. Everything
# genuinely nanocoder-specific — the VS Code extension — stays in this file
# rather than becoming an input on the shared workflow.
# Nanocoder-specific checks (VS Code extension) that sit outside the shared org workflow.

on:
pull_request:
Expand All @@ -17,26 +15,18 @@ permissions:
jobs:
pr-checks:
uses: Nano-Collective/.github/.github/workflows/pr-checks.yml@main
with:
fail-on-coverage-drop: true

# `changeset-check.yml` only asserts that a changeset file was added, never
# that the package name inside it resolves. A wrong name is accepted on the
# PR and then breaks `release-prepare` on every subsequent push to main,
# which is what #1065 did.
#
# This runs scripts/validate-changesets.js rather than `changeset status`:
# status also exits 1 when packages changed but no changeset was added, which
# would turn changeset-check.yml's deliberately non-blocking nudge into a hard
# requirement, and it needs a local `main` ref that this detached checkout
# does not have.
# Validates changeset package names to prevent main branch breakages.
# Uses a custom script instead of `changeset status` to keep the check non-blocking.
changeset-validation:
name: Changeset Validation
runs-on: ubuntu-latest
# The automated "Version Packages" PR consumes changesets rather than
# adding them, matching the skip in changeset-check.yml.
# Skip for the automated "Version Packages" PR.
if: github.head_ref != 'changeset-release/main'
steps:
# The validator is dependency-free and reads only the working tree, so
# this job needs no pnpm install and no history beyond the head commit.
# Dependency-free check, no pnpm install needed.
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
Expand All @@ -50,9 +40,7 @@ jobs:
- name: Validate every changeset resolves to a workspace package
run: node scripts/validate-changesets.js

# nanocoder ships a VS Code extension alongside the CLI. It has its own
# tsconfig, so the root `test:types` does not cover it, and it produces the
# .vsix that the release consumes.
# Tests and builds the VS Code extension.
vscode-extension:
name: VS Code Extension
runs-on: ubuntu-latest
Expand All @@ -75,16 +63,19 @@ jobs:
- name: Install dependencies
run: pnpm install --frozen-lockfile

# The root tsconfig only includes source/**, so the extension's own
# sources and specs are checked by their own project or not at all.
# Type check extension separately from the root tsconfig.
- name: Type check the extension
run: pnpm test:types:vscode

- name: Build the extension
run: pnpm run build:vscode

# Verify .vsix existence. The next step will verify its CSS theme tokens.
- name: Verify the .vsix was produced
run: |
set -euo pipefail
test -f assets/nanocoder-vscode.vsix
echo "VS Code extension packaged"

- name: Verify the theme tokens compiled into the CSS
run: node plugins/vscode/scripts/verify-theme-css.js
70 changes: 70 additions & 0 deletions .github/workflows/pr-labeler.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: PR path labels

on:
pull_request_target:
types: [opened, synchronize, reopened]
branches: [main]

permissions:
contents: read
issues: write
pull-requests: write

jobs:
label:
runs-on: ubuntu-latest
# Skip the automated "Version Packages" PR.
if: github.head_ref != 'changeset-release/main'
steps:
- name: Color area labels
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const colors = {
'area:tools': ['1d76db', 'Tool implementations and tool-calling'],
'area:tui': ['fbca04', 'Terminal UI'],
'area:ci': ['e99695', 'GitHub Actions and CI'],
'area:docs': ['0e8a16', 'Documentation'],
'area:vscode': ['5319e7', 'VS Code extension and host integration'],
};
const {owner, repo} = context.repo;
const {data} = await github.rest.repos.getContent({
owner,
repo,
path: '.github/labeler.yml',
ref: context.payload.pull_request.head.sha,
});
if (data.type !== 'file' || typeof data.content !== 'string') {
throw new Error('labeler.yml is not a file');
}
const yaml = Buffer.from(data.content, 'base64').toString('utf8');
const names = [...yaml.matchAll(/^(\S+):\s*$/gm)].map(m => m[1]);
if (names.length === 0) {
throw new Error('labeler.yml had no top-level label keys');
}
for (const name of names) {
const meta = colors[name];
if (!meta) {
throw new Error(
`labeler.yml has ${name} but no colour map entry`,
);
}
try {
await github.rest.issues.getLabel({owner, repo, name});
} catch (error) {
if (error.status !== 404) throw error;
const [color, description] = meta;
await github.rest.issues.createLabel({
owner,
repo,
name,
color,
description,
});
}
}

- name: Label by path
uses: actions/labeler@bf12e9b00b37c5c0ca2b87b79b2daf7891dbda13 # v7.0.0
with:
sync-labels: false
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,4 @@ benchmarks/.module-*

# Auto-generated CSS
plugins/vscode/media/chat-panel.css
assets/*.vsix
Binary file removed assets/nanocoder-vscode.vsix
Binary file not shown.
2 changes: 1 addition & 1 deletion badges/coverage.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion badges/forks.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading