Commit Graph

571 Commits

Author SHA1 Message Date
Peter Steinberger 0d14434d0e feat(secrets): add explicit protected and agent-readable access (#126088)
* feat(secrets): add explicit agent access modes

Distinguish protected write-only secrets from agent-readable Gateway environment values, expose policy-bound Gateway exec aliases to Codex, and activate Node environment proxy support for destination-bound egress.\n\nCloses #125975

* fix(gateway): bind lifecycle dispatch to owning instance

* test(ui): preserve mock gateway recovery state

* fix(codex): avoid unavailable gateway process guidance

* fix(harness): keep run correlation host-owned

* fix(gateway): bind restart delivery to instance

* test(codex): construct tools through test host capability
2026-08-18 22:51:15 -07:00
Peter Steinberger a6b77ffc07 fix(msteams): preserve replies after durable ingress replay (#126169)
* fix(msteams): preserve replies across ingress replay

Recovered Teams channel and group-chat responses now preserve reply and quote context across durable ingress replay. Discovery metadata also advertises the existing group and reaction capabilities.

* chore(msteams): document replay assertion safety

* test(msteams): normalize replay delivery errors
2026-08-18 22:22:13 -07:00
Peter Steinberger baefd067bb fix(deps): keep package runtime dependencies single-owned (#126119)
* fix(deps): consolidate shared runtime helpers

* test(concurrency): support current test lib target

* fix(time): preserve year-scale plugin durations

* fix(agents): preserve empty subagent completions
2026-08-18 22:12:45 -07:00
Peter Steinberger 5564671c4f fix(gateway): bound audit and Codex backlogs (#126154)
* fix(gateway): bound audit and Codex backlogs

Live Gateway SQLite lock failures and process heap pressure exposed two
independent queue owners. Route best-effort audit persistence through the
canonical shared-state connection with bounded contention retries, and remove
the per-notification Codex yield so the keyed turn queue can drain directly.

Follow-up to #126033 and #126073.

* fix(gateway): annotate raw SQLite cold-open probe

* test(codex): register notification burst shard
2026-08-18 21:44:09 -07:00
Peter Steinberger 41ed3c3460 fix(ui): buttons use the default cursor instead of the link hand (#126153)
* fix(ui): reserve pointer cursors for links

* test: align cursor and docs contracts
2026-08-18 21:40:52 -07:00
Peter Steinberger 093b191318 test(agents): remove tool-policy warning reset API (#126175) 2026-08-18 21:37:26 -07:00
Jason (Json) d16c2858bf improve(update): make managed finalization timing auditable (#126107)
* improve(update): report finalizer phase timings

* test(update): return completion cache outcome

* refactor(update): isolate finalize command

* chore(update): document finalize config assertion

* test(update): isolate finalizer capability fixtures
2026-08-18 22:34:22 -06:00
Peter Steinberger 00482543ff fix(agents): bound Skill Workshop model projections (#126158) 2026-08-18 21:28:54 -07:00
Peter Steinberger a8bc60a119 refactor(ui): generalize session placement startup (#126118) 2026-08-18 18:59:50 -07:00
Peter Steinberger 4b8b2920b4 fix: fallback traces omit failed model candidates (#126048)
* fix(agents): preserve outer fallback execution traces

* fix(agents): align fallback trace contracts

* style(skills): format release validation instructions
2026-08-18 16:25:51 -07:00
Peter Steinberger e2643afb2a fix(codex): retain terminal facts in oversized trajectories (#126050)
* fix(codex): delegate trajectory bounding to host

* fix(trajectory): preserve compact terminal facts

* style: format release validation skill
2026-08-18 16:22:25 -07:00
Peter Steinberger b34eb16071 fix(copilot): restore OpenClaw guidance to agent turns (#125997)
* fix(copilot): add OpenClaw prompt guidance

Copilot append-mode system messages included credential safety, workspace bootstrap, and extra context but omitted OpenClaw delegation and reply-delivery policy.

Build guidance from the final policy-filtered tool surface so visible delegated work, Skill Workshop, and source replies follow the same behavior as Codex.

* fix(copilot): break prompt guidance import cycle

The CI architecture gate detected a cycle through attempt-config and prompt-guidance. Isolate raw-run mode detection in a leaf module.
2026-08-18 15:01:15 -07:00
Peter Steinberger fa62fccb86 refactor(gateway): remove workspace plugin generation projections (#125990)
* refactor(agents): remove workspace plugin generation projections

* test(agents): pass explicit generation in auth refresh
2026-08-18 14:03:27 -07:00
Peter Steinberger 5301fb5e7f fix(codex): preserve harness trajectories (#125941) 2026-08-18 11:47:09 -07:00
Peter Steinberger 97a4d324f5 fix(gateway): allow non-admin cloud sessions (#125787)
* fix(gateway): allow non-admin cloud sessions

Admin-provisioned shared runners are now usable by operator.write while raw environment, config, and pairing controls remain admin-only.

Closes #125602

* chore(test): prune assertion safety baseline

* refactor(gateway): isolate cloud reclaim lifecycle

* test(gateway): declare Codex dispatch ownership

* test(ui): cover session-scoped cloud cleanup

* perf(ui): trim tooltip startup path

* fix(gateway): fence cloud placement activation

* test(gateway): update move recovery dispatch contract

* fix(gateway): fail closed on placement recovery

* docs(gateway): explain fail-closed move recovery

* refactor(gateway): consolidate session mutation target keys
2026-08-18 11:33:54 -07:00
Peter Steinberger b1d53fcdda fix(browser): repair session lifecycle ownership (#125933)
Preserve browser availability and profile ownership across node and extension routes, close session-owned node tabs, honor screenshot refs, and hide unavailable tab-bound actions.
2026-08-18 11:20:04 -07:00
Peter Steinberger fd216cb550 fix: prevent plugin metadata rescans from stalling Gateway (#125596)
* fix(plugins): preserve gateway metadata ownership

Generic runtime contexts no longer displace the Gateway lifecycle snapshot, preventing repeated synchronous plugin inventory validation on session hot paths.

* fix(gateway): reuse lifecycle plugin generation for turns

* test(agents): align static runtime lifecycle expectations

* test(gateway): refresh minimal runtime fixtures

* test(runtime): pass lifecycle metadata explicitly

* fix(skills): reuse gateway metadata for commands

* test(gateway): prepare reply runtime for agent RPCs

* style(agents): format rebased runtime preparation

* test(gateway): prepare runtime for direct agent RPCs

* test(gateway): provide direct agent runtime fixture

* test(gateway): prepare chat send reply runtime

* test(qa): await descendant process exit
2026-08-18 10:47:16 -07:00
Peter Steinberger 0684f50136 fix(gateway): harden hook admission and shutdown (#125893)
* fix(gateway): harden hook admission and shutdown

Flush structured 413 and 408 hook responses before closing oversized or timed-out request sockets, and reject deferred wake requests that target an explicit session.

Direct Gateway close now marks startup and readiness as draining immediately and attempts every HTTP listener shutdown before reporting an incomplete close.

* test(gateway): model request destruction in fuzzing

Give the HTTP request fuzz double the IncomingMessage destroy contract exercised after 413 and 408 responses finish.

* fix(gateway): preserve response and shutdown bounds

Route installed webhook body-limit failures through the shared response-first close owner and require complete Feishu 413/408 responses before terminal connection closure.

Retain the current-main grace bound for agent-harness disposal so one stuck harness cannot block listener teardown.

* test(telegram): model response-close request cleanup

Keep the slow-body request alive through response finish, then assert cleanup when the mock response transport closes.
2026-08-18 10:39:56 -07:00
Peter Steinberger 2bed8caf9e feat(ui): channel conversation avatars in the sidebar (Discord + Slack) (#125668)
* feat(gateway): proxy channel conversation avatars

* feat(discord): capture conversation avatars

* feat(slack): capture DM sender avatars

* test(discord): bind guild avatar mock

* feat(ui): render channel conversation avatars

* fix(ui): align sidebar owner fixtures

* fix(gateway): version channel-avatar routes by media revision

A stable per-session URL let AuthenticatedAvatarRouteLoader's blob and
sticky-404 caches pin a mounted row to a stale or blank avatar after the
backing media changed. Append an opaque digest of the media reference so
replacement and 404-recovery change the route identity.

* test(ui): align sidebar owner facet

* fix(ui): keep owner chip until channel avatar loads

A session with a channelAvatarUrl suppressed its owner chip even while the
blob was loading, auth was not ready, or the route 404ed, leaving an empty
lead slot. The chip now rides as fallback content inside the avatar element
and yields only to a usable image. Covers 404 and auth-pending states;
avatar rows keep renderedOwnerId unset so an owner-viewer stays visible in
the facepile.

* perf(ui): keep channel avatar fallback within budget

* perf(ui): lazy-load the channel avatar element

The avatar element and its authenticated blob loader rode the startup
bundle through session-leading-indicator, pushing startup JS 51 B over the
CI gzip budget. Channel avatars are not startup-critical: register the
element on the first avatar row; the owner-chip fallback covers the
one-time upgrade window. Startup JS returns ~1 KiB under the ceiling.

* build(ui): raise startup baseline for channel avatars

CI-measured startup JS is 344379 B against a 343289 B baseline (+1090 B).
The avatar element and blob loader are code-split out of startup (previous
commit); the residual is the sidebar lead-slot render branch and row
plumbing, which cannot be deferred. Baseline updated via
check-control-ui-performance --update-baseline with CI bytes per the
script's contract; well inside the 4096 B ratchet step and 358400 B
ceiling.
2026-08-18 09:55:50 -07:00
Peter Steinberger 5f65ef8138 feat: add A2UI widgets to session boards (#125803)
* feat: add A2UI board widgets

* fix: harden A2UI board widget integration

* fix: repair A2UI CI contracts

* fix(canvas): keep native A2UI pushes on v0.8

* fix(canvas): support board-only widgets without file host
2026-08-18 09:08:45 -07:00
Peter Steinberger d84a910fc8 refactor(ui): send to the selected session; delete exact-run steer machinery (#125862)
browser no longer chooses or persists run targets; steer sends ride the generic durable outbox with queueMode steer and no expectedRunId/expectedLeafEntryId; deletes steer-lifecycle.ts, steered-chip.ts, kind:"steered", steerTargetRunId, sendState:"steering", target-bound retry, uniqueness failure rows; persisted outbox rows normalize at load; net -625 production LOC.
2026-08-18 08:38:23 -07:00
Peter Steinberger b9fb56566b fix(browser): treat Linux zombies as exited (#125831) 2026-08-18 07:32:02 -07:00
Peter Steinberger 4048ae26e0 feat: credit linked session participants as Git co-authors (#125827)
* feat: credit linked session participants as co-authors

Authenticated profiles can link GitHub and receive automatic co-author credit in shared coding sessions.

* style: format rebased co-author registries

* fix: mark profile schema DDL boundary
2026-08-18 07:15:01 -07:00
Peter Steinberger 4589d8514c fix(gateway): stop agent terminal processes after session archive (#125784)
* fix(gateway): stop terminal PTYs on session archive

Bind agent terminals to the durable session incarnation, drain exact ownership during archive, and terminate every job-control process group in the PTY session.\n\nCloses #125769

* test(gateway): cover terminal cleanup on archive

* test(gateway): align terminal outcome assertions

* test(gateway): preserve session exports in invoke test

* fix(gateway): await terminal exit before archive

* test(codex): consolidate supervised instruction coverage

Move the duplicated two-attempt regression into the canonical thread lifecycle test so the exact two-worker extension shard stays bounded on low-core CI.\n\nRelated: #125783
2026-08-18 06:27:42 -07:00
Ayaan Zaidi e8044fdffe fix(ui): group Skill Workshop applied revisions per skill with inline history (#125794)
The Applied view rendered every applied proposal as an independent recency-sorted row, so one skill's revision history looked like duplicate skills. Applied now shows one row per live skill with a revision-count badge and grouped tab count; the detail pane gains a lazily loaded History section with operations from the ledger's recorded kind. Pending/rejected/quarantined/stale keep one row per proposal.

Fixes #125632
2026-08-18 12:30:05 +00:00
Peter Steinberger 029f6c14cc refactor(ui): split oversized chat side-panel modules (#125770)
* refactor(ui): split chat sidebar modules

* fix(ui): break chat sidebar import cycle
2026-08-18 05:25:01 -07:00
Peter Steinberger f1453c7c77 fix(ci): heal red main - dialog reopen under isolation + startup baseline (#125800)
Two landed-PR races left main red (run 32131816085):

- #125692's rewritten markdown-tables dialog test drives every interaction
  through direct handler calls except the reopen, which used a raw
  expand.click() that only worked via a leaked cross-file document listener
  in the shared lane; #125766 moved the file to the isolated lane where no
  such listener exists. Reopen now uses the file's own handler idiom.
- Accumulated startup-JS creep from landed features put main 50 B over its
  gzip budget (344395 B vs 343289 B baseline + 1056 B tolerance). Baseline
  updated to main's CI-measured bytes via the script's --update-baseline
  contract.
2026-08-18 05:06:05 -07:00
Ayaan Zaidi a884d19bad feat(skills): merge execution-dir skills after agent workspace skills (#125786)
* feat(skills): merge execution-dir skills after agent workspace skills

* test(skills): cover new workspace-skill-loader exports in mock factories

* fix(skills): complete multi-root invariant across sync, CLI snapshot, and prompt fallback

* fix(skills): use canonical workspace session facts
2026-08-18 17:14:09 +05:30
Peter Steinberger 8cbeb51503 fix(ui): preserve automation mutation lifecycle (#125698)
* fix(ui): preserve cron mutation lifecycle state

* test(ui): align cron e2e revision fixtures

* fix(ui): preserve queued cron run feedback

* fix(ui): advance cron editor revision after toggle
2026-08-18 03:14:25 -07:00
Peter Steinberger dd2ad9695c fix(ui): hide invalid remote worktree choice (#125720)
* fix(ui): remove remote worktree choice

* fix(ui): remove stale node path copy

* test(ui): cover hidden unavailable detail controls

* test(ui): preserve cloud project checkout proof
2026-08-18 02:50:35 -07:00
Peter Steinberger 8a0d28d6ba refactor(qa): simplify scenario runner infrastructure (#125738) 2026-08-18 02:03:37 -07:00
Peter Steinberger 20b46bbb3b perf(memory): avoid duplicate embeddings during filtered recall (#125735)
* perf(memory): search filtered sessions in one pass

* refactor(memory): model transcript capture outcome
2026-08-18 02:00:38 -07:00
Peter Steinberger c9d924cd0f fix(agents): report local trash failures in JSON (#125715)
Expose per-path removed and failed outcomes for offline agent deletion so scripted callers can detect manual cleanup. Keep unfinished deletion journals retryable until every path reaches a terminal state.
2026-08-18 01:42:38 -07:00
Vyctor H. Brzezowski e349d520a2 feat(ui): add typed update recovery actions (#125098)
* feat(ui): add typed update recovery actions

* fix(ui): surface update status refresh failures

* fix(ui): keep update failure type internal

* fix(ui): publish update failure facts atomically

* fix(ui): validate update recovery startup budget

---------

Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
2026-08-18 01:31:21 -07:00
Peter Steinberger 079a874159 feat: revalidate cached chat history with cursor deltas (#125606)
* feat(gateway): add cursor catch-up to chat history

* feat(ui): revalidate cached transcripts via history cursor

* fix(ui): stop append-miss stubs clobbering persisted snapshots

* fix(gateway): fence history delta cursor to projected events

* fix: repair cursor delta landing gates
2026-08-18 00:54:58 -07:00
Peter Steinberger 9564b9fc00 fix(codex): preserve approval timeout outcomes (#125671)
Preserve operator approval terminal reasons through the harness, map denials and timeouts to Codex decline, and retain visible timeout evidence so the turn can continue instead of being killed.
2026-08-18 00:29:15 -07:00
Peter Steinberger 6cc40431d1 fix(voice): prevent choppy audio in realtime calls (#125620)
* fix(voice-call): pace realtime audio from stream clock

* fix(voice): preserve resampler state across audio chunks

* fix(voice-call): honor telephony TTS audio formats

* fix(voice-call): await acknowledged stream playback

* fix(voice): bound realtime input audio backlog

* chore(voice-call): shrink assertion baseline and localize tts format error

* test(voice-call): split playback-mark coverage into its own suite

* test(voice-call): drop helper left unused by suite split

* test(openai): scope queued audio copy assertion

* fix(openai): flush realtime resampler at response end

* fix(voice-call): reject containerized mulaw TTS
2026-08-18 00:07:01 -07:00
Peter Steinberger da4ad4110b fix(process): treat zombie lock owners as dead (#125658)
Linux signal-zero probes succeed for zombie processes. Reclaim memory promotion and session usage locks only when their exact zombie owner is still current, and route shared test waits through the canonical zombie-aware PID helper.
2026-08-17 23:55:08 -07:00
Peter Steinberger bbf7454b17 fix(codex): retain structured tool result details (#125610) 2026-08-17 22:13:33 -07:00
Josh Avant 916aca13f3 feat: record subagent execution lineage (#122015)
* feat(audit): record subagent execution lineage

* fix(audit): type-check spawn lineage validation

* docs: preserve spawned-run lineage invariants

* fix(audit): preserve lineage for worker spawns

* fix(audit): bind worker lineage to live authority

* fix(audit): keep lineage carrier private

* fix(sessions): preserve ACP participant recording

* fix(audit): keep lineage out of runtime bearer

* fix(audit): keep lineage type private

* test(audit): match current worker claim shape

* test(audit): preserve readonly lineage result

* fix(audit): redeem spawn lineage privately

* fix(audit): preserve lineage redemption on copy

* test(audit): prove nested worker spawn lineage

* fix(audit): restore execution identity CI gates
2026-08-17 21:41:30 -07:00
Peter Steinberger 1cf8ea446d fix(mcp): prevent stale catalogs and silent tool failures (#125564)
* fix(mcp): harden lifecycle and result integrity

* fix(mcp): bound catalog invalidation replay

* test(mcp): stabilize process cleanup proof
2026-08-17 21:37:12 -07:00
Peter Steinberger d9b69c5b6f fix(agents): keep model resolution on one plugin generation (#125569)
* fix(agents): pin model resolution to prepared generation

* test(agents): complete prepared runtime fixture
2026-08-17 21:32:37 -07:00
Peter Steinberger 01eec285d9 fix(cli): render gateway transport failures as expected conditions (#125556)
* fix(cli): render gateway transport failures as expected conditions

An unreachable gateway is an expected, recoverable operator condition, but
only the devices command family surfaced it through the root failure handler,
where it rendered as "The CLI command failed" with debug hints. Extract
GatewayTransportError into its own module so the failure renderer can classify
it without importing the transport stack, and treat it as an expected CLI
error alongside missing credentials.

* fix(gateway): import the transport error kind used by the JSON shape

* test(cli): extract the process-test gateway harness

The new devices coverage pushed gateway-backed-exit.process.test.ts past the
max-lines budget, and that file is not in the ratchet baseline. Move the mock
Gateway servers into a sibling test-helpers module instead of suppressing the
rule.
2026-08-17 21:18:02 -07:00
Peter Steinberger 7e7b860bca fix: preserve message delivery after result middleware (#125497)
* fix(agents): carry typed message delivery receipts

* fix(agents): preserve receipts across harness middleware

* fix(agents): preserve plugin broadcast delivery receipts

* fix(agents): preserve partial broadcast delivery receipts
2026-08-17 21:16:14 -07:00
Peter Steinberger 75fcaba919 fix(voice-call): survive gateway in-process restart and stop CLI dead-ends (#125458)
* fix(voice-call): survive gateway in-process restart and stop CLI dead-ends

The gateway's in-process restart (SIGUSR1 config reload) reuses the cached
plugin registry, so service stop/start run on the same retained voice-call
registration. Generation fencing from #120289 treated that restart as a stale
actor: stop retired the generation forever, the next start silently bailed,
and every voicecall.* RPC answered UNAVAILABLE "runtime generation is
retired" while the webhook never rebound.

- Registrations now hold a replaceable generation: service start after stop
  mints a fresh generation, takes over a running slot owned by a retired
  predecessor, and reports start failures to service health instead of
  silently returning.
- The voicecall CLI classifies gateway failures with typed guards instead of
  message substrings: standalone/store fallback only when the gateway is
  genuinely absent; reachable-but-failed (request errors, auth, timeout)
  exits with actionable text; a standalone webhook port collision explains
  that a running Gateway probably owns the port instead of raw EADDRINUSE.
- Plugin SDK gateway-runtime exports structural isGatewayTransportError /
  isGatewayClientRequestError guards (+2 documented surface budget).
- Regression coverage: same-registration stop/start restart, retired-owner
  takeover, typed CLI fallback classification, and a real token-auth gateway
  server routing voicecall.status through callGatewayFromCli.

* refactor(voice-call): split CLI modules and dedupe gateway fallbacks

Collapse the four duplicated gateway-or-runtime command blocks (speak, dtmf,
end, continue fallback) into one generic runGatewayManagerCommand helper —
the continue command owns its legacy-method fallback and operation polling
via a gatewayCall closure, so the helper carries no per-command policy.
Smoke reuses the shared initiateVoiceCall path instead of a bespoke
fallback.

Split the 988-line cli.ts into concept modules (cli-gateway-call,
cli-call-log, cli-command-io) and drop its grandfathered max-lines
suppression plus the now-stale max-lines and assertion-safety baseline
entries (shrink-only ratchet maintenance).

Behavior-frozen: stdout/exit semantics unchanged; net -2 production LOC.

* fix(voice-call): redact gateway URLs in CLI operational errors

ClawSweeper P1: the operational-error formatter interpolated the raw
connectionDetails.url, so a configured gateway URL with userinfo or query
tokens would print credentials into terminal output. Redact the composed
message once with the canonical net-policy redactor (also covers
remote-controlled close-reason text), exported through the plugin SDK
gateway-runtime subpath (+1 documented surface budget). Regression test
covers a credential-bearing URL in both the URL and message fields.
2026-08-17 18:59:19 -07:00
Peter Steinberger b5b17c654b fix: keep Workboard visible in the sidebar (#125473)
* fix(ui): keep workboard in sidebar navigation

* test(ui): align workboard navigation ownership

* fix(ui): preserve saved workboard sidebar slots

* test(ui): shrink assertion safety baseline

* fix(plugins): bind native routes to bundled owners

* refactor(plugins): isolate native route policy
2026-08-17 18:44:39 -07:00
Peter Steinberger bb1ce58514 refactor(gateway): remove obsolete reverse worker tunnel (#125465)
* refactor(gateway): remove reverse worker tunnel

* test(gateway): align worker transport expectations

* docs(gateway): clarify cloud worker ingress
2026-08-17 18:19:52 -07:00
Peter Steinberger 720da745d9 fix(voice-call): keep realtime calls alive through brief stream reconnects (#125469)
* fix(voice-call): grace realtime stream disconnects

Share reconnect grace by CallSid and stream ID across classic and realtime streams while cleaning realtime bridge resources immediately.

Log terminal call reasons and document Twilio inbound voice and status callback setup.

* test(voice-call): align reconnect grace after rebase

Preserve the newly landed realtime generation and inactivity coverage while updating its terminal expectations for shared delayed finalization.

Remove the redundant replacement cross-product case so the lifecycle suite remains below the max-lines limit.
2026-08-17 17:51:46 -07:00
Peter Steinberger e3de722971 refactor(tooling): consolidate baseline ratchets (#125459) 2026-08-17 17:17:49 -07:00
Peter Steinberger e169520fef fix: surface swallowed failures on action paths (#125319)
* fix: surface swallowed failures on action paths

* fix(memory): propagate directory traversal failures
2026-08-17 17:14:05 -07:00