Commit Graph
8450 Commits
Author SHA1 Message Date
can1357 9e0b6cddf2 chore: bump version to 16.3.2 2026-07-02 17:50:38 +02:00
can1357 e73a25489c feat(coding-agent/tools): migrated path input from array to semicolon-delimited string
- Changed the `path` property from an array of strings to a single semicolon-delimited string across tool definitions and tests.
- Updated validation error messages to reflect the new `path` input format.
- Adjusted all relevant test cases to provide path targets as semicolon-separated strings.
2026-07-02 17:48:46 +02:00
can1357 f8becede72 docs(coding-agent): rebuilt changelog after union-merge duplicated released sections
- Restored released sections byte-identical to pre-sweep main (immutable).
- Consolidated the 18 merged-fix entries under [Unreleased].
- Dropped a foreign entry imported from a non-landed branch (edit-tool
  oldText/newText snapshot bounding), which this merge set does not contain.
2026-07-02 10:50:43 +02:00
can1357 88f0aab994 style: formatted eval fix commits with biome 2026-07-02 10:34:53 +02:00
can1357 e569208786 test(coding-agent): cover snapcompact overflow fallback recovery (from PR #3707 by @cexll) 2026-07-02 10:31:58 +02:00
can1357 d49bcd4be7 chore: normalized changelog entries from merged fixes 2026-07-02 10:31:58 +02:00
can1357 3830ad353e merge PR #3843 (surviving delta): perf: streaming-reveal/render throughput + core hot-path optimizations (@oldschoola)
# Conflicts:
#	packages/coding-agent/src/config/model-resolver.ts
2026-07-02 10:31:45 +02:00
can1357 12bbf4a090 merge PR #1706 (+exit-guard port): fix(coding-agent): guard custom tool process exits during load (@roboomp) 2026-07-02 10:30:58 +02:00
can1357 a8547638b4 docs(changelog): cover awaited-IRC auto-reply and stale-directive cleanup 2026-07-02 10:30:51 +02:00
can1357 eeeab97db0 fix(session): auto-reply awaited IRC sends to an idle plan-mode session
Plan mode records idle IRC deliveries into context without waking a turn,
so an 'irc send await:true' sender was stranded until its wait timeout:
delivery reported injected but no reply could ever be generated. Extend the
existing ephemeral side-channel auto-reply (previously only for mid-turn
recipients with async execution disabled) to the idle plan-mode case — the
second situation where a real reply turn cannot happen in time. No primary
turn is woken; plan-mode convergence stays user-driven.

The deliverIrcMessage eligibility change itself rode in the previous commit
(same-file hunks); this commit carries the bus doc and the regression test:
an awaited idle IRC message in plan mode resolves the sender's bus waiter
via the side-channel reply while the primary loop stays asleep.
2026-07-02 10:30:51 +02:00
can1357 71209f025d fix(session): drop stale plan-mode-decision tool choice on skip/exit
The settle-time reminder queues a hard 'required' tool choice paired with a
scheduled continuation. If that continuation never runs (user prompt bumps
the generation, dispose, compaction/handoff) or plan mode is exited first,
the queued directive leaked onto the next unrelated turn as a forced tool
call. Remove it by label on continuation skip, on user-initiated prompts,
and when plan mode is disabled.
2026-07-02 10:30:51 +02:00
can1357 2875dd3349 merge PR #3911: fix(session): converge plan mode on ask/resolve across continuation paths (@metaphorics)
# Conflicts:
#	packages/coding-agent/src/session/agent-session.ts
2026-07-02 10:30:51 +02:00
can1357 727bcf1401 fix: drop superseded /btw todo-reminder HUD clear
Main removed the floating todoReminderContainer in 112317bc8 (todo
reminders are now anchored inside the scrollback transcript and reset
by renderInitialMessages({clearTerminalHistory: true})), so the added
this.todoReminderContainer.clear() references a property that no longer
exists post-merge, failing typecheck and throwing on every /btw branch.
Revert the interactive-mode hunk and its test, and reword the changelog
entry to cover only the goal-mode todo context fixes.
2026-07-02 10:30:12 +02:00
can1357 4940a053ad merge PR #3777: Fix todo HUD and goal context follow-ups (@jeffscottward) 2026-07-02 10:30:12 +02:00
can1357 23d16a4c5e merge PR #3922: fix(task): scan OMP extension agents/ dirs in discoverAgents (@roboomp) 2026-07-02 10:30:06 +02:00
can1357 a23d1d6554 merge PR #4140: fix(coding-agent): stopped isolated task merges failing when working tree carries WIP for files the agent also modifies (@roboomp) 2026-07-02 10:30:06 +02:00
can1357 ebf41281e7 fix(tui): stop spinner ticks for frozen pending previews
The github renderer materializes plain Text per display rebuild, so its
animatedPendingPreview opt-in requested 30fps repaints with a frozen
glyph for the whole run_watch wait; drop the flag. Custom tools with
only one of renderCall/renderResult never route to the animated generic
fallback, so gate the unregistered-renderer spinner on both being
absent. Regression tests for both no-tick contracts.
2026-07-02 10:30:06 +02:00
can1357 6429de3e83 merge PR #4172: fix(tui): animate live tool spinners (@roboomp) 2026-07-02 10:30:06 +02:00
can1357 278056025b merge PR #4200: fix(tui): stop /move overlay from statting every entry per keystroke (@roboomp) 2026-07-02 10:30:06 +02:00
can1357 4e12e5bf76 fix(extensibility): read lazy graph modules from disk at import time
The consume-once source map kept entries for graph modules the initial
import never loaded (modules only reached via lazy dynamic imports).
Their first import - possibly long after load, and after an on-disk
edit - was served the boot-time snapshot instead of current file
content, and the unconsumed sources stayed in the plugin closure for
the process lifetime.

Clear the map once the entry import settles: everything Bun loaded at
startup was already consumed (keeping the read-once win), and anything
left must be read at its actual import time, matching pre-dedup
behavior for lazy modules. The new regression test passes on the
pre-dedup baseline and fails on the unfixed dedup.
2026-07-02 10:29:57 +02:00
can1357 29ddf875c7 style(test): format graph-read-dedup test with repo formatter
biome check previously failed on this file (unsorted imports, space
indentation where the repo formatter emits tabs).
2026-07-02 10:29:57 +02:00
can1357 64e4bd89d1 merge PR #4205: perf(extensibility): read extension source graph once per load (@metaphorics) 2026-07-02 10:29:57 +02:00
can1357 2a7a7ec15c merge PR #4202: fix(coding-agent): scope discoverExtensionPaths to native extension-module provider (@roboomp) 2026-07-02 10:29:57 +02:00
can1357 c8fcf7a3c7 merge PR #4209: fix(coding-agent): cache plugin extension resolution (@roboomp) 2026-07-02 10:29:56 +02:00
can1357 88e352298a merge PR #4204: fix(model-discovery): auto-update ZenMux models into models.db without a key (@metaphorics) 2026-07-02 10:29:47 +02:00
can1357 a7ff81e0f6 merge PR #4217: fix(providers): hydrate runtime model cache before selection (@roboomp) 2026-07-02 10:29:47 +02:00
can1357 a5043b11ec merge PR #4221: fix(session): keep model switches active after rate limits (@roboomp) 2026-07-02 10:29:47 +02:00
can1357 c2a9f97c41 fix(title): don't treat caseless scripts as shouting
isAllCapsWord matched any multi-letter token without a lowercase letter,
so CJK tokens registered as ALL-CAPS words: two adjacent ones marked the
whole source shouty and silently disabled acronym restoration for every
non-Latin-script message (e.g. '修复 CNPG 集群故障' kept 'Cnpg'). Require an
actual uppercase letter; cased-script shout detection is unchanged.
2026-07-02 10:29:38 +02:00
can1357 289c7b357d fix(title): allowlist ETL so acronym restoration matches the documented contract
The PR's changelog, doc comment, and prompt examples all name ETL as a
restored acronym, but the review-response narrowing (vowel heuristic +
allowlist) silently dropped it: ETL bears a vowel and was not listed.
Add it to COMMON_TITLE_ACRONYMS and pin it in the allowlist test.
2026-07-02 10:29:37 +02:00
can1357 7be66da1ef merge PR #4222: fix(title): preserve ALL-CAPS acronyms in auto-generated session titles (@roboomp) 2026-07-02 10:29:37 +02:00
can1357 a6bd317af6 style: bun run fix 2026-07-02 10:26:33 +02:00
PR Evaluator ceeb60ccc1 docs(coding-agent): move #1704 changelog entry onto main's Unreleased head
The three-way merge against main silently dropped the entry because
main rewrote the old Unreleased region into released sections; the
branch changelog now mirrors main's head with the entry inserted under
the current Unreleased section so the merge keeps it.
2026-07-02 10:26:10 +02:00
PR Evaluator a76a33476a fix(coding-agent): guard custom tool loads with the shared exit guard
Replaces the bespoke batch-scoped process.exit interceptor with the
withExitGuard convention main established for extension/hook/plugin
loaders (500c39aa2): guard the module import and factory invocation so
a synchronous process.exit()/process.reallyExit() from a custom tool
becomes an ExtensionExitError handled as a recoverable load error,
while host exit paths stay untouched outside the guarded windows.
Tests cover the import-time exit (issue #1704 repro) and factory-time
exit; both would kill the test process without the guard.
2026-07-02 10:24:21 +02:00
can1357 fca39e8ede perf: reconcile with main — drop superseded streaming/patch/session work, port resolver context reuse
main independently absorbed batch-1 (incremental grapheme slice 718c7cea2, markdown
stream-prefix cache 705426548 + 3822a83b4) and the pathTo/patch.ts items; restore
main's refined versions wholesale. Port the model-resolver optimization onto main's
resolver shape: hoist per-candidate case folds in matchModel and build the
preference context once per role resolution (matchPatternWithContext) instead of
per fallback pattern. Rewrite changelog entries to the surviving items only.
2026-07-02 10:22:48 +02:00
PR Evaluator 6ad4db58a5 fix(coding-agent): backport shared extension exit guard from main
Byte-identical copy of the withExitGuard/ExtensionExitError block from
main (500c39aa2) so the custom-tool loader can reuse the established
guard convention; merges as an identical change against main.
2026-07-02 10:21:13 +02:00
roboomp bc5fbb4eb6 fix(title): avoid restoring emphasized words as acronyms
Narrow acronym restoration so plain all-caps English words such as FIX
and WORK do not get restored when the model naturally capitalizes the
first title word. Restorable all-caps source tokens now need a stronger
acronym signal: a common technical acronym allowlist, digits, or a
consonant-only shape.

This keeps CNPG, ETL, JWT, SQL, and API restoration while preserving the
anti-shout behavior for single emphatic words.

Fixes #4220
2026-07-02 07:02:26 +00:00
can1357 0ea6ea630b chore: bump version to 16.3.1 2026-07-02 09:00:04 +02:00
can1357 94645752ff feat(coding-agent/tts): introduced natural speech synthesis pipeline
- Added an enhanced speech pipeline that utilizes small models to rewrite text for natural language synthesis.
- Implemented `SpeechEnhancer` and `BlockAccumulator` to manage fence-aware text streaming and paragraph splitting.
- Configured a new `speech.enhanced` setting to toggle between mechanical and enhanced vocalization modes.
- Resolved `EPIPE` rejections during speech playback by ensuring stream flushes and suppressing stop-related errors.
2026-07-02 08:59:13 +02:00
roboomp 76ac419aaa style: bun run fix 2026-07-02 06:55:52 +00:00
roboomp 48d2b5c06b fix(title): preserve ALL-CAPS acronyms in auto-generated session titles
reconcileTitleCasing now maps ALL-CAPS source tokens (CNPG, API, ETL,
JWT) into an acronyms table and restores them when the model produces a
plain title-cased artifact (Cnpg). Restoration is disabled when the
source is shouty (>=2 consecutive multi-letter ALL-CAPS tokens like
"FIX the BUG NOW" or "ALL ERROR HANDLING"), and lowercase model output
is left alone so isolated single-word emphasis (WORK -> work) is never
re-shouted.

The three title system prompts (title-system.md, title-system-marker.md,
tiny-title-system.md) also gained an explicit instruction to preserve
ALL-CAPS acronyms verbatim, so a competent model short-circuits via the
verbatim set before post-processing kicks in.

Fixes #4220
2026-07-02 06:55:20 +00:00
roboomp a06d0c54b3 fix(session): switched models during goal recovery
Removed the live-context guard that let default model selection persist a new role without changing the active session model. The next prompt's compaction path now owns oversized-context recovery after a switch.

Fixes #4219
2026-07-02 06:48:30 +00:00
can1357 41cc57c238 feat(coding-agent/tts): redesigned streaming speech vocalization
- Added `SpeakableStream` to strip markdown noise, silence code blocks and tables, normalize links and paths, and emit sentence/clause segments.
- Reworked `Vocalizer` to segment assistant deltas in the parent process, lazily open TTS streams, idle-flush partial thoughts, and chain playback sessions.
- Added gapless streaming playback with ffmpeg/sox backends, ducking-aware pacing, fallback file playback, and immediate stop handling.
- Added IPC `sendAndFlush` support and used it in the TTS worker so audio chunks drain before blocking ONNX inference resumes.
- Added speakable-stream coverage for markdown filtering, segmentation latency, idle flushing, and forced long-segment splits.
2026-07-02 08:30:58 +02:00
can1357 95b91c7f73 feat(coding-agent/tools)!: replaced paths arrays with path strings
- Replaced `grep`, `glob`, and `ast_grep` `paths` inputs with optional single `path` strings while preserving default workspace-root behavior.
- Added shared `toPathList` normalization for legacy arrays and JSON-encoded arrays across tool execution and TUI renderers.
- Updated prompts, fixtures, shims, transcript summaries, and tests to send and display the new `path` argument.
- Updated collab-web search tool cards to read `path` while falling back to legacy `paths` for historical transcripts.
- Recorded the contiguous coding-agent changelog run for the tool-path breaking change and adjacent TTS entries.
2026-07-02 08:30:33 +02:00
roboomp e58d86448a fix(changelog): moved provider fix to unreleased
Moved the #4216 runtime provider cache fix entry out of the released 16.3.0 section and into Unreleased.\n\nFixes #4216
2026-07-02 06:24:49 +00:00
roboomp 114b4bedfa fix(providers): hydrated runtime model cache before selection
Loaded cached runtime extension provider catalogs before deferred model resolution so dynamic-only providers can satisfy cold-start --model and session resume selection from models.db.\n\nFixes #4216
2026-07-02 06:16:39 +00:00
roboomp 15c4835e99 fix(coding-agent): cached plugin extension resolution
- Added shared plugin cache invalidators wired through clearClaudePluginRootsCache.\n- Memoized enabled plugin discovery and legacy bare dependency fallback resolution.\n- Added regression coverage for cache reuse and invalidation.\n\nFixes #4197
2026-07-02 04:54:10 +00:00
metaphorics 39668f36f7 fix(model-discovery): auto-update ZenMux models into models.db without a key
ZenMux discovery only defined a dynamic fetcher when a ZENMUX_API_KEY was
present, and the descriptor lacked the top-level allowUnauthenticated flag
that gates keyless runtime manager creation. Newly published ZenMux models
therefore never reached the runtime models.db cache without a key — they
were stranded until the bundled models.json was regenerated.

Make fetchDynamicModels unconditional (the public /api/v1/models endpoint
needs no auth) and add top-level allowUnauthenticated so the runtime builds
a keyless manager and writes discoveries to models.db, matching the
ollama/lm-studio pattern. ZenMux stays out of #keylessProviders: it is a
paid gateway, so discovered models are cached and findable but not
selectable without credentials (they would 401 at inference).

Also fixes a latent runtime bug: getProviderBaseUrl returns the first
bundled model's baseUrl, which for ZenMux is the anthropic-routed
/api/anthropic. Discovery then fetched /api/anthropic/models (nonexistent)
instead of /api/v1/models, breaking discovery even for keyed users.
normalizeZenMuxOpenAiBaseUrl now remaps a trailing /api/anthropic back to
/api/v1 before the /models fetch.

Op: correct
Restores: spec:ZenMux runtime discovery reflects newly published models in models.db without a ZENMUX_API_KEY
2026-07-02 13:50:06 +09:00
roboomp cf9533ac95 fix(tui): stat-fallback /move overlay Dirents with unknown type
Some filesystems (NFS, FUSE, older SMB) return UV_DIRENT_UNKNOWN, making every Dirent.isX() return false. The prior early-return dropped real directories on those mounts. Now only reject when a known non-directory type (file/device/fifo/socket) is reported; symlink and unknown-type entries fall back to fs.statSync.
2026-07-02 04:46:36 +00:00
roboomp 65377c1ca8 style: bun run fix 2026-07-02 04:43:45 +00:00
roboomp 0eb820e7ce fix(coding-agent): scope discoverExtensionPaths to native extension-module provider
`discoverExtensionPaths` loaded the extension-module capability across all
registered providers (native, claude, codex, gemini, opencode) and then
discarded every item whose `_source.provider !== "native"`. Four foreign
directory walks ran on every session startup only for their results to be
dropped — worst on Windows.

Scope the load to the native provider via the existing `LoadOptions.providers`
filter: `loadCapability(extensionModuleCapability.id, { ...loadOptions,
providers: ["native"] })`. The hook-capability load in the same function is
unchanged (hooks legitimately span providers). Output is identical.

Regression test in `extensions-discovery.test.ts` spies on each extension-module
provider's `load()` and asserts only "native" is invoked.

Fixes #4198
2026-07-02 04:43:20 +00:00