Commit Graph

5318 Commits

Author SHA1 Message Date
can1357 48241afcc4 test(coding-agent): dropped stale URL read-cache assertions
- 33d66643d removed the process-local URL response cache (#5803) but left
  two fetch-kagi-toggle tests asserting the old reuse contract.
- Deleted the obsolete repeated-read reuse test (refetch behavior is
  covered by fetch-raw-mode and search-url-paths regressions) and kept
  the offset/limit selector contract without the no-network assertion.
2026-07-17 22:16:21 +02:00
can1357 8c546bda77 Merge PR #5816: fix(tools): recognize zip-family archives and prune unconvertible extensions (@roboomp) 2026-07-17 21:22:07 +02:00
can1357 089eec18e6 Merge PR #5811: fix(read): refresh URL responses on each invocation (@roboomp) 2026-07-17 21:22:07 +02:00
can1357 3df9cb12c1 Merge PR #5883: fix(agent): preserve signed thinking-only stops (@roboomp) 2026-07-17 21:22:06 +02:00
can1357 1311e6440b Merge PR #5809: fix(session): make /new an atomic boundary against queued steers (@roboomp) 2026-07-17 21:22:06 +02:00
can1357 357d683007 Merge PR #5894: fix(mcp): process-group kill and SIGKILL escalate on stdio transport close (@Mathews-Tom) 2026-07-17 21:22:06 +02:00
can1357 0422357bff Merge PR #5880: fix(extensions): restore legacy Kimi provider compatibility (@roboomp) 2026-07-17 21:22:05 +02:00
can1357 3de62abccb Merge PR #5878: fix(tui): keep active todo visible in collapsed views (@roboomp) 2026-07-17 21:22:05 +02:00
can1357 940855608e Merge PR #5865: fix(hub): restore persisted peers after resume (@roboomp) 2026-07-17 21:22:05 +02:00
can1357 3e006c8a70 Merge PR #5855: fix(mcp): stop reauth after failed dynamic client registration (@roboomp) 2026-07-17 21:22:05 +02:00
can1357 255707426b Merge PR #5846: fix(cli): preserve carriage-return progress boundaries (@roboomp) 2026-07-17 21:22:04 +02:00
can1357 0b1e794545 Merge PR #5844: fix(tui): drop stale hidden-lines footer on expanded bash/eval output (@roboomp) 2026-07-17 21:22:04 +02:00
can1357 80544edabb Merge PR #5826: fix(lsp): support pull diagnostics (@roboomp) 2026-07-17 21:22:03 +02:00
can1357 754195f5e7 Merge PR #5814: fix(read): support history URL selectors (@roboomp) 2026-07-17 21:22:03 +02:00
can1357 261ce6c370 fix(prompting): preserved direct tools sharing xd names
Kept top-level custom tool descriptors when a retained xd device uses the same name. Added compact and inline inventory coverage for mounted-only and dual-presentation tools.
2026-07-17 20:44:34 +02:00
Mathews-Tom 42e17c52d5 test(mcp): skip SIGTERM-trap escalation timing test on Windows
Subprocess.kill("SIGTERM") terminates a Windows child immediately
regardless of any handler, so the child in
"is idempotent even when close() had to escalate to SIGKILL" can never
trap SIGTERM to exercise the escalation path — the >=900ms grace-window
assertion would fail spuriously on win32 even though close() behaves
correctly there. Guards it the same way stdio.test.ts's
terminateStdioProcess describe block already skips its POSIX-only
real-signal tests.
2026-07-18 00:13:58 +05:30
can1357 e1e2a868b1 merge pull request #5799 2026-07-17 20:40:39 +02:00
can1357 248421fdf9 fix(coding-agent): fixed xd:// mount notices triggering unsolicited model turns
- Fixed xd:// mount notices forcing their own model turn by deferring them until the next user prompt instead.
- Added `#pendingXdevMountDelta` field and `#takePendingXdevMountNotice()` to coalesce mount/unmount events and ride along with prompts.
- Mount and unmount events that cancel each other out before the next prompt are now dropped from the coalesced delta.
- Notices remain buffered during quiet startup mode (`startup.quiet`) and are delivered on the subsequent user prompt.
2026-07-17 20:36:11 +02:00
roboomp f662d79ffd fix(tui): keep hidden-pending summary when actives fill the todo cap
selectCollapsedTodos took the active-overflow branch at active.length >= cap, so exactly cap actives plus trailing pending returned the cap rows with an empty summary — the pending work vanished with no '… N more' indicator.

Use a strict '> cap' guard so equality falls through to the normal branch, which counts every hidden row.

Fixes #5873
2026-07-17 18:06:47 +00:00
roboomp 939d6761f7 fix(tui): shared walking-viewport policy for collapsed todos
The first pass anchored a slice on the active task, which still showed completed rows, kept the active item mid-window, and gave the two views divergent selection logic. Per reviewer, replace it with one shared policy both collapsed views run.

selectCollapsedTodos (todo.ts) omits completed/abandoned, pulls every active task (in_progress or subagent-matched pending) to the head in todo order, fills remaining rows with following pending tasks, and emits '… N more active todos' when active work alone exceeds the cap; it falls back to closed tasks for a settled phase so HUD persistence still renders. renderTreeList gains a trailingSummary primitive so item selection lives in the todo domain. The transient tool result reaches live subagent matches via setActiveTodoDescriptionsProvider, wired from interactive mode's observer registry, so both views share the active set.

Fixes #5873
2026-07-17 18:03:13 +00:00
Mathews-Tom c30c3ab0fb fix(mcp): process-group kill and SIGKILL escalate on stdio transport close
Before: StdioTransport.close() did a bare `this.#process.kill()` — a single
direct SIGTERM to the immediate child, with no wait and no escalation. On
Linux (and other non-Windows/non-macOS POSIX hosts), the MCP server is
spawned detached (setsid, its own session leader) so terminal job-control
signals can't stop it. A detached server that traps/ignores SIGTERM — or a
grandchild it spawns inside that session — survived omp process exit and
was orphaned, re-parented to PID 1.

After: close() runs a bounded, idempotent teardown:
  1. End stdin first (cooperative EOF) so a well-behaved server can exit on
     its own before any signal is sent.
  2. Send SIGTERM: to the whole process group (negative-pid `process.kill`)
     when this transport actually spawned detached on a POSIX host, else to
     the direct child only. A negative-pid signal is never attempted for a
     non-detached transport, since it could hit an unrelated group. ESRCH
     from the group signal means the group is already gone (treated as
     success); any other group-signal failure falls back to a direct-child
     signal.
  3. Wait up to ~1s for the direct child to exit; if it hasn't, escalate to
     SIGKILL (group-or-direct, same rule as step 2) and wait a further
     bounded ~0.5s before returning. Total worst case (~1.5s) stays well
     inside the ~3s MCP disconnect-all budget in agent-session.ts dispose().

`#process` is captured into a local and nulled before the first `await`, so
repeat/concurrent close() calls see it already cleared and skip re-signaling
— idempotent per the existing contract documented above close().

Extracted the signal/escalate logic into an exported `terminateStdioProcess`
(plus a `KillableSubprocess` structural type, decoupled from the stdio pipe
generics) so tests can drive group-signal escalation with an explicit
`detached` flag — `StdioTransport.connect()` ties `detached` to the host's
real `process.platform` via `resolveStdioSpawnCommand()`, so a POSIX
detached session can't be reproduced end-to-end through `connect()` on a
non-Linux dev/CI host, but a real detached process group can still be
spawned directly on any POSIX host to exercise it.

Tests added to stdio.test.ts: detached child trapping SIGTERM escalates to
SIGKILL; a detached parent's SIGTERM-trapping grandchild is only reached by
the group SIGKILL (proves group, not direct-child-only, signaling); a
well-behaved child closes promptly without escalating; a non-detached
transport never attempts a group signal. Extended
test/mcp-stdio-transport.test.ts's existing close() idempotency coverage
with a case where the first close() had to run the full escalation path.

Fixes #5578.
2026-07-17 23:22:06 +05:30
roboomp bacc24e12e fix(agent): preserved signed thinking-only stops
- Treated non-empty thinking signatures as terminal provider content.
- Added regression coverage for empty visible thinking with a valid signature.

Fixes #5881
2026-07-17 17:08:15 +00:00
roboomp aaac0ace1d fix(extensions): created legacy auth database directory
Create the resolved agent database parent before the synchronous compatibility store opens SQLite, and cover a fresh nested agent directory.

Fixes #5879
2026-07-17 17:06:15 +00:00
roboomp 7e8c4fc01f fix(extensions): restored legacy provider compatibility
Restored the historical assistant-message stream factory and synchronous auth-storage facade needed by pi-provider-kimi-code.

Fixes #5879
2026-07-17 16:54:47 +00:00
roboomp e6fd29ec21 fix(tui): keep active todo visible in collapsed views
Both collapsed todo renderers took fixed edge slices: the tool result kept the tail eight (truncateFrom start) and the HUD kept the head five (base.slice), so a mid-phase in_progress task fell in the omitted middle of both.

Add an anchorIndex option to renderTreeList that slides the collapsed window over the anchored item with two-sided '… N more' summaries, and anchor both call sites on the in_progress task (HUD falls back to the first subagent-matched pending task).

Fixes #5873
2026-07-17 16:33:28 +00:00
vmcall d53cf023b0 fix(task): reconciled structured subagents with upstream
- Preserved the plan-mode capability clamp after upstream removed report_finding.
- Updated persisted-revival coverage for mounted xdev tool activation.
- Applied current formatter output to conflicted runtime files.
2026-07-17 17:38:12 +02:00
vmcall 2aaa639b69 fix(task): marked dynamic task schema non-strict
Caller-provided output schemas are free-form JSON and cannot be represented by OpenAI strict tool schemas. Keep todo strict while explicitly sending task as non-strict.
2026-07-17 17:38:12 +02:00
vmcall 414ef80c41 fix(task): restored goal activation outside restricted sessions
- Preserved goal-mode tool injection for ordinary explicit tool lists.
- Kept plan-mode LSP and IRC unavailable under the host capability clamp.
- Added regressions for both capability boundaries.
2026-07-17 17:36:59 +02:00
vmcall d944879f21 feat(task): unified structured subagent execution
- Added per-invocation task schemas with strict and permissive validation.
- Shared task and eval agent policy, artifacts, isolation, and lifecycle handling.
- Enabled host-restricted plan-mode eval agents and persisted their capability clamp.

Fixes #5279
2026-07-17 17:36:59 +02:00
roboomp 66837a96be fix(hub): restored persisted peers after resume
Moved persisted roster discovery out of the Agent Hub UI so model-facing coordination can use the same disk-backed registration path.

Rehydrated parked peers before an empty hub list response and added a crash-resume regression test.

Fixes #5864
2026-07-17 15:20:43 +00:00
roboomp 189ac462cc fix(mcp): narrowed failed DCR block to unapproved clients
Only a 403 response that identifies unapproved_client now blocks generateAuthUrl before its clientless probe. Invalid metadata, invalid redirect, generic forbidden, retryable, and server failures preserve the probe path.

Consolidated fallback coverage across 400, 403, 429, and 503 responses.

Fixes #5852
2026-07-17 14:56:56 +00:00
roboomp 490686602c fix(mcp): excluded retryable 4xx DCR statuses from reauth block
Added #isDefinitiveRegistrationRejection so only non-retryable 4xx DCR errors block generateAuthUrl; 408/425/429 fall through to the clientless authorization probe alongside transport and 5xx failures.

Fixes #5852
2026-07-17 14:49:51 +00:00
roboomp 7faa6eb2dd fix(mcp): scoped reauth block to definitive DCR rejections
Only a 4xx DCR client error blocks generateAuthUrl; transport (status 0) and 5xx failures fall through to the clientless authorization probe so providers accepting client-less authorization keep working.

Fixes #5852
2026-07-17 14:45:56 +00:00
roboomp 33f2f00d58 fix(mcp): blocked reauth after failed client registration
Surfaced rejected dynamic client registration from generateAuthUrl before probing or returning an authorization URL without client_id.

Added coverage for a Cropwise-style 403 unapproved_client response.

Fixes #5852
2026-07-17 14:39:15 +00:00
roboomp e5f65fcd5f fix(cli): preserved carriage-return progress boundaries
Normalized lone carriage returns before terminal output is buffered while retaining CRLF as a single line boundary across chunk splits.

Fixes #5845
2026-07-17 13:58:45 +00:00
roboomp ea78e346d0 fix(tui): dropped stale hidden-lines footer on expanded output
Expanded `!` bash and `eval` execution output kept rendering the
`… N more lines (ctrl+o to expand)` footer after Ctrl+O revealed every
line, because `hiddenLineCount` was computed from the collapsed preview
window regardless of the `#expanded` (or sixel-passthrough) state.

Zero the hidden count whenever the full output is shown so
`buildStatusFooter()` stops advertising hidden lines and ctrl+o.

Fixes #5842
2026-07-17 13:11:52 +00:00
roboomp db91dbe3ea fix(lsp): returned pull diagnostics promptly
Raced document diagnostic pulls against the push polling interval so completed full reports return without waiting for the deadline.

Covered inline edit writethrough delivery for an immediate pull-only response.

Fixes #5825
2026-07-17 10:17:00 +00:00
roboomp 58b1d4440f fix(lsp): supported pull diagnostics
Advertised document diagnostic support and tracked static and dynamic server capabilities.

Pulled full reports within the existing diagnostics wait window while preserving push precedence.

Fixes #5825
2026-07-17 10:10:11 +00:00
roboomp 22a8524058 fix(tools): recognized zip-family archives and pruned unconvertible extensions
- Treated ZIP-based .jar/.war/.ear/.apk as zip archives in archiveFormatFromPath and parseArchivePathCandidates so read/write member access works.
- Shared one archive-extension alternation between format detection and path splitting to stop them drifting.
- Derived the markit convertible-extension set from a single source of truth (utils/markit) matching the registered converters (pdf/docx/pptx/xlsx/epub), dropping legacy .doc/.ppt/.xls/.rtf that had no converter and only produced Unsupported format errors.
- Updated read/write tool prompts to document the zip-family extensions.

Fixes #5808
2026-07-17 08:04:10 +00:00
roboomp 67727c8de5 fix(session): resumed queued messages after compaction reconnects
The #5800 drain guard suppressed the abort-finally stranded-message
drain while the session was disconnected from the agent event stream.
newSession/switchSession drop the agent queues on transition, so nothing
is lost there. compact() preserves the queues and only reconnected in
its finally — it never re-drained — so a steer/follow-up arriving during
compaction (async IRC, an xd:// mount notice, an SDK steer) stayed
stranded until the next explicit prompt.

Re-drain in compact()'s finally after #reconnectToAgent (and after the
compaction AbortController is cleared, so isCompacting is false and the
scheduled agent.continue() actually runs). Added a regression test that
queues a follow-up mid-compaction and asserts it resumes.

Fixes #5800
2026-07-17 08:03:03 +00:00
roboomp dc7238f5a4 fix(read): supported history URL selectors
Added history to selector-aware internal URL schemes so read paging resolves the agent id before applying transcript ranges.

Fixes #5806
2026-07-17 07:46:37 +00:00
roboomp 33d66643d3 fix(read): refreshed URL responses on each invocation
Removed process-local URL response reuse so read and URL-backed search paths fetch current content.

Added regressions for repeated reads and searches.

Fixes #5803
2026-07-17 07:45:06 +00:00
roboomp 4d685bf761 fix(session): made /new an atomic boundary against queued steers
newSession() disconnects the agent listener and awaits abort() before
agent.reset(). abort()'s finally clears #abortInProgress and calls
#drainStrandedQueuedMessages(), which scheduled agent.continue() on the
still-old context — starting an unsolicited provider turn (e.g. from a
queued xdev-mount hidden steer) that raced the reset and appended its
late output to the fresh session.

Guard the drain to no-op while the session is disconnected from the
agent event stream (#unsubscribeAgent === undefined): a transition owns
the queue, and there is no listener to persist or render output. A plain
user-interrupt abort() stays connected, so its legitimate stranded drain
still runs.

Fixes #5800
2026-07-17 07:43:06 +00:00
roboomp 6b88e69057 fix(prompting): hid xd tools from direct inventory
- Filtered xd-mounted names from compact and inline tool inventories.

- Added regression coverage for both inventory rendering modes.

Fixes #5797
2026-07-17 07:09:23 +00:00
can1357 0f9fceeea4 test(plan): seeded anthropic runtime key in issue-816 repro
- Both plan-model transition tests relied on ambient host credentials to
  make anthropic models resolvable; on CI runners without keys the
  plan-role reassignment and restore paths were silently skipped.
- Seeded a runtime API key via AuthStorage, matching the pattern used by
  every other coding-agent session test.
2026-07-17 08:06:11 +02:00
can1357 0f26558d03 chore: reformat 2026-07-17 07:40:21 +02:00
can1357 eac51b6a04 Merge: darkphilosophy/feat/advisor-per-agent-toggle
Brings the per-advisor toggle, status-line glyphs, quota display, and the
failing-advisor stall/abort fix (f4c8143) onto main's rewritten advisor
runtime. Conflict reconciliation kept main's architecture (fingerprint
prefix reconciliation, host-level onTurnError recovery + fallback chains,
terminal-failure classification) and ported the branch semantics onto it:

- #failing latch: waitForCatchup resolves immediately while an advisor is
  mid-failure; parked waiters wake the moment a turn fails, before any
  async hook or retry sleep.
- Turn-end render containment: a formatter bug restores the cursor/prefix/
  dedup snapshot and never propagates into the primary's turn-end callback
  (per-advisor try/catch boundary in AgentSession).
- Quota pause: when host recovery declines a usage-limit failure, the
  runtime latches quotaExhausted, requeues the batch, and notifies —
  cleared only by an explicit reset.
- Hard halt after a permanent rejection or three backlog-drop cycles.
- #recoverAdvisorTurn also marks usage limits for structural errors thrown
  before any assistant turn is recorded.
2026-07-17 07:37:29 +02:00
can1357 38b73a5cbc style(tests): removed unused fixture variable and formatted plan test
The redaction-contract rewrite left credentialTokens unused in the
GitLab Duo provider test, failing biome's lint gate.
2026-07-17 07:24:54 +02:00
can1357 85b9c01f1c test(plan): made plan-role apply and restore regressions deterministic
The reassignment test awaited a single microtask, but the role-change
listener crosses real async storage hops since per-project model roles;
it now awaits the setModelTemporary call itself. The failed-restore
test picked claude-haiku unconditionally, which no-ops plan entry when
the ambient default already resolves to haiku (as on CI); it now picks
a model that differs from the active session model.
2026-07-17 06:56:59 +02:00
can1357 2a6d551063 revert(status-line): restored single-row status bar with priority drop
- Reverted PR #5751 (issue #5749): continuation rows wrapped the editor
  top border onto extra lines, which is unacceptable for the input frame.
- EditorTopBorder is back to a single content/width pair; narrow widths
  drop right segments, shrink the path, then drop left segments.
2026-07-17 05:49:13 +02:00