Commit Graph

77912 Commits

Author SHA1 Message Date
Peter Steinberger c39abcecda fix(security): report DM isolation from effective routing (#121741)
* fix(security): audit effective DM session ownership

Resolve admitted DM principals through canonical route, account, identity-link, and channel-owned session policy before reporting shared-session risk. Doctor now renders the structured channel security owner instead of duplicating the global-only default-account heuristic.\n\nCloses #121711

* chore(plugin-sdk): refresh API contract baseline

* fix(telegram): preserve direct peer SDK export

* fix(telegram): preserve direct peer resolver signature

* fix(ci): use supported DM audit grouping

* fix(protocol): refresh approval reviewer Swift models
2026-08-10 15:34:37 -07:00
Peter Steinberger cf432ec871 fix(media): keep file-store keys portable 2026-08-10 15:33:06 -07:00
Peter Steinberger 877e9831b9 fix(ci): refresh generated Swift protocol models (#121746) 2026-08-10 15:23:29 -07:00
Peter Steinberger 5fb5eefa61 refactor(cloud-workers): centralize placement lifecycle fences (#121658)
* refactor(cloud-workers): centralize placement ownership fences

Amp-Thread-ID: https://ampcode.com/threads/T-019feaaa-c7ed-769e-9f29-a3612bec72e7

* test: restore core test typechecking

Amp-Thread-ID: https://ampcode.com/threads/T-019feaaa-c7ed-769e-9f29-a3612bec72e7

* test: repair current-main CI regressions

Amp-Thread-ID: https://ampcode.com/threads/T-019feaaa-c7ed-769e-9f29-a3612bec72e7

* test: align shared main contracts

Amp-Thread-ID: https://ampcode.com/threads/T-019feaaa-c7ed-769e-9f29-a3612bec72e7

* docs(cloud-workers): document placement fence

Amp-Thread-ID: https://ampcode.com/threads/T-019feaaa-c7ed-769e-9f29-a3612bec72e7

* test(approvals): align account routing fixtures

Amp-Thread-ID: https://ampcode.com/threads/T-019feaaa-c7ed-769e-9f29-a3612bec72e7

* fix(protocol): refresh Swift approval resolve models

Amp-Thread-ID: https://ampcode.com/threads/T-019feaaa-c7ed-769e-9f29-a3612bec72e7

* test(approvals): use scoped event kind fixtures

Amp-Thread-ID: https://ampcode.com/threads/T-019feaaa-c7ed-769e-9f29-a3612bec72e7

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-10 15:15:24 -07:00
Peter Steinberger 1263450938 improve: start fresh gateways without migration overhead (#121639)
* Optimize fresh gateway startup migrations

* Fix startup optimization CI gates

* Fix compact startup CI coverage

Amp-Thread-ID: https://ampcode.com/threads/T-019fec00-3abd-710b-b9de-8925c23ad779

* Fix stale managed image CI coverage

* Fix stale model setup route expectation

* Fix setup admission lint

* Fix system agent setup test isolation

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-10 15:01:37 -07:00
Peter Steinberger d230a4ac9f test(sqlite): preserve publication identity in fault injection 2026-08-10 14:59:25 -07:00
Peter Steinberger 0ca0781fec test(approvals): align plugin runtime event kinds 2026-08-10 14:57:25 -07:00
Peter Steinberger 8ae273603d test(commands): align learn prompt invariants 2026-08-10 14:57:25 -07:00
Martin Cleary e0a4146f55 fix(ci): carry branch authority to ClawSweeper (#121674)
Co-authored-by: brokemac79 <255583030+brokemac79@users.noreply.github.com>
2026-08-10 22:50:44 +01:00
Patrick Erichsen 105038e658 ci: mirror Docker release images to Vercel registry (#120058)
* ci: publish release images to Vercel registry

* ci: publish beta images to Vercel registry

* fix(ci): allow beta Vercel dispatch

* fix(ci): publish VCR-compatible image indexes

* fix(ci): allow VCR readiness propagation

* fix(ci): use Sandbox as VCR readiness proof

* fix(ci): promote clean VCR channel indexes

* fix(release): harden VCR publication

* fix(release): bind VCR publishing to verified inputs

* fix(test): follow script declaration migration

* fix(release): isolate VCR mirroring

* test(release): align VCR secret ownership
2026-08-10 14:45:05 -07:00
Peter Steinberger db879e73fa fix(ci): heal dead-export scan and refresh plugin-sdk baseline
collection-rollback's directory helper lost its external caller in
bdf202ccc8 — make it local; register collection-review's focused-test
seam per the knip ignoreIssues convention; regenerate the API baseline
after recent harness/channel contract drift.
2026-08-10 14:34:54 -07:00
kevinlin-openai 8e91d6c0c1 fix(codex): let code-mode-only models discover deferred tools (#121703)
* fix(codex): let code-mode-only models discover deferred tools

* test(codex): refresh deferred tool prompt snapshots

* test: expose prompt snapshot drift context

* test: pinpoint prompt snapshot drift

* test(codex): sync deferred tool prompt metadata

* test(codex): refresh rebased heartbeat metadata
2026-08-10 14:15:06 -07:00
Peter Steinberger 2205c5df28 test(approvals): align native route selection semantics 2026-08-10 14:13:18 -07:00
Peter Steinberger 40817435e8 fix(architecture): split cyclic runtime contracts 2026-08-10 14:13:18 -07:00
Peter Steinberger aeeacd9565 fix(test): align approval gateway request mock type 2026-08-10 14:13:18 -07:00
Peter Steinberger 2990b7b238 test(sqlite): stop forwarding lstat options in snapshot inspection mock
Reverts the arg-forwarding change from #121696: forwarding bigint options
shifts which publication-identity lstat the injected EIO lands on, and on
Windows the snapshot fails with 'publication source identity did not
match' instead of the inspection failure under test, breaking
checks-windows-node-test deterministically. Restore the previously
Windows-green single-argument forwarding with a comment explaining why.
2026-08-10 13:54:44 -07:00
Ayaan Zaidi bdf202ccc8 feat(skills): reconcile learned skill collections (#121653)
Replace divergent per-skill curation with one daily isolated collection review that can consolidate, rewrite, create, and drop writable skills atomically.

Autonomous auto mode remains automatic. Adds bounded review, transactional recovery, durable cadence, shared locking, and reuse-first /learn behavior.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-11 02:06:26 +05:30
Peter Steinberger 39b9d7b1a1 fix(ci): heal main formatting and worker-registry import cycle
approval.ts was pushed unformatted; worker-provider-registry.ts pulled the
full OpenClawConfig graph back into the plugins layer — use the
CloudWorkersConfig leaf instead.
2026-08-10 13:32:36 -07:00
Peter Steinberger 0b0d9f5811 fix(ui): prevent terminal garble after Gateway reconnect (#121637)
* fix(ui): recreate terminal runtime after replay gaps

Replace Ghostty's in-place reset with a fresh controller/runtime for authoritative recovery replay so Gateway reconnects cannot expose stale WASM terminal state. Preserve replay ordering, focus and tab visibility, and dependency cleanup.\n\nFixes #121636

* test(ui): fix terminal replay type coverage

* fix(ci): repair current-main validation blockers

* test(discord): align progress fixtures with callbacks

* fix(ui): restore focus after cancelled terminal replay

* chore(ci): drop superseded baseline fixups

* fix(ui): stage terminal replay replacements safely

* fix(ui): serialize asynchronous terminal replay

* fix(ui): guard superseded terminal replay recovery

* fix(ui): invalidate superseded terminal replay callbacks

* fix(ui): keep staged terminal replay inert
2026-08-10 13:27:28 -07:00
Peter Steinberger 29ab80f185 fix(update): record verified install receipts even when the handoff fails (#121664)
A campaign apply that succeeds at the git level but fails its managed-service
handoff (e.g. a post-restart health-probe false negative under SQLite load)
marked the update sentinel "error", so the #121328 receipt-backed upstream
fallback never engaged and dev campaigns stalled silently on "no-upstream"
until manual branch re-attach. The receipt now records the install fact
proven by the running process (git mode, root + revision verified, install
changed) regardless of sentinel status; the reader and store drop their
redundant success gates; the concept is renamed Successful* -> Verified*.
Receipt writes are scoped to git mode (the only mode ever read), so dead
npm-mode rows can no longer clobber a valid git receipt.

Fixes #121634
2026-08-10 13:27:10 -07:00
Peter Steinberger 9a0ea5d69b fix: finish completed tool work after empty final responses (#115104)
* fix(agents): record completed-empty finalization

* test(agents): align settled finalization outcome assertion
2026-08-10 13:24:11 -07:00
Peter Steinberger fd96df8d86 test(agents): trim duplicate fault sequence (#121718) 2026-08-10 13:23:50 -07:00
Vyctor H. Brzezowski 20d928e3c3 fix(ui): name new session groups in an owned dialog instead of a browser prompt (#121249)
* fix(ui): name new session groups in an owned dialog

Sidebar Move to group -> New group and the Sessions page New group action collected the group name with window.prompt, so the only text-entry step in that flow was browser chrome: unthemed, unvalidated, and unable to keep the typed name when the create was rejected.

Adds showPromptDialog next to the existing showConfirmDialog helper and routes both new-group surfaces through it. createSessionGroup now reports its mutation result so a rejected create keeps the dialog and its value for a retry.

* fix(ui): keep the prompt dialog usable when its operation throws

A rejected submit left the field disabled and the module-level guard latched, so every later prompt in the session was dropped. Report the thrown error as the visible failure instead.

* refactor(ui): keep the prompt dialog options type module-local

Nothing outside prompt-dialog.ts consumes the options type, and the deadcode export gate rejects unused public surface.

* fix(ui): keep the new-group catalog write and assignment on one scope

rememberSessionCustomGroup discarded whether its connection was still current, so a groups.put that outlived its connection was followed by a sessions.patch issued on the replacement one. It now reports completed/failed/stale like the sidebar catalog write, and the Sessions page threads one captured scope through both writes.

* refactor(ui): name new session groups through the shared input dialog

input-dialog.ts already owns Control UI text entry, so the new-group flow no
longer ships a second near-identical dialog next to it. showInputDialog gains
two additive options instead:

- requireValue trims the entry and holds submission closed while it is blank,
  replacing the ?.trim() bail every prompt call site repeated. Rename keeps it
  off, because an empty rename still has to clear a custom label.
- submit runs the operation behind the dialog and keeps it open on failure with
  the typed value intact, so a rejected create is correctable rather than
  retyped. The Gateway rejects a group name over 512 characters, and that
  message now reaches the operator without discarding what they wrote.

The input stays uncontrolled: its value binding is constant, so repaints for the
submit and failure states leave the caret and IME composition alone. The
AbortSignal contract and the reentrancy guard are unchanged.

Both catalog writes also honor the result groupsPut returns. The capability
retires a write on its own connection epoch, which the caller's scope predicate
cannot observe, so discarding it could file a session into a group no live
connection ever confirmed.

* fix(ui): survive a submit callback that throws before it returns

The catch was attached to the returned promise, so a non-async callback that
threw during synchronous validation escaped it: the rejection left submitting
latched, every control disabled, escape blocked, and the module-level guard held
for the rest of the session. The call now happens inside the try.

Also aligns the shared sidebar harness with the catalog contract. groupsPut
resolved undefined while its groupsRename and groupsDelete siblings already
resolved "completed", so the harness disagreed with the capability it stands in
for as soon as the caller started reading that result.

* fix(ui): do not recreate a session that vanished during the catalog write

Awaiting the group catalog write before the assignment opens a window in which
the target row can be deleted. sessions.patch creates a store entry for an
unknown key, so the assignment would resurrect the session the operator just
removed. assignCategory already guards its own patch this way; the new-group
path now does the same.

* test(ui): widen the empty session-list cast for the vanished-row case

* fix(ui): re-resolve sidebar group targets before assigning them

The new-group dialog no longer blocks, so the rows captured when the menu opened
can be deleted while the catalog write is in flight. sessions.patch creates a
store entry for an unknown key, so assigning them would resurrect the sessions
the operator just removed. The Sessions-page path already guards this; the
sidebar now re-resolves every target against the current list before patching.

* refactor(ui): load the input dialog behind one lazy boundary

input-dialog.ts was imported statically by the Sessions page and dynamically by
the sidebar controller. Mixing both for one module makes the dynamic import
ineffective and pulls the dialog into a startup chunk that never needs it until
an operator opens a menu. All four call sites now share the lazy boundary.

* fix(ui): keep a stale group submission open for retry

A Gateway connection replaced mid-write confirmed neither the group nor the
move, but both surfaces mapped that outcome to a silent close: the dialog
vanished and the typed name went with it, leaving nothing on screen to explain
why no group appeared. Both now report a retryable message so the entry stays
put and resubmitting runs against the replacement connection.

The row-vanished path still closes: there the group did land, and only the
assignment was skipped.

* fix(ui): close the input dialog when its owner goes away

The dialog mounts on document.body, so navigating away left it over the
destination with a detached owner, and a later submit ran against a page that
had already torn down its subscriptions. Both the Sessions page and the sidebar
controller now hand it a lifecycle AbortSignal and abort on disconnect, using
the option the component already accepted.

* fix(ui): prove the target session when a delayed patch lands

The new-group assignment guarded itself by asking whether the row was still in
the current list. That list is a bounded, filtered projection, so an ordinary
refresh that pages a row out of view read as a deletion and silently dropped a
legitimate move, while a row that was genuinely replaced still looked present.

Both surfaces now carry the identity captured when the operator acted, and the
Gateway decides: sessions-patch-engine compares expectedSessionId against the
stored entry and refuses a changed target, so a patch can neither land on a
successor session nor recreate one that is gone. The projection guards are
removed rather than kept alongside it.

SessionPatch and the sidebar patchMany targets carry the field, and
SidebarRecentSession keeps the sessionId its rows already had from the Gateway,
so every sidebar mutation the operator starts before a replacement is covered,
not just group creation.

* fix(ui): make the dialog's lazy boundary safe to await

Three races opened up when the dialog moved behind a dynamic import.

The Sessions page read the target's identity after awaiting the chunk, so a
refresh during a cold load handed back whichever row had replaced it and the
identity guard then approved the wrong session. The lookup now happens before
any await.

The lifecycle was armed only after the chunk resolved, so a sidebar that
disconnected mid-import left nothing for hostDisconnected to abort and the
dialog opened behind a dead host. The import now runs inside the lifecycle.

A rejected chunk load produced no dialog, no error and an unhandled rejection at
the void callers. Both surfaces now report it where they report their other
failures.

* test(ui): make the sidebar projection case prove the assignment

The case waited on a condition that was already true before the catalog write
landed, so it returned before the continuation reached patchSessions and its
negative assertions passed without exercising anything. It also still claimed
the old behaviour: rows leaving the projection now do not suppress the
assignment, because a bounded, filtered list is not evidence of deletion.

It now waits for the batch itself and asserts each target carries the identity
captured with its row, which is what lets the Gateway refuse a replaced target.

* test(ui): split the sidebar new-group cases out of interactions

Adding the projection case pushed interactions.ts past the 700-line ceiling.
The multi-select helpers move to multi-select-support.ts so both files share one
definition, and the two new-group dialog cases get their own case module beside
the other per-topic sidebar suites.

No behaviour change: 246 sidebar cases still pass, and interactions.ts drops to
well under the limit without a suppression.

* fix(ui): stop cancelling the sidebar dialog on a re-layout

The compact-viewport E2E caught this: at 420px the sidebar is dropped from the
DOM, which fired hostDisconnected and aborted the open dialog, so resizing the
window mid-edit closed it and discarded the typed name — the same silent loss
this PR set out to remove.

A sidebar detach is not the operator leaving. The dialog is a body-level modal
and outlives the sidebar's DOM position by design, so the controller no longer
tears it down. The Sessions page keeps its binding, where a page unmount really
is a navigation.

* style(ui): format the extracted sidebar multi-select helpers

* fix(ui): keep the live dialog abortable when a second open overlaps

Two fire-and-forget new-group actions during the lazy import both installed a
lifecycle controller. showInputDialog drops the reentrant request, but the
second call still cleared the field on its way out, so the dialog actually on
screen was left with nothing for disconnect to abort and survived navigation.

A second open now reuses the active controller instead of taking ownership, and
a regression case overlaps two opens then detaches the page.

* refactor(ui): defer session-identity plumbing to its own change

The new-group dialog work had grown a second, separable concern: threading the
identity of the row the operator acted on through SessionPatch, the sidebar
patchMany targets and SidebarRecentSession, so the Gateway could refuse a patch
whose session had been replaced. That contract is real and already enforced by
server-methods/sessions-patch-engine.ts, but it reaches every session mutation
the sidebar makes rather than group creation alone, and a rejected identity
still needs its own terminal outcome before it helps an operator. It belongs in
a change that can be judged on those terms.

Both surfaces return to the projection-presence guarantee this change shipped
first: captured rows are re-resolved against the current list and an assignment
whose row is gone is skipped, which is what keeps sessions.patch from recreating
a session the operator just deleted.

The sidebar case covering that keeps the waiting fix it gained meanwhile. It now
waits for the dialog to be removed, which happens only once the submit chain has
run, instead of for a condition that was already true before the catalog write
landed and let the negative assertions pass without exercising anything.

* fix(ui): say when a new group landed without its move

Both new-group paths skip the assignment when the captured row is no longer in
the current list, because sessions.patch would otherwise recreate a store entry
for a session the operator had removed. That guard was silent: the dialog closed
on the same "completed" a full success returns, so an operator whose list had
simply refreshed or paged got a new group, an unmoved session, and nothing that
accounted for the difference.

The list is a bounded, filtered projection, so a row leaving it is not proof the
session is gone. The skip stays — it is the safe choice without the target's
identity — but it now ends in a visible outcome. The Sessions page records the
partial result in its own error surface and closes; the sidebar raises a toast,
singular or plural with the rows the operator selected. Both are terminal rather
than retryable: the group already exists, so resubmitting the same name could
only fail.

A header-created group still starts empty with no notice, since nothing was
requested to move.

* fix(ui): tighten the skipped-move notice

The two-string singular/plural pair pushed the Control UI startup bundle past
its gzip ceiling: the catalog is loaded at startup, so long copy is paid for on
every page load, and the check failed by 41 bytes.

One string covers both surfaces and both counts. It still states the outcome and
the next step, which is what the notice is for, and it drops the count branch in
createSessionGroup along with the second key.

* test(ui): split the new-group case out of the groups e2e file

The groups e2e file crossed the 1000-line ceiling for test files once this
branch's new case landed on top of the growth main had already added, and a
max-lines suppression is not an option here.

The owned-dialog case moves to its own file beside it, matching the split the
sidebar cases already got. It keeps the same shared helpers, so the move is
mechanical, and it leaves the groups file with room for the cases that stay.

* fix(ui): report sidebar group moves that were skipped

Re-resolving the selection against the live list stopped a removed row from
being recreated, but only the all-removed case reached the operator. When part
of a multi-row selection left the list while the catalog write was in flight,
the survivors were patched and the call returned a plain success, so the dialog
closed with the group created, some sessions moved, and nothing saying the rest
were not.

The count comparison now covers the partial case: the surviving subset is still
patched, and whenever fewer rows resolve than were requested the skipped outcome
is named. It stays terminal, since the group already exists and retrying would
only recreate it.

The Sessions-page path takes a single optional key, so all-or-nothing is the
only shape it has and it already reports the skip; the sidebar is the surface
with a multi-row selection to partially satisfy.
2026-08-10 17:16:16 -03:00
Peter Steinberger 7ec87b87e7 fix(agents): honor exec policy in Claude live sessions (#121678) 2026-08-10 13:15:39 -07:00
Peter Steinberger 59d545d81f fix(gateway): fence session worktree lifecycle (#121666)
Same-key replacement sessions no longer retain a managed worktree that predecessor deletion can remove.
2026-08-10 13:13:04 -07:00
Ayaan Zaidi 9935ca3b30 fix(approvals): bind native requests to channel accounts (#121673)
Native approval delivery and resolution now stay bound to the originating or explicitly targeted channel account. Unbound requests fail closed across multiple eligible accounts; trusted reviewer-less SDK callers remain compatible.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-11 01:42:41 +05:30
Peter Steinberger aa2a0006b1 docs(config): refresh generated baseline hash (#121714) 2026-08-10 13:12:01 -07:00
Peter Steinberger 9edc531244 perf(agents): ship one automations job schema for add and update (#121645)
The automations tool shipped two near-duplicate ~1.4k-token object schemas
(job for add, patch for update) in every prompt on the default tool path —
13,016 chars of tool schema, 88% of it the duplicated pair. One nullable
object schema now serves both actions (7,864 chars, ~1.3k tokens saved per
prompt): update reads the job parameter, and the add path strips null
clears before the strict gateway cron.add contract while preserving the
agentId/sessionKey nulls that cron.add accepts.

Fixes #121606
2026-08-10 13:05:30 -07:00
Vyctor H. Brzezowski 71cf5cf704 fix(gateway): keep chat history visible past a silent raw tail (#121337)
The bounded raw tail window that chat.history reads can be filled entirely
by records that project to nothing (tool traffic, hidden memory-flush
prompts, dropped silent turns, or one oversized record). The first page then
came back empty even though the branch still held visible turns, and every
snapshot client rebuilds destructively from that page, so the TUI wiped a
conversation the transcript still had.

Scan older transcript chunks when the first page projects to no display
rows, bounded in records and bytes so a pathological transcript cannot turn
the tail read into a full scan, project each chunk beside the newer records
it borders so paired rows survive a chunk boundary, and report the scanned
record count so older paging still resumes strictly before the served page.
2026-08-10 17:00:09 -03:00
Peter Steinberger 97bd54ded7 fix(sessions): prevent failures and stale state under rapid use (#121680)
* fix(sessions): harden lifecycle reliability and listing speed

Amp-Thread-ID: https://ampcode.com/threads/T-019febfb-f949-77cd-b15b-d31d0b42d2fb

* test: repair strict type fixtures

Amp-Thread-ID: https://ampcode.com/threads/T-019febfb-f949-77cd-b15b-d31d0b42d2fb

* chore(plugin-sdk): refresh current main API baseline

Amp-Thread-ID: https://ampcode.com/threads/T-019febfb-f949-77cd-b15b-d31d0b42d2fb

* fix(ci): repair current-main validation blockers

Amp-Thread-ID: https://ampcode.com/threads/T-019febfb-f949-77cd-b15b-d31d0b42d2fb

* test(cron): preserve upstream assertion order

Amp-Thread-ID: https://ampcode.com/threads/T-019febfb-f949-77cd-b15b-d31d0b42d2fb

* fix(gateway): settle setup admission test sessions

Amp-Thread-ID: https://ampcode.com/threads/T-019febfb-f949-77cd-b15b-d31d0b42d2fb

* test(ui): sample wizard action geometry atomically

Amp-Thread-ID: https://ampcode.com/threads/T-019febfb-f949-77cd-b15b-d31d0b42d2fb

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-10 12:58:59 -07:00
Peter Steinberger 810c3510ee fix: reject invalid memory parents and trim test facades (#121696)
* test(scripts): trim dead testing facades

* test(memory): align non-directory path contract

* test(discord): drop stale progress callback ids

* fix: repair current main validation failures

* fix(gateway): remove redundant setup admission generic

* test(gateway): await setup admission settlement
2026-08-10 12:58:30 -07:00
Peter Steinberger 084ed7f04b fix(ui): stabilize mobile drawer focus E2E (#121663)
* test(ui): await native drawer focus settlement

* test(ui): distinguish browser chrome focus
2026-08-10 12:56:19 -07:00
Peter Steinberger e63bd3e9a4 fix: make gateway stress results reflect real concurrency (#121677)
* fix(qa): preserve gateway rpc concurrency

Amp-Thread-ID: https://ampcode.com/threads/T-019fec02-d170-73eb-aec8-b364ab706745
Co-authored-by: Peter Steinberger <steipete@gmail.com>

* fix(agents): clean detached session lifecycle

Amp-Thread-ID: https://ampcode.com/threads/T-019fec02-d170-73eb-aec8-b364ab706745
Co-authored-by: Peter Steinberger <steipete@gmail.com>

* fix(gateway): classify metadata startup sequencing

Amp-Thread-ID: https://ampcode.com/threads/T-019fec02-d170-73eb-aec8-b364ab706745
Co-authored-by: Peter Steinberger <steipete@gmail.com>

* fix(types): heal main test typecheck

Amp-Thread-ID: https://ampcode.com/threads/T-019fec02-d170-73eb-aec8-b364ab706745
Co-authored-by: Peter Steinberger <steipete@gmail.com>

* fix(qa): type gateway rpc request mock

Amp-Thread-ID: https://ampcode.com/threads/T-019fec02-d170-73eb-aec8-b364ab706745
Co-authored-by: Peter Steinberger <steipete@gmail.com>

* fix(qa): preserve terminal transport state

Amp-Thread-ID: https://ampcode.com/threads/T-019fec02-d170-73eb-aec8-b364ab706745
Co-authored-by: Peter Steinberger <steipete@gmail.com>

* test(gateway): allow qa transport owner

Amp-Thread-ID: https://ampcode.com/threads/T-019fec02-d170-73eb-aec8-b364ab706745
Co-authored-by: Peter Steinberger <steipete@gmail.com>

* test(ui): isolate attachment handoff lifecycle

Amp-Thread-ID: https://ampcode.com/threads/T-019fec02-d170-73eb-aec8-b364ab706745
Co-authored-by: Peter Steinberger <steipete@gmail.com>

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-10 19:54:55 +00:00
Peter Steinberger 8a5978154f fix(ui): handle keyboard context menu shortcuts (#121628)
* fix(ui): handle keyboard context menu shortcuts

* fix(ci): repair shared validation regressions

* fix(ci): repair setup admission lint

* fix(ci): settle setup admission tests
2026-08-10 12:39:22 -07:00
Peter Steinberger f8916e4eb2 test(gateway): await setup admission cleanup 2026-08-10 12:33:32 -07:00
Peter Steinberger 620ca5f008 fix(lint): drop single-use type parameter in wizard settlement helper
Heals main check-lint: f3e1efead4 introduced a generic used only once,
tripping typescript/no-unnecessary-type-parameters.
2026-08-10 12:24:11 -07:00
Peter Steinberger 55afad26c0 test(ci): align owner and lifecycle expectations 2026-08-10 11:47:43 -07:00
Peter Steinberger 519c8ed38d fix(ui): align managed image preview contracts 2026-08-10 11:47:43 -07:00
Peter Steinberger f3e1efead4 fix(gateway): settle setup admission with wizard sessions 2026-08-10 11:47:42 -07:00
Peter Steinberger 21e7f200aa test(cron): align alert assertions with generic failure messages 2026-08-10 11:35:13 -07:00
Peter Steinberger 940373909f fix(session-memory): delimit transcript text (#98574)
Co-authored-by: SunnyShu <shu.zongyu@xydigit.com>
2026-08-10 11:05:13 -07:00
Colin Johnson 86fe45ce17 fix(control-ui): scale sidebar text with appearance setting (#121087)
Scales Control UI sidebar and navigation text with the existing Appearance preference while preserving mobile input zoom safety and bounded session-count layout.

Prepared head SHA: bafb9a2b74
Co-authored-by: Colin Johnson <211764741+Solvely-Colin@users.noreply.github.com>
Co-authored-by: Shakker <165377636+shakkernerd@users.noreply.github.com>
Reviewed-by: @shakkernerd
2026-08-10 18:29:23 +01:00
Peter Steinberger aa33c63c5b chore(lint): clear sort mutation, spread fallback, and error-cause findings
toSorted/flat in the labeler coverage test, drop no-op empty-object spread
fallbacks in the telegram command-menu e2e config, and attach the caught
cause when rewrapping the trusted-workflow parse error.
2026-08-10 10:25:31 -07:00
Peter Steinberger 4e5029e43b fix(ci): repair test-type breakage from generated image actions
The image-actions feature landed with an untyped fetch spy and an unknown
URL argument; newer vitest types surface both. Capture anchor downloads via
a typed mock implementation and coerce the probed block URL. Also add the
toolCallId/itemId fields to the Discord harness's stale local copies of the
onToolStart/onCommandOutput payload types (canonical type already has them).
2026-08-10 10:25:31 -07:00
Peter Steinberger 3d2f134d16 chore: refresh Plugin SDK API baseline (#121670)
Co-authored-by: Amp <amp@ampcode.com>
2026-08-10 10:18:33 -07:00
Peter Steinberger b2bb148407 fix(types): heal package acceptance checks 2026-08-10 09:55:54 -07:00
Peter Steinberger 511db367fe fix(lint): preserve release validation parse cause 2026-08-10 09:55:54 -07:00
Peter Steinberger 2d06d46c89 fix(ci): restore missing extra-path reads 2026-08-10 09:55:54 -07:00
Peter Steinberger 63776cf5a0 fix(mcp): honor Windows PATH key casing in doctor (#121595) 2026-08-10 09:55:41 -07:00
Marvinthebored 01884775aa fix(context-engine): preserve fresh-turn engine selection (#121461)
Keep configured engines selected before the current turn is persisted, then durably advance accepted turns across embedded and CLI paths. Preserve runtime plugin ownership and canonical transcript anchors through prepared execution.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Co-authored-by: Peter <noreply@anthropic.com>
2026-08-10 22:23:24 +05:30