Commit Graph

77765 Commits

Author SHA1 Message Date
Dallin Romney e323d862cb ci: persist extended-stable Docker completion 2026-08-10 17:17:01 +08:00
Dallin Romney 883eb91053 ci: make extended-stable closeout idempotent 2026-08-10 17:17:01 +08:00
Dallin Romney 5ce4cf8319 ci: publish extended-stable GitHub releases 2026-08-10 17:17:01 +08:00
Ayaan Zaidi 2d627a0c25 feat(skills): repair used skills in turn (#121522)
* feat(skills): repair used skills in turn
* fix(skills): bind repair to used skill receipt
* fix(skills): preserve explicit repair review

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-10 14:42:41 +05:30
Peter Steinberger 6f917dfabb test(macos): remove remaining coverage exercisers (#121413)
* test(macos): remove remaining coverage exercisers

* test(macos): remove dead skills typealias

* test(macos): remove unused skill config constructor
2026-08-10 02:08:34 -07:00
Pavan Kumar Gondhi c9d39979f2 fix(ci): read dependency guard state from trusted metadata [AI] (#121505)
* fix(ci): bind dependency guard state to head

* test(ci): isolate dependency guard state forgeries
2026-08-10 14:32:49 +05:30
Peter Steinberger a77dd02a04 fix(plugin-sdk): restore API baseline manifest (#121527) 2026-08-10 02:02:12 -07:00
Vincent Koc a994d2ad5f fix(qa): provide protocol base to evidence runs (#120710)
Co-authored-by: Dallin Romney <6581799+RomneyDa@users.noreply.github.com>

Punchcard-Session: amber-workshop-workshop-36
2026-08-10 16:59:58 +08:00
Peter Steinberger 560d172ae7 chore(scripts): prevent new wrapper shadowing (#121456)
* chore(scripts): prevent wrapper shadowing

* chore(scripts): refresh wrapper baseline
2026-08-10 01:40:44 -07:00
Peter Steinberger 83dfd44eca fix(terminal): always emit full intro art (#121501)
* fix(terminal): always emit full intro art

Open-time request.cols is the pre-fit boot grid (the client resizes right
after open), so the 40-column gate suppressed the art on real terminals.
Live-verified against a dev gateway on post-merge main.

* test(terminal): align intro banner fixture
2026-08-10 01:30:37 -07:00
Dallin Romney a471a94b53 fix(matrix): preserve payload delivery ownership (#121006) 2026-08-10 16:30:11 +08:00
Ayaan Zaidi 2642d79000 fix(agents): suppress recovered patch warnings
Track apply-patch targets through the shared patch grammar so successful per-file recovery clears stale failure warnings while incomplete recovery remains visible.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-10 13:59:49 +05:30
Peter Steinberger 51a78b2924 fix(update): keep countdown stable during active work (#121504) 2026-08-10 01:29:41 -07:00
Peter Lee 816d787413 fix(models): normalize partial cost in generated plugin catalogs to prevent schema validation warnings (#116317)
* fix(models): normalize partial cost in generated plugin catalogs to prevent schema validation warnings

* fix(models): handle no-cost overlays and fix test types for catalog cost normalization

* fix(models): preserve tieredPricing when completing catalog costs and remove duplicate Anthropic branches

* fix(models): normalize model costs after duplicate merge

* fix(models): normalize catalog costs at publication

---------

Co-authored-by: Dallin Romney <dallinromney@gmail.com>
2026-08-10 16:26:38 +08:00
Peter Lee f8cfd54f41 fix(infra): heartbeat runs honor timeoutSeconds 0 as unlimited (#119297)
* fix(infra): preserve timeoutSeconds 0 as unlimited for heartbeat runs

* test(infra): consolidate heartbeat timeout coverage

---------

Co-authored-by: Dallin Romney <dallinromney@gmail.com>
2026-08-10 16:21:14 +08:00
Ayaan Zaidi 7d4d02fff0 feat(skills): improve used skills autonomously
Teach the semantic reviewer to improve skills the agent actually used, keep review input provider-bound, and preserve bounded deterministic retries.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-10 13:50:33 +05:30
Peter Lee 780e3b0ef1 fix(gateway): reject invalid session history cursor with 400 (#119443)
* fix(gateway): reject invalid session history cursor with 400

* fix(gateway): export resolveCursorSeq and resolveSessionHistoryTailReadOptions from revocation-test mock

* fix(gateway): reject blank session history cursors

* fix(gateway): preserve blank cursor compatibility

* test(gateway): fit cursor case title formatting

---------

Co-authored-by: Dallin Romney <dallinromney@gmail.com>
2026-08-10 16:20:08 +08:00
Ayaan Zaidi 223015ba07 fix(models): probe Codex-pinned providers through OpenClaw
* fix(models): probe Codex-pinned providers through OpenClaw

---------

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-10 13:49:37 +05:30
Peter Lee f50260764a fix(gateway): MCP App standalone UI hangs when sandbox fetch never resolves (#119276)
* fix(gateway): add timeout to MCP App standalone fetch calls

* fix(gateway): honor configured MCP request deadline in standalone app operations

* fix(gateway): preserve MCP request timeout across catalog invalidation and add gateway grace

- Snapshot requestTimeoutMs onto McpAppViewLease at view creation so the
  configured deadline survives catalog invalidation (e.g. tools/list_changed).
- Add bounded gateway grace to the browser-side operation fetch signal so the
  outer timer expires after the runtime MCP deadline, avoiding false failures
  for valid near-deadline operations.
- The initial view load remains bounded at 30s.

* fix(gateway): read MCP App view deadline from runtime session, not invalidatable catalog

* fix(gateway): pass initial-load timeout through serialized MCP App host config

* fix(gateway): clamp MCP App browser operation timeout to timer-safe maximum

* fix(gateway): preserve native MCP App request budgets by omitting browser timeout when runtime has no deadline contract

* fix(gateway): own MCP app deadlines at the view boundary

---------

Co-authored-by: Dallin Romney <dallinromney@gmail.com>
2026-08-10 16:19:23 +08:00
Peter Lee 9aebf14695 test(providers): cover clone-tee binary rejection cleanup (#119457) 2026-08-10 16:18:38 +08:00
Ayaan Zaidi 4b0151682e refactor(commitments): remove inferred follow-up subsystem
Remove hidden follow-up extraction, heartbeat delivery, CLI, docs, and supporting tests/tooling. Existing commitment records remain inert pending separately approved cleanup.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-10 13:48:32 +05:30
Dallin Romney a808b0d96a docs(release): reconcile stable maturity issue signals (#120515)
* docs(release): reconcile stable maturity issue signals

* docs(release): preserve stable label audit context

* docs(release): reconcile open labelled fixes
2026-08-10 16:13:34 +08:00
Peter Steinberger bcf342903f refactor: finish export shadow hazard renames (#121471)
* refactor(gateway): distinguish pending node handlers

* refactor(approvals): distinguish button presentation builder

* refactor(daemon): distinguish service home resolver
2026-08-10 01:01:20 -07:00
Peter Steinberger 5b478bb64f fix(windows): shorten home paths case-insensitively (#121455) 2026-08-10 00:59:32 -07:00
Peter Steinberger 7954dde7cc fix(cloud-workers): support large Git workspaces (#121262)
* fix(cloud-workers): support large git workspaces

* test(cloud-workers): track workspace temp dirs

* refactor(cloud-workers): keep inventory helpers internal
2026-08-10 00:56:48 -07:00
Peter Steinberger da2684b890 fix: serialize onboarding and plugin installation (#121482)
Co-authored-by: Amp <amp@ampcode.com>
2026-08-10 00:49:25 -07:00
Peter Steinberger f6298bf84d fix(workers): preserve disappeared-worker failures across restarts (#121122)
* fix(workers): persist placement terminal failures

* fix(workers): refresh placement protocol clients

* refactor(workers): isolate error formatting

* fix: integrate cloud terminal state with current main

* chore(plugin-sdk): refresh API baseline

* refactor(ui): inline one-use cloud terminal-reason banner helper

Keeps the Control UI startup JS bundle inside its 317 KiB gzip budget
(the helper + type-only import tipped it by 16 bytes).

* refactor(ui): trim terminal-reason lookup to type-erased optional access

Recovers the last gzip byte of the Control UI startup budget
(324609 B vs the 324608 B limit).
2026-08-10 00:36:52 -07:00
Peter Steinberger 3f08684989 feat(control-ui): preview text attachments inline with a download action (#121400)
* feat(control-ui): preview text attachments inline with a download action

Document attachments in chat now render a unified attachment card: text-like
files get a bounded, cached inline preview plus an explicit download button;
other documents get the same card chrome with a download action.

* fix(control-ui): split document preview module and e2e file under lint caps

* fix(control-ui): keep availability helpers module-internal after resolver move

* fix(control-ui): cancel document preview streams at the preview budget

Reads at most the preview budget from the response body and cancels the
reader, so unknown-size or endless text attachments cannot buffer fully
just by rendering; adds a streaming regression test.

* fix(control-ui): slice preview chunks to the byte budget before decoding

A blob or misbehaving source can deliver one giant chunk; cap the bytes
handed to TextDecoder at the remaining preview budget so rendering never
allocates or scans the full payload. Adds a single-oversized-chunk
regression asserting the decoded byte bound.

* test(control-ui): track decoded bytes via a TextDecoder subclass

Replaces the prototype spy that tripped typescript(unbound-method) in
oxlint with a stubbed tracking subclass; unstubGlobals restores it.
2026-08-10 00:30:56 -07:00
Peter Steinberger e4b617300d refactor(macos): remove obsolete Gateway startup probe (#121439)
* refactor(macos): remove dead gateway command builder

* chore(i18n): refresh native inventory after gateway-env cleanup
2026-08-10 00:19:23 -07:00
Peter Steinberger e0262e6aa4 feat(ui): add people session sorting (#121470)
* feat(ui): add people session sorting

Offer People sorting in the Control UI session sidebar when the Gateway reports multiple session-sharing identities.

* fix(ui): restore sidebar translation dependency

* fix(ui): preserve session sort ordering contracts
2026-08-10 00:18:02 -07:00
Peter Steinberger a7d61fc114 fix(ui): remote sessions show pasted titles and final replies (#121467)
* fix(ui): refresh remote session titles and final replies

* test(ui): split sidebar presentation e2e coverage
2026-08-10 00:13:55 -07:00
Peter Steinberger 32c740384a improve(ui): show dashboard switcher only for real board content (#121480)
* improve(ui): remove builtin observer dashboard injection

The Control UI fabricated a synthetic Observer tab + read-only builtin
widget on top of the real board snapshot whenever a session produced an
observer digest, which forced hasBoard=true and surfaced the prominent
chat/split/dashboard face switcher for sessions that never had a
dashboard. The dashboard face only duplicated the chat-rail observer HUD.

Delete the injection path, the builtin widget kind and its readOnly
concept, the pane-local ObserverDigestHistory, the observer widget
renderer/styles, and the orphaned chat.observer.* i18n keys. The session
header face switcher now appears only when the board provider has real
content. Chat-rail observer HUD, sidebar narration, config observer
settings, and protocol surfaces are unchanged.

* test(ui): give plugin widget cell chunk waits a real timeout

The four vi.waitFor calls on the lazily imported workboard-card element
used the 1s default, which a cold transform exceeds on loaded machines;
observed flaking 1-3 of 4 tests depending on host contention.
2026-08-10 00:13:51 -07:00
Peter Steinberger f9730534fb feat(ui): turn the widget pin action into an icon button (#121419)
* feat(ui): turn the widget pin action into an icon button

The chat widget card's pin control was a bare text button ("Pin to
dashboard" / "Pinning…" / "Pinned"). It is now a 26px icon button using
the shared Lucide pin icon, styled like the adjacent widget-actions
trigger, with the accent color marking the pinned state. Labels move to
title/aria-label so tooltips and accessible names are unchanged, and the
two pin handlers collapse into one shared helper. The session-dashboard
e2e now records hover/pinned proof screenshots under
.artifacts/control-ui-e2e/workboard-pin when OPENCLAW_UI_E2E_RECORD=1.

* test(ui): assert pin button state via aria-label

The pin control no longer carries text content; the pinned state is
exposed through aria-label/title, which is what the widget-card unit
test now asserts.

* fix(ui): trim pin action label updates
2026-08-10 00:13:23 -07:00
Sarah Fortune a968d15f63 feat(slack): enable Enterprise Grid identity, DMs, routing, actions, approvals, and presence (#121373)
* refactor(slack): detect Enterprise Grid installs at runtime

* fix(slack): preserve enterprise bot identity

* style(slack): format enterprise identity test

* fix(slack): scope enterprise config by workspace

* fix(slack): preserve qualified binding casing

* feat(slack): enable enterprise presence polling

* fix(slack): normalize enterprise binding accounts

* fix(slack): require workspace-scoped Grid targets

* docs(slack): document Enterprise policy target forms

* fix(slack): preserve Grid pairing workspace scope

* refactor(slack): simplify scoped target formatting

* fix(slack): repair Enterprise Grid CI checks

* chore: refresh generated Slack metadata

* refactor(slack): simplify optional workspace scope

* test(slack): infer installation state handle types

* chore: resolve plugin SDK baseline conflict

* fix(ci): regenerate plugin SDK API baseline on Linux

* fix(slack): allow standalone workspace sends

---------

Co-authored-by: Sarah Fortune <sarah.fortune@gmail.com>
2026-08-10 07:10:06 +00:00
Peter Steinberger 5fad24c8da refactor(agents): split CLI output into concept modules (#121412)
* refactor(agents): split cli-output into concept modules

* refactor(agents): canonicalize complete JSONL on the streaming parser

* refactor(agents): delete retired codex-exec projection residue

* chore(lint): ratchet max-lines baseline after cli-output split

* fix(agents): restore truncated-stream rejection and prune split leftovers

* fix(agents): prune cli-output lint leftovers

* style(agents): use import type for cli-output contract types
2026-08-10 00:03:34 -07:00
Peter Steinberger 145ec3778f refactor(agents): consolidate failover classification into one substrate (#121341)
* refactor(agents): consolidate failover classification substrate

* chore(agents): align failover refactor guards

* fix(agents): preserve leading 429 status handling

* perf(agents): retain lazy failover hook gating

* chore(agents): refresh failover guard artifacts
2026-08-09 23:58:44 -07:00
Peter Steinberger 0e74a1bd86 fix(agents): clean up failed SSH session setup (#121457)
Remove temporary SSH config directories when config writes or permission hardening fail, using one lifecycle owner for both SSH session constructors.
2026-08-09 23:58:09 -07:00
Peter Steinberger 3621c4b511 feat: browse and start sessions inside agent workspaces (#121417)
* feat(gateway): allow workspace-contained browsing

* fix(ui): preserve canonical workspace selections
2026-08-09 23:57:46 -07:00
Peter Steinberger 98298a9f55 fix(ui): commentary survives refresh after steering (#121449)
* fix(ui): preserve commentary across steered refreshes

Retain keyed active-run commentary and its original timestamps so Control UI reloads keep progress on the correct side of persisted steering messages.

Closes #121448

* refactor(ui): simplify active-run replay coverage

Reuse the run-bound lookup and remove redundant transcript, hydration, and browser-test setup while preserving the steering refresh regression contract.
2026-08-09 23:55:38 -07:00
Peter Steinberger 8bb1fe4d7e fix(acp): drain runtime handles on gateway shutdown (#121359)
* fix(acp): drain runtime handles on gateway shutdown

* refactor(acp): isolate manager shutdown lifecycle

* style(acp): brace lifecycle guard

* fix(acp): cancel active turns before shutdown drain

* fix(acpx): reap process tree before wrapper close

* fix(test): diagnose surviving Vitest process groups

* fix(test): type process completion signals portably

* fix(test): reap orphaned live Docker workers

* fix(test): preserve child signal typing

* fix(gateway): retain ACPX through manager drain

* test(gateway): type deferred ACP disposal exactly
2026-08-09 23:55:19 -07:00
Peter Steinberger 6b365fa5d3 fix(ui): keep own-message sender name stationary on footer hover (#121406)
The persistent-identity footer for the viewer's own messages is
right-aligned, so the hover-revealed relative timestamp used to push the
always-visible sender name sideways. Flip the visual order with CSS
`order` so the time slots in to the left of the name and the name stays
pinned under the avatar. Peer footers are left-aligned and already
stable; DOM (screen-reader) order is unchanged.
2026-08-09 23:53:49 -07:00
Peter Steinberger a6a464f4c0 feat(terminal): fullscreen /terminal route and dot-matrix claw intro (#121451)
* feat(ui): add fullscreen /terminal route and open button

* feat(terminal): dot-matrix claw intro banner and CLI mascot

* fix(terminal): satisfy lint and wizard-header assertions for the new mascot

* ci: account for fullscreen terminal startup bytes

* test(terminal): split session manager coverage
2026-08-09 23:52:59 -07:00
Vincent Koc f4987deb94 fix(ci): support frozen validation scripts (#121458) release-publish/f4987deb94b8-1786361493 2026-08-10 14:49:51 +08:00
Peter Steinberger 98d1397a9d fix(ui): keep chat sidebar opening transparent (#121464)
Keep transient sidebar columns transparent while preserving explicit panel and discussion surfaces.\n\nFixes #121462. Related to #113712 and #121435.
2026-08-09 23:42:15 -07:00
Vyctor H. Brzezowski 35e8798828 fix(ui): offer undo and a named recovery path when hiding a sidebar section (#121385)
* fix(ui): offer undo and a named recovery path when hiding a sidebar section

Hiding a session catalog section wrote the preference and returned nothing:
the section vanished, no undo was offered, and the only standing recovery
(Settings > Appearance > Sidebar) was never named anywhere near the action.

Announce the outcome at the producer. hideSessionCatalog now names the section
that disappeared, offers Undo, and carries the Settings path in the toast text
for after it times out. The hidden-catalog set gets one owner,
setStoredSessionCatalogHidden, so the sidebar, the undo, and the Settings
toggle all mutate the same authoritative read instead of each rebuilding the
set from its own copy.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(ui): align the automation-sessions checkmark with its popover siblings

Every selection state in the sidebar sessions filter popover reads on the
trailing edge, but "Show automation sessions" used Web Awesome's
type="checkbox" checkmark, which its template renders before the label. The one
row in the menu that is a checkbox rather than a radio put its check on the
opposite side of the row from every neighbour.

Hide the leading part and render the shared session-menu__check in the details
slot, so the row matches GROUP BY / SORT BY / STATUS while Web Awesome keeps
owning the menuitemcheckbox role and aria-checked.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(ui): stop toasts from ellipsing away their recovery instruction

app-toast__message was nowrap + ellipsis, so any message longer than one line
lost its tail. That is fine for a bare acknowledgement and wrong for a toast
that tells the operator how to undo or where to re-enable something: the part
that gets cut is exactly the part they need.

Wrap instead, clamped to three lines so a pathological string still cannot grow
the toast without bound.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* refactor(ui): make the hidden-catalog writer module-private

With setStoredSessionCatalogHidden owning every hide/show, the raw
storeHiddenSessionCatalogIds writer no longer has a caller outside its own
module and the deadcode:exports gate flagged it. Drop the export rather than
keep a second public way to write the same preference, and move the two tests
that used it onto the owner they are actually meant to exercise.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(ui): anchor toasts to the bottom-right corner

Toasts were centered over the content column, which on chat routes puts a
passive notification directly on top of the composer. Move the shared
.app-toast container to the trailing bottom corner, the standard desktop
placement for passive notifications.

Anchoring it there alone would trade one overlap for a worse one: at a 20px
inset the toast lands exactly on the composer's mic and send controls. Chat
routes therefore lift it above the composer via --app-toast-inset-bottom on
.shell--chat, which the toast host inherits as a child of .shell. Routes
without a composer keep the tight 20px corner.

Phone widths keep the full-width bottom idiom, and now get it properly: the
centered toast used to collapse to its content width (200px measured at 390px
viewport), so the explicit left/right insets also widen it to 366px.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(ui): drop the chat-route toast lift

The corner toast no longer clears the composer on chat routes. Overlapping
the composer region is the accepted trade for one placement rule on every
route, so the route-specific 140px lift and its custom property are gone and
every surface uses the same 20px safe-area corner inset. Wrapped toast text
balances its lines now that the message can run to two.

* fix(ui): open the sidebar recovery path from its toast

Naming "Settings > Appearance > Sidebar" in the hide toast still left the
operator to find it. The recovery sentence is now a link built from the
settings-search destination that already describes that block, so the toast
opens the re-enable list instead of describing where it lives. Toast messages
accept a template for that.

* revert: leave the automation-checkmark repair to its own PR

#121429 fixes the same Web Awesome checkmark alignment on its own, with
browser regression coverage this branch does not carry. Two PRs owning one
CSS part is worse than losing the drive-by, so this keeps to the hide and
recovery invariant.

This reverts commit 6b1438a5be4bb1c9dd4c2ce9cd7d0dd54e77cb00.

* fix(ui): let the hide outcome reach a phone operator

On a phone the sidebar only exists inside the navigation drawer, and that
drawer is a modal dialog: a toast raised behind it is both occluded and inert,
so hiding a section there stayed exactly as silent as before this branch.
Promoting the toast into the top layer only fixes the paint half — a modal
dialog inerts everything outside it, so Undo and the recovery link still take
no clicks. So the hide hands the drawer back to the shell first, through a
seam the sidebar can use for any outcome that belongs on the main surface.
It is a no-op wherever the drawer is not open.

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 03:41:48 -03:00
Peter Steinberger f37507cac2 test(macos): keep mocked gateway probe routes off the operator identity store (#121398) 2026-08-09 23:36:22 -07:00
Peter Steinberger 9d77e5c3b7 feat(ui): move chat view toggles into a header session menu (#121452)
* feat(ui): move chat view toggles into a header session menu

Control UI: replace the chat composer eye-icon View dropdown with a Claude Desktop-style three-dot session menu at the far right of the chat pane header. The menu adds Open in for editor/worktree sessions, Rename, the three display toggles under View, Fork, Archive/Restore with undo, and Delete with confirmation.

Reuse the sidebar session-organizer actions through a narrowed SessionActionHost seam, consolidate session permission gating in sessionMenuReasons, and remove the obsolete composer menu state, dismissal handling, tests, and CSS.

* test(ui): update header session menu e2e interactions
2026-08-09 23:35:55 -07:00
Peter Steinberger 17bea1136f fix(ui): recover GitHub previews when GitHub auth is stale (#121454)
* fix(ui): recover GitHub previews from stale auth

* fix(ui): keep GitHub preview helpers internal
2026-08-09 23:35:02 -07:00
Peter Steinberger 23d1eca455 refactor(sessions): enforce transcript writer fence in sqlite sync ops (#121316)
Fold the writer-claim fence into the four sync write ops at their
definition sites, collapse the logical-layer fence wrappers to plain
re-exports, delete the session-accessor.sqlite middle barrel (the only
unfenced escape hatch), and retarget its 26 importers to the focused
defining modules. replaceSessionEntrySync intentionally stays unfenced:
its two production callers own their freshness guards and its return
carries no rebound signal. Net -106 production LOC, behavior-neutral.
Part 1 of the session-accessor dual-layer collapse.
2026-08-09 23:16:57 -07:00
Peter Steinberger 627e5bb063 refactor(outbound): split message action runner by concept (#121434)
* refactor(outbound): split message-action-runner into concept modules

* refactor(outbound): delete forwarding and duplicate collectors

* chore(lint): ratchet max-lines baseline after message-action split
2026-08-09 23:11:32 -07:00