Commit Graph

11440 Commits

Author SHA1 Message Date
Peter Steinberger 6dc77a37d9 refactor(agents): render failover user copy from one reason-keyed module (#121717)
* refactor(agents): centralize failover user copy

* refactor(agents): route failure callers through user copy

* refactor(qa): carry typed reply failure markers

* refactor(agents): keep failover copy import-light

* refactor(agents): pass structured failure copy context

* refactor(agents): isolate copy rendering from runtime state

* refactor(agents): separate copy rendering from sanitization

* refactor(agents): keep failover copy internals private

* fix(qa-channel): type failure markers on bus sends

* style(agents): brace failover copy conditions

* test(qa-lab): avoid map spread in failure cases

* chore(plugin-sdk): refresh failover closure hashes

* fix(agents): preserve generic runner fallback

* fix(qa): preserve text-only failure markers

* test(qa): type failure delivery fixture
2026-08-10 16:43:51 -07:00
Peter Steinberger 96b0cf95ef fix(gateway): restore restart preflight compatibility (#121757)
* fix(gateway): restore restart preflight compatibility

* ci(protocol): preserve restored method vintages

* chore: defer compatibility note to release
2026-08-10 16:43:27 -07:00
Peter Steinberger 59492c51a5 feat(agents): rename spawn_task tool to suggest_task (#121694)
* feat(agents): rename spawn_task tool to suggest_task

Models across vendors read the name spawn_task as 'starts background
work' and refuse to call it when the user has not asked to start
anything (Claude Sonnet 5, verbatim: 'spawn_task (which actively starts
background work)... Since you didn't ask me to start work, I'm flagging
this as a follow-up instead'). The tool only records a suggestion card,
so the name defeated the feature.

Rename the model-facing tool to suggest_task everywhere (catalog,
descriptors, presets, display config, OpenClawKit tool-display, docs)
and migrate persisted operator state via doctor: config tool policies
and cron SQLite toolsAllow entries that reference spawn_task are
rewritten to suggest_task. No runtime alias remains; runtime exposes
only the canonical name.

Live clean-room matrix on a dev gateway (virgin session per cell):
suggested-task-card phrasing now yields exactly one card on
anthropic/claude-sonnet-5, claude-haiku-4-5, openai/gpt-5.6-sol,
gpt-5.6-luna, and google/gemini-3.1-pro; pre-rename the same bait
produced prose-only follow-ups.

* chore(doctor): keep legacy tool-name predicate module-local

isLegacyTaskSuggestionToolName has no external consumers; the exported
form tripped the knip unused-export gate (deadcode:exports).

* fix(doctor): keep tool-name migration out of plugin-owned config

The rename migration traversed the whole raw config, so any object
carrying a toolsAllow key was rewritten - including opaque
plugins.entries.*.config, which core must not mutate. Scope the apply
pass to the typed core roots (tools, agents, channels, gateway) and pin
plugin config preservation in the test. Plugin-owned tool lists migrate
via the owning plugin's doctor contract instead.

* fix(ci): heal main deadcode and stale Swift protocol mirror

Unrelated main breakage blocking this PR's merge gate, healed here per
landing policy:

- #121653 left dead exports in src/skills/workshop: make
  removeSkillCollectionDirectory and SkillCollectionRestoreResult
  module-local; register collection-review.ts under the documented knip
  ignoreIssues test-only-export convention (production runs it via the
  scheduled maintenance loop).
- #121673 added ApprovalResolveParams.reviewer without regenerating the
  Swift mirror; regenerate GatewayModels.swift (additive only).

* fix(ci): satisfy generic approval-runtime request signature in resolver test

Third main-heal carried by this PR: #121673 (9935ca3b30) left the
scoped-request mock's concrete inferred type unassignable to the generic
GatewayNativeApprovalRuntime request signature, breaking check-test-types
on main. Cast the mock at the runtime literal; assertions keep the Mock.

* chore(ci): drop approval-test cast superseded by main's typed mock rewrite

* chore(ci): drop duplicate knip entry superseded by main's heal
2026-08-10 16:41:39 -07:00
Peter Steinberger f09a33ce41 Optimize OpenAI turn latency and simplify reuse (#121687)
Amp-Thread-ID: https://ampcode.com/threads/T-019fe95b-d75c-70fc-82b6-4825ca874826

Co-authored-by: Amp <amp@ampcode.com>
2026-08-10 16:23:06 -07:00
Peter Steinberger 1ced7441eb refactor(agents): move announce, completion, recovery, and registry families into concept directories (#121553)
* refactor(agents): move announce family into subagents/announce/

* refactor(agents): move completion and main-session recovery families

* refactor(agents): move registry family into subagents/registry

* refactor(agents): update registry state type imports

* style(agents): format moved subagent imports

* test(agents): preserve isolated registry test routing

* fix(scripts): recognize relocated subagent announce seams
2026-08-10 16:06:39 -07:00
Peter Steinberger a770218518 refactor: consolidate duplicate helpers (#121431)
* refactor(agents): consolidate session slug creation

* refactor(commands): consolidate config validation

* refactor(infra): consolidate stale pid termination

* refactor(tui): reuse canonical sleep helper

* chore(scripts): burn resolved entries from collision baseline

* fix(refactor): preserve cross-platform helper contracts

* fix(plugin-sdk): keep approval helper private

* chore(scripts): burn resolved wrapper shadowing entry

* chore(scripts): refresh wrapper shadowing baseline

* test(agents): target canonical session slug helper

* chore(plugin-sdk): refresh API baseline
2026-08-10 15:57:24 -07:00
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 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
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
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 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 87475758dc fix(cloud-workers): retry timed-out dispatches without reprovisioning (#121616)
* fix(cloud-workers): coalesce dispatch retries

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

* chore: lower environment variable count budget

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

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-10 09:17:17 -07:00
Ayaan Zaidi 4c951398ef fix(messages): keep runtime details out of chat alerts (#121600)
Keep raw commands, paths, and provider errors out of ordinary chat while preserving explicit raw diagnostics and structured admin history.

Default command progress is status-only; `/verbose full` and `commandText: "raw"` retain diagnostic detail.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-10 21:37:48 +05:30
Ittiz bad30d5a74 feat(ui): add generated image actions (#77017)
Give Control UI managed images bounded previews and shared full-image Open, Download, and Copy actions. Keep artifact access transcript-bound; the existing ticket is intentionally attachment-scoped to the lower-fidelity thumbnail.

Co-authored-by: Ittiz <github@daein.org>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-10 21:30:58 +05:30
Peter Steinberger 5e5cf67314 chore(plugin-sdk): refresh API baseline closures (#121640) 2026-08-10 08:45:29 -07:00
Peter Steinberger a0ad38e71a feat(docs-ci): validate docs config examples against the schema (#121336)
* feat(docs-ci): validate config examples against schema

* docs: teach canonical agent roster configuration

* docs: nest inline environment variables under vars

* docs: update canonical media model keys

* docs: remove retired config keys from examples

* fix(docs-ci): keep audit internals private

* feat(docs-ci): validate plugin-owned config examples

* fix(docs-ci): validate indented config fences

* fix(ci): route manifest changes through docs audit

* chore(docs): refresh generated config baselines
2026-08-10 07:57:56 -07:00
Peter Steinberger 98b1e8b69c fix(plugin-sdk): make the API baseline contract path-free and surface-reachable (#121514)
* fix(plugin-sdk): make the API baseline hash path-free and surface-reachable

Manifest hashes now cover only surface-reachable, path-independent facts.
Rewrite closure from whole-file/path-keyed traversal to declaration-granular reachability with fail-toward-recall fallbacks and taint-tracked cycles.
Exclude source paths from the committed hash and split declaration printing into api-baseline-declaration-print.ts.

* fix(plugin-sdk): close side-effect and namespace-import gaps in baseline closure

Address ClawSweeper findings:
- Traverse side-effect imports before collecting globals.
- Normalize repo-owned namespace import types.

* refactor(plugin-sdk): rebase precision closure onto the JSONL contract
2026-08-10 07:44:53 -07:00
Vincent Koc 1f591bba56 fix(release): bound validation retries and soak 2026-08-10 22:31:32 +08:00
Shakker c5a5ba2263 fix: preserve staged attachments across chat remounts 2026-08-10 16:10:18 +02:00
Peter Steinberger f4bac99a81 feat(secrets): add SQLite-backed secret store (#121559) 2026-08-10 07:08:40 -07:00
Peter Steinberger 3b3c540896 refactor: remove dead branches and test-only helpers (#121345)
* refactor: remove dead branches and test-only helpers

* fix: preserve codex cleanup error causes

* fix: preserve gateway error code compatibility

* chore: update plugin sdk api baseline

* docs: fix live cache runner path
2026-08-10 06:47:43 -07:00
Peter Steinberger 8d810d188b refactor: split ClawHub infrastructure by responsibility (#121565)
* refactor(infra): split clawhub into concept modules

* refactor(plugins): move compat predicates to their owners

* chore(lint): ratchet baselines after clawhub split
2026-08-10 06:42:37 -07:00
Peter Steinberger f286928210 refactor(agents): type the reply failover seam and carry structured attempts (#121551)
* refactor(agents): carry structured fallback attempts

* refactor(agents): preserve typed failover delivery metadata

* refactor(auto-reply): consume canonical failover classification

* fix(auto-reply): preserve typed failure copy

* fix(auto-reply): keep failover facets internal

* fix(agents): remove stale failover exports

* chore(plugin-sdk): refresh API baseline

* fix(delivery): repair queue and pending-final settlement

* fix(lint): keep delivery queue within line budget

* fix(ci): refresh baselines after main rebase

* test(outbound): assert ambiguous send payload directly

* refactor(reply): follow upstream custody revert
2026-08-10 06:16:46 -07:00
Peter Steinberger 0d4e9f3ede fix(codex): report harness context window; compact context popover (#121491)
* fix(codex): report harness context window as session contextTokens

Codex app-server reports model_context_window per turn. Carry it through the projector into the run result meta so session rows show the real window instead of the catalog's standard-tier input cap (272k vs 1M for gpt-5.6 models).

* improve(ui): compact chat context popover

Inline stat rows replace boxed tiles; zero-value cost rows and the whole cost section when empty are omitted; provider/model provenance lines are removed because the footer already shows the model; and the popover is narrowed to 300px.

* refactor(codex): split attempt-result assembly out of event projector

* fix(codex): seed attempt context window from startup binding

App-server v2 turn/started omits the core model_context_window, so thread/tokenUsage/updated is the only live carrier. Seed usage-less attempts from the retained startup binding rollout/session window so session metadata cannot regress to the catalog fallback.

* fix(codex): prefer native startup context window

Persisted session contextTokens has no source provenance and may contain the catalog fallback. Keep the minimum window for the conservative rotation fuse, but seed the projector from the native rollout when it is available.

* chore(plugin-sdk): regenerate api baseline (new format)

* revert(gateway): "prevent restart replay after final delivery" (broke 5 CI jobs)
2026-08-10 05:52:19 -07:00
Peter Steinberger 4f046b5dc6 docs(web): document the sidebar unsent-draft pencil indicator 2026-08-10 04:56:43 -07:00
Ayaan Zaidi 1f75018600 fix(gateway): prevent restart replay after final delivery
Record channel delivery custody before recipient-visible sends so restart recovery cannot duplicate accepted finals.

Ambiguous legacy markers now fail closed with a visible interruption instead of blind replay.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-10 16:42:14 +05:30
Peter Steinberger e37614c83f refactor(plugin-sdk): replace hash manifest with JSONL contract (#121473)
* refactor(plugin-sdk): use JSONL API baseline contract

* chore(plugin-sdk): add generated JSONL API baseline
2026-08-10 03:49:17 -07:00
Peter Steinberger d847a62e5d fix(opencode): keep API-key onboarding routes usable (#121414)
* fix(opencode): keep API-key onboarding routes usable

Amp-Thread-ID: https://ampcode.com/threads/T-019fe94f-6aac-73c9-995b-ced5336f3230

* refactor(opencode): simplify onboarding compatibility

Amp-Thread-ID: https://ampcode.com/threads/T-019fe94f-6aac-73c9-995b-ced5336f3230

* fix(opencode): avoid unverified onboarding fallbacks

Amp-Thread-ID: https://ampcode.com/threads/T-019fe94f-6aac-73c9-995b-ced5336f3230

* fix(opencode): reconcile dynamic tool deltas

Amp-Thread-ID: https://ampcode.com/threads/T-019fe94f-6aac-73c9-995b-ced5336f3230

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-10 03:23:36 -07:00
Peter Steinberger c6edd3e80f feat(gateway): grant scopes by verified identity (#121531)
* feat(gateway): grant scopes by verified identity

* chore(plugin-sdk): refresh API baseline

* test(agents): isolate transcript repair mocks
2026-08-10 03:19:45 -07:00
jesse-merhi 2300de7162 Gateway: negotiate Custodian wizard cancellation 2026-08-10 20:01:24 +10:00
Jesse Merhi c30c98c028 chore: refresh plugin SDK contract 2026-08-10 20:01:24 +10:00
Peter Steinberger bab4546b41 refactor(gateway): remove dead rpc surfaces (#121387) 2026-08-10 02:41:57 -07:00
Peter Steinberger 72c4f26a4e refactor(sessions): collapse session accessor aliases (#121516)
* refactor(sessions): collapse session accessor aliases

Declaration ownership moved to defining modules; no name or signature changed.

* test(auto-reply): remove stale session hint import
2026-08-10 02:20:18 -07: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 a77dd02a04 fix(plugin-sdk): restore API baseline manifest (#121527) 2026-08-10 02:02:12 -07:00
Peter Steinberger 51a78b2924 fix(update): keep countdown stable during active work (#121504) 2026-08-10 01:29:41 -07: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
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
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 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 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
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 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 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 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
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