Commit Graph

79964 Commits

Author SHA1 Message Date
Peter Steinberger b8a95e082b fix(ui): make terminal open failures retryable (#124890) 2026-08-16 16:15:24 -07:00
Peter Steinberger 00990506c0 fix(tui): close selection overlays and report rejected handlers (#124876)
openSelector's onSelect fired the async handler with void and only
closed the overlay after a successful await. A rejecting handler (e.g.
setAgent -> setSession against a failing gateway) left the selector
stranded open with an unhandled rejection: the TUI froze on the picker
with no visible cause — a silent dead-end.

Root cause: failure path missing from the overlay lifecycle. The
handler now catches, surfaces the cause via chatLog, and always closes
the overlay.

Regression: /agent selection with a rejecting setSession asserts the
overlay closes and the cause reaches the chat log — fails pre-fix.
2026-08-16 16:14:28 -07:00
ClawSweeper a4efa7c22b fix(ui): replace the broken terminal tab underline (#124875)
* fix(ui): redesign dock panel tabs

* fix(ui): remove stale terminal tab overrides

---------

Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
2026-08-16 16:11:30 -07:00
Peter Steinberger 572e9f907a fix(skills): expand explicit references on agent turns (#124784)
* fix(skills): expand explicit references on agent turns

Route generic Gateway, CLI, webhook, and local agent turns through the same explicit skill-reference renderer as channel auto-replies. Keep original transcript text, preserve unknown slash behavior, and fail visibly for allowlist-hidden skills.

Maintainer review: scoped Option 1 — generic agent turns expand both $skill-name and leading /skill-name args through shared skill rendering; they do not run the channel command dispatcher, and all other slash commands retain their existing behavior.

* fix(skills): bound explicit reference prompts

* fix(skills): prefer allowed reference collisions

* fix(skills): preserve command invocation boundaries

* fix(skills): reject hidden channel slash commands

* perf(skills): skip literal dollar discovery
2026-08-16 16:09:21 -07:00
Peter Steinberger 9cbf998c72 fix(cli): keep internal error causes out of operator output (#124887) 2026-08-16 16:08:56 -07:00
Peter Steinberger 06fa48099e fix(ui): reveal clipped session history (#124866)
* fix(ui): reveal clipped session history

Show a persistent earlier-history action for paginated sessions and reveal loaded content without chaining observer fetches.

Related: #110771

* refactor(ui): split chat history support
2026-08-16 16:04:30 -07:00
ClawSweeper 6bddfed530 fix: prevent clipped session selections and Code Mode timer crashes (#124879)
* fix(agents): support timers in code mode

* fix(ui): keep selected sessions clear of scrollbars

* fix(agents): propagate timer cancellation after resume

---------

Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
2026-08-16 16:03:54 -07:00
Josh Avant ffc94d0ff0 fix: stop forked commands after Gateway timeouts (#124081)
* fix: stop service child trees before timeout completion

* fix: preserve service child root results during cleanup

* test: isolate relay selection from linux spawn wrapping

* refactor: keep service anchor payload internal

* test: validate lifecycle probe pid output

* fix: close service child adversarial races

* fix: preserve service startup failures

* fix(process): flush service output before root result

* fix(process): bound cleanup on held output

* chore(process): satisfy promise executor lint

* fix(process): finish cleanup after lineage loss

* fix(process): retain relay output before subscription

* fix(ci): register service child runtime entries

* fix(ci): expose relay safety invariants

* fix(process): preserve service cancellation grace

* test(process): prove service grace on macOS
2026-08-16 16:02:34 -07:00
Peter Steinberger 1f1aa88f14 perf(ci): split Windows CI two ways instead of one serial lane
`checks-windows-node-test` ran the whole 222-266s Windows body in a single
Blacksmith lane, so every run that scheduled it finished at 287-334s against a
~180s plateau. Measured across 45 canonical main runs it was the wall in all
seven runs that triggered it (324-519s vs a 210s median elsewhere).

Blacksmith's Windows class admits exactly 2 concurrent jobs (run 31865243804),
which is why the earlier 3-part split failed: its tail queued 211s behind a
finished part. Pin the split width to that measured capacity instead. The two
parts are balanced by measured per-project wall time -- part 1 keeps the old
list 1 plus list 2's non-infra projects (~108s), part 2 takes list 2's infra
project plus the old list 3 (~112s) -- so both land near 113s and the lane
stops setting the wall.

One canonical partition now serves every backend; the github-mode/dispatch
3-part variant and its separate file inventory are gone, along with the
single-lane `task: test` case and the per-row `matrix.runner` the collapsed
lane needed. The complete 65-file Windows inventory is preserved exactly, and
the guards pin the width on both sides (mutation-checked: restoring 3 parts
fails the matrix guard).
2026-08-16 16:02:24 -07:00
Shakker efc243823f docs: note length-aware Workboard errors (#118888) 2026-08-16 23:54:27 +01:00
Shakker 02d8b46b24 test: cover Workboard length errors at gateway boundary 2026-08-16 23:54:27 +01:00
Kailigithub 8f174ceca2 test(workboard): align matrix with real normalizeBoundedString consumers
ClawSweeper flagged that the prior matrix at line 31-48 tested
labels/title/notes by manually invoking normalizeBoundedString, even
though those fields use the independent normalizeTitle, normalizeNotes,
and normalizeLabels functions (each with its own generic message).
A regression that drops the (got N) suffix from normalizeBoundedString
would not be caught for those three surfaces — operators would still
see the old opaque error.

This commit narrows the matrix to only the consumers of the shared
helper (comment body, link title, link target, link URL, card id) and
restores the exact labels gateway assertion that should match the
unchanged normalizeLabels error.

Verification: 9/9 inline Node 18 AST harness (node /tmp/verify-pr-118888-v77.mjs);
parent-commit proof-gate (pre-PR helper without the got suffix) fails
4/9 of the post-fix expected messages.

Closes ClawSweeper review on PR #118888 (P2 + P3).
2026-08-16 23:54:27 +01:00
Kailigithub f990fb777a fix(workboard): include actual length in bounded-string error
The shared normalizeBoundedString helper in extensions/workboard/src
threw an opaque error like 'comment body must be 2000 characters or
fewer.' whenever an oversize string hit any bounded field. Agents that
posted a long run summary or oversized link URL had no way to tell
how far over the limit they were, so they could not retry with a
trimmed payload.

Include the actual length in the error so the message tells the agent
exactly what to do next:

  comment body must be 2000 characters or fewer (got 3502).

The format applies uniformly to every bounded field routed through
this helper (labels, link URL, link title, link target, comment
body, title, notes, worker log message, session key, run id,
protocol violation detail, etc.) since the helper is the single
canonical owner of the message.

Cover the new format with a focused unit test that pins the regex
for the comment-body repro from #118845 and exercises the six other
bounded fields listed in the issue. Update the existing
gateway.test.ts assertion to allow both the old and new format so
the format change is a forward-compatible improvement.
2026-08-16 23:54:27 +01:00
Peter Steinberger 57b1a69167 fix(state): report v9 registry migration row decisions (#124862)
* fix(state): report v9 registry migration row decisions in doctor and logs

* fix(state): consume registry migration summary type

* fix(state): avoid registry path observer import cycle
2026-08-16 15:52:42 -07:00
Peter Steinberger 800a0bb52a perf(webui): render cached model catalog while the chat pane refreshes (#124868)
* perf(webui): render cached model catalog while the chat pane refreshes

* test(webui): fix seed-test types and shrink assertion baseline
2026-08-16 15:52:26 -07:00
Peter Steinberger 7344ce4341 fix(browser): cancel node discovery with tool runs (#124880)
Amp-Thread-ID: https://ampcode.com/threads/T-01a00b6b-e4e9-74af-bb31-30363fae6c89

Co-authored-by: Amp <amp@ampcode.com>
2026-08-16 15:52:00 -07:00
Peter Steinberger 8aef31b903 fix(ui): align update status card spacing (#124878) 2026-08-16 15:48:55 -07:00
Vyctor H. Brzezowski 03f4ff5cc2 fix(ui): restore task count badge (#124840) 2026-08-16 19:48:19 -03:00
Peter Steinberger 72ddf22b93 fix(qa): recover repeated gateway restarts through channel ingress (#124746)
* fix(qa): repair repeated gateway restart recovery

* test(qa): satisfy restart recovery checks

* fix(audit): rekey repeated recovery identity

* fix(plugin-sdk): expose authored context cap

* test(android): synchronize process tree readiness
2026-08-16 15:47:31 -07:00
Peter Steinberger eadde4a9d0 fix(ui): show recovery when Control UI does not render (#124861)
* fix(ui): retire bootstrap fallback after render

* test(ui): avoid returning from Promise executor
2026-08-16 15:46:15 -07:00
Peter Steinberger 358c06ec95 fix(gateway): persist agent turns before acknowledgement (#124857)
* fix(gateway): persist agent turns before acknowledgement

* fix(gateway): revalidate exec approval handoffs

* docs(gateway): clarify durable session ownership

* fix(gateway): reject stale transcript admission targets
2026-08-16 15:42:49 -07:00
Peter Steinberger add30d455d refactor(security): consolidate path containment onto canonical fs-safe guard (#124870)
* refactor(security): expose canonical path containment modes

* refactor(agents): use canonical path containment guard

* refactor(security): consolidate core path containment sites

* refactor(plugins): consolidate path containment sites

* test(security): cover canonical path containment behavior
2026-08-16 15:37:02 -07:00
Peter Steinberger 9b468ccaa2 test: replace assertion chains with typed fixture builders — wave 2 (#124865) 2026-08-16 15:36:45 -07:00
Peter Steinberger 03cf9851d8 fix(protocol): model cron run delivery trace (#124856)
* fix(protocol): model cron run delivery trace

* chore(protocol): refresh generated cron run model
2026-08-16 15:34:56 -07:00
Peter Steinberger 36b0971772 perf(test): reuse postpublish file-cap fixture (#124871) 2026-08-16 15:31:46 -07:00
Peter Steinberger 1ce67d541f docs(ci): record artifact checkout experiment 2026-08-16 15:30:04 -07:00
Peter Steinberger 2d3612da6b fix(gateway): preserve prepared plugin metadata under load (#124844)
* fix(gateway): preserve prepared plugin metadata under load

* fix(gateway): project metadata before catalog preparation

* test(agents): assert projected startup metadata

* test(gateway): bind load probes to each finalization wave
2026-08-16 15:14:39 -07:00
Peter Steinberger 6c66f48a7c fix(cli): emit one JSON failure contract for --json invocations (#124849)
* fix(cli): unify JSON failure output

* test(cli): update skills verify failure envelope
2026-08-16 15:09:58 -07:00
Peter Steinberger 0b5bb09510 fix(test): propagate parent heavy-check ownership (#124859)
Amp-Thread-ID: https://ampcode.com/threads/T-01a00b7c-b9f0-73d5-8fb7-e619e8e458e1

Co-authored-by: Amp <amp@ampcode.com>
2026-08-16 15:09:30 -07:00
Peter Steinberger efdfb69adc fix(agents): keep queued followups from missing post-compaction context (#124850)
* fix(auto-reply): order post-compaction context before followups

Amp-Thread-ID: https://ampcode.com/threads/T-01a00b6b-e4e9-74af-bb31-30363fae6c89

* test(auto-reply): clean compaction workspace fixture

Amp-Thread-ID: https://ampcode.com/threads/T-01a00b6b-e4e9-74af-bb31-30363fae6c89

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-16 15:06:39 -07:00
Peter Steinberger 2d887acba3 fix(slack): drop the tool-call receipt from finished progress cards (#123851)
The Block Kit session card terminalized into a '🛠️ N tool calls · ⏱️ Ns'
footer, leaving a per-turn receipt in the Slack transcript on the default
progress path. PR #122976 deleted the same receipt from the native progress
surface but left this sibling rendering it.

Finished cards now keep only the durable diff stat and the session link;
tool-call and elapsed counters stay live working state. Also corrects the
documented channels.slack.streaming.mode default, stale since #122552.
2026-08-16 14:58:23 -07:00
Peter Steinberger 8754be900a feat(ui): add steer-now composer shortcut (#124826) 2026-08-16 14:57:58 -07:00
Peter Steinberger eab2b8fdca refactor(slack): mark approval headers with typed block ids (#124841) 2026-08-16 14:53:26 -07:00
Peter Steinberger 080887df92 refactor(types): discriminated unions for internal contracts — pilot lane A (#124845) 2026-08-16 14:49:28 -07:00
Peter Steinberger fb841993b1 perf(test): remove Gmail watcher shutdown wait (#124851) 2026-08-16 14:41:28 -07:00
Peter Steinberger 06101b1037 refactor(validation): consolidate boundary guards into schemas (#124820)
* refactor(validation): consolidate boundary guards into schemas — pilot lane B

* fix(meetings): reject non-object browser status
2026-08-16 14:41:14 -07:00
Peter Steinberger d23246770a fix(memory): report indexed SQLite sessions (#124834)
* fix(memory): report indexed SQLite sessions

* refactor(memory): remove unused state path export
2026-08-16 14:38:15 -07:00
Peter Steinberger eec67fd67b fix(ui): keep sent images visible through history handoff (#124839) 2026-08-16 14:35:21 -07:00
Peter Steinberger 9b17b93414 refactor(ui): derive cron types from gateway protocol (#124827)
* refactor(ui): derive cron types from gateway protocol

* fix(protocol): preserve cron session target type
2026-08-16 14:34:26 -07:00
Peter Steinberger 33f3b72a19 refactor(plugin-sdk): extract stream and SecretRef primitives (#124835) 2026-08-16 14:30:11 -07:00
Peter Steinberger 68762ad22c fix(ui): give queued-outbox badges their own outbox icon (#124842)
The sidebar queued-message badge and the composer queue reused the clock
glyph that also marks attached automations, so a session with both showed
two identical clocks distinguishable only by tooltip. Add an outbox tray
icon (Lucide inbox with the roof swapped for a rising arrow) and use it
for queued-to-send surfaces; the clock stays automation/cron-only. The
mock dev fixture now flags one session with hasAutomation so the badge
renders in mocked-dashboard proofs.
2026-08-16 14:29:41 -07:00
Peter Steinberger 86cfcd3833 fix(delivery): unify terminal settlement ownership (#124825)
* fix(delivery): unify terminal settlement ownership

Treat identityless adapter returns as potentially visible across channel, queue, and cron paths. Let recovery own terminal completion so ambiguity persists as notice debt instead of being double-settled or silently suppressed.

Co-authored-by: ruel225 <ruel225@users.noreply.github.com>

* refactor(delivery): narrow terminal internals

Remove now-unused internal exports after terminal-settlement ownership was consolidated.

* test(tts): preserve message runtime exports

Import and spread the actual message runtime so the focused mock retains every runtime binding while overriding only the durable send core.

---------

Co-authored-by: ruel225 <ruel225@users.noreply.github.com>
2026-08-16 14:28:26 -07:00
Peter Steinberger 8635f9cf03 fix(agent): preserve implicit roster in configless exec (#124805)
Amp-Thread-ID: https://ampcode.com/threads/T-01a00b7c-b9f0-73d5-8fb7-e619e8e458e1

Co-authored-by: Amp <amp@ampcode.com>
2026-08-16 14:27:29 -07:00
Peter Steinberger 2f98eeabfd feat(auto-reply): record message-tool mute outcomes (#124830)
* feat(auto-reply): record message-tool mute outcomes

* fix(auto-reply): require source delivery evidence

* test(infra): preserve historical agent schema fixtures
2026-08-16 14:26:20 -07:00
Peter Steinberger 313fcf1dba fix(channels): route direct DM replies to sender (#124837)
Default direct-message reply context to the authenticated sender address so targetless Reef and Nostr replies do not resolve to the local recipient.
2026-08-16 14:24:30 -07:00
Peter Steinberger 4aafed1f4a fix(media): bound image-optimize fetch headroom to the image cap (#124838)
When a caller passed an explicit maxBytes with optimizeImages on (the
default), the source-read bound was inflated to max(maxBytes, 100MB
document cap). A channel with a 5MB attachment cap therefore let a
hostile or oversized URL buffer up to 100MB before the final size check
— 20x resource amplification, and the inflation applied before content
classification, so it was not limited to images.

The inflation exists so oversized-but-compressible originals can be
fetched and compressed under the delivery cap. Size that headroom off
the thing that justifies it: 4x the 6MB image cap (24MB), enough for
large phone photos, instead of the document cap.

Accepted tradeoff (named at the constant): originals above 24MB that
would have compressed under the cap now fail; the fetch error names the
bound. Callers without an explicit cap keep per-kind defaults.

Live proof on a real localhost HTTP server (no mocked fetch): an 8.1MB
PNG under a 5MB cap compresses to 3.75MB and delivers; a 30MB-declared
image is rejected at the Content-Length precheck in 7ms with 'content
length 31457280 exceeds maxBytes 25165824'.

Regression: headroom-bound test fails pre-fix (30MB passes the old
100MB bound); companion test proves compression headroom still works.
2026-08-16 14:23:25 -07:00
Peter Steinberger 63a3a958f4 fix(browser): support Chrome Web Store native bootstrap (#124775)
* fix(browser): support Chrome Web Store native bootstrap

* chore: keep browser release note in PR body

* docs(browser): document Store identity trust boundary

* docs(browser): correct Store recovery guidance
2026-08-16 14:20:47 -07:00
Peter Steinberger 65922f9507 fix(gateway): share generated session titles with worktree names and start title work at dispatch (#124787)
Worktree sessions now derive their worktree/branch name from the same
concise generated title the sidebar shows (bounded 8s wait, raw-prompt
slug then crustacean fallback), persisted once as displayName so the
chat-send pass never duplicates the model call. Dashboard title
scheduling moves from the dispatch chain's finally (after the whole
first turn) back to dispatch start, so long or interrupted first turns
no longer leave sessions silently untitled (regression from #122471).
slugifyWorktreeTitle truncates at word boundaries; dead
generatedDisplayName plumbing removed.
2026-08-16 14:07:54 -07:00
ClawSweeper da85382686 improve(ui): make chat disclosures compact (#124832)
Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
2026-08-16 14:04:47 -07:00
Peter Steinberger d39a29fcbe fix(browser): stop local actions when agent turns are cancelled (#124795)
* fix(browser): cancel local actions with agent signal

Amp-Thread-ID: https://ampcode.com/threads/T-01a00b6b-e4e9-74af-bb31-30363fae6c89

* fix(agent-harness): expose authored context cap

Amp-Thread-ID: https://ampcode.com/threads/T-01a00b6b-e4e9-74af-bb31-30363fae6c89

* chore(agent-harness): drop redundant context-cap override

Amp-Thread-ID: https://ampcode.com/threads/T-01a00b6b-e4e9-74af-bb31-30363fae6c89

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-16 14:03:43 -07:00