Commit Graph

727 Commits

Author SHA1 Message Date
Peter Steinberger
9086389527 feat(control-ui): agent identity editor, Settings-homed Agents page, scalable chip switcher (#106058)
* feat(control-ui): agent identity editor, settings-homed agents page, chip switcher pinning

* test(control-ui): pinned-agent persistence coverage; persist pins only when set

* refactor(control-ui): split agent menu, identity actions, model staging out of oversized files

* chore(i18n): sync control-ui locale bundles for agent identity/switcher keys

* fix(control-ui): stabilize new sidebar switcher tests; ratchet LOC + export baselines

* chore(review): document identity clear limitation; drop unused export

* feat(control-ui): scope pages to selected agent

* fix(control-ui): keep scoped page state consistent

* docs(control-ui): explain shared agent scope

* fix(control-ui): reconcile agent scope with current ui

* fix(control-ui): preserve complete agent filtering

* fix(control-ui): bound uploaded agent avatars

* test(control-ui): keep pinned-route fixture valid

* test(control-ui): keep pinned-route fixture valid

* chore(i18n): sync locale bundles for agent scoping keys
2026-07-13 04:03:26 -07:00
Peter Steinberger
2aa4ff0825 refactor: consolidate duplicate helper exports (#106016)
* refactor(normalization): consolidate string helpers

* refactor(normalization): consolidate agent ids

* refactor(paths): consolidate user path resolution

* refactor(gateway): preserve transcript helper facade

* fix(normalization): align helper build aliases

* fix(memory): keep helper import line neutral

* chore(plugin-sdk): align consolidated helper surface

* refactor(normalization): reuse lowercase string helper

* refactor(normalization): reuse record guard

* refactor(normalization): share surrogate boundary helper

* refactor(agents): share token estimate constant

* refactor(memory): distinguish standalone helper contracts

* refactor(normalization): share error cause formatter

* refactor(config): distinguish eligibility predicates

* refactor(plugins): share registry state symbol

* refactor(cli): reuse outbound dependency adapter

* refactor(cron): distinguish positive duration parser

* fix(gateway): keep transcript helper private

* fix(paths): preserve public helper status

* refactor(channels): reuse registry normalizer

* refactor(agents): reuse agent core runtime facade

* refactor(auth): reuse locked profile upsert

* refactor(records): distinguish trap-safe guard

* refactor(migrations): distinguish sync directory helper

* test(plugins): drop stale duration alias expectations

* fix(channels): remove stale registry import

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

* fix(memory): keep renamed helpers private

* fix(plugins): keep registry state key private

* fix(plugin-sdk): tighten wildcard surface budget

* chore(plugin-sdk): refresh rebased helper API baseline
2026-07-13 03:22:00 -07:00
Peter Steinberger
7c9b8baa2b refactor(gateway): consolidate TypeScript WebSocket clients (#106113)
* refactor(gateway): unify websocket clients

* fix(gateway): preserve adapter lifecycle behavior

* test(gateway): keep reconnect proof black-box

* chore(gateway): satisfy shared client lint

* refactor(gateway): keep protocol decisions internal

* refactor(gateway): preserve shared reconnect supervision

* test(gateway): use canonical browser barrel

* fix(gateway): resolve browser retry workspace source

* refactor(gateway): tighten shared protocol types
2026-07-13 03:08:21 -07:00
Peter Steinberger
938d41014f feat(mobile): default pairing to full node access (#105928)
* feat(mobile): default pairing to full node access

* chore: leave release notes to release workflow

* refactor(mobile): bound pairing helpers

* chore(i18n): refresh mobile access inventory

* chore(ci): lower mobile pairing LOC baseline

* fix(mobile): complete pairing validation artifacts

* ci: remove stale transcript target export baseline

* fix(ios): wrap access upgrade guidance

* fix(ios): preserve localized access key

* fix(ci): dedupe read-only SQLite guardrail

* fix(mobile): secure full-access node setup
2026-07-13 02:30:45 -07:00
Peter Steinberger
16b1bd2032 fix(android): support gateway protocol v3 (#106205) 2026-07-13 02:29:16 -07:00
Peter Steinberger
bafabba0df fix(gateway): preserve Control UI turns across restarts (#106151)
* fix(gateway): preserve Control UI turns across restart

* perf(sessions): index restart recovery state

* fix(sessions): avoid replaying pre-admitted turns

* fix(sessions): index per-entry recovery status

* fix(sessions): guard restart failure notices

* fix(sessions): preserve terminal claims across admissions

* fix(sessions): retry failed recovery notices

* fix(sessions): harden restart retry ownership

* fix(gateway): tighten restart recovery typing

* fix(sessions): close restart recovery races

* refactor(sessions): split restart recovery ownership

* chore(sessions): clean restart recovery lint

* chore: drop release-owned changelog entry

* fix(gateway): satisfy restart recovery guards

* test(gateway): cover Control UI durable admission
2026-07-13 02:08:56 -07:00
Peter Steinberger
1136757174 refactor: consolidate bounded concurrency on p-limit and p-map (#106002)
* refactor: adopt p-limit and p-map for bounded concurrency

* chore: normalize lockfile ordering

* fix: preserve memory host concurrency export

* refactor: keep media apply within size budget

* fix: drain memory concurrency before failure

* fix: satisfy memory concurrency guards

* chore: scope memory host dead-code checks

* chore: lower concurrency LOC baselines

* fix: preserve concurrency API surfaces

* chore: reconcile concurrency LOC baseline

* test: keep memory concurrency gate portable

* style: simplify concurrency drain

* ci: refresh deadcode export baseline
2026-07-13 01:53:28 -07:00
Peter Steinberger
6df498c3cd refactor: canonicalize binary operation results (#106049)
* refactor(normalization-core): promote shared result type

* refactor(agent-core): reuse canonical error coercion

* refactor: discriminate internal operation results

* docs: establish shared result convention

* fix(agent-core): preserve error coercion facade

* build: derive package entries from exports

* fix(plugins): resolve shared result subpath

* fix(ci): align Result integration guards

* build: refresh plugin SDK API baseline

* fix(agent-core): preserve toError compatibility
2026-07-13 00:39:43 -07:00
Peter Steinberger
2fc91410e8 refactor: consolidate reconnect supervisors (#105987)
* refactor: consolidate reconnect supervisors

* style: satisfy reconnect supervisor lint

* fix: keep reconnect supervisor internal

* refactor: keep retry supervisor lean

* chore: lower gateway client LOC baseline

* style: satisfy large-file LOC guard

* fix: cap long-lived reconnect backoff

* fix: preserve reconnect start failures

* test(sdk): include retry package in install smoke
2026-07-13 00:39:17 -07:00
Peter Steinberger
4cbbb86d5e refactor(zalouser): share offset-preserving text chunk ranges (#105842)
* refactor(zalouser): share text chunk ranges

* chore(plugin-sdk): refresh combined API baseline
2026-07-12 23:46:16 -07:00
Peter Steinberger
adf6b08ab4 refactor: consolidate duration parsing and formatting (#105988)
* refactor: consolidate duration handling

* docs: leave release notes to release workflow

* fix: preserve build timing precision

* ci: align plugin sdk surface budgets
2026-07-12 23:38:22 -07:00
Peter Steinberger
a0e5c15988 refactor(errors): consolidate shared error formatting (#105927)
* refactor(errors): consolidate shared formatting

* fix(errors): preserve structured diagnostic details

* fix(errors): preserve nested cause compatibility

* chore(ci): ratchet reduced formatter files
2026-07-12 22:48:55 -07:00
Ayaan Zaidi
143fed81c1 feat(sessions): reopen history around search hits 2026-07-13 10:27:29 +05:30
Ayaan Zaidi
432da8b3cb feat(agent): preserve interrupted turn context
Inspired by Codex: codex-rs/core/src/context/turn_aborted.rs and codex-rs/core/src/tasks/mod.rs.
2026-07-13 10:27:29 +05:30
Peter Steinberger
1aff6da827 refactor(test): use shared timeout helper (#105918) 2026-07-12 20:51:51 -07:00
Peter Steinberger
d49acffa5e refactor(infra): consolidate retry scheduling (#105789)
* refactor(infra): consolidate retry scheduling

* fix(build): wire shared retry package

* fix(build): resolve retry package in source graphs

* fix(infra): keep retry adapter dependency-free
2026-07-12 19:58:55 -07:00
xiaobao-k8s
ff166425d1 fix(media): parse local file extensions across path styles (#105614)
* fix(media): parse local file extensions across path styles

* docs: note cross-platform media path fix

* docs: keep release notes in PR context

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-12 17:35:43 -07:00
wuqxuan
5429f06940 fix(ai): clean up abort listener after provider retry sleep (#105519)
* fix(ai): unregister abort listener after provider sleep completes

* refactor(ai): isolate abortable retry sleep

* test(ai): isolate retry sleep lifecycle coverage

* docs: keep release notes in PR context

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-12 17:34:30 -07:00
Peter Steinberger
867284dfa3 refactor(deadcode): delete package and script exports (#105776)
Refs #105733
2026-07-12 17:24:45 -07:00
Vincent Koc
dc644800ef refactor(packages): trim private aggregate roots (#105747) 2026-07-13 08:00:59 +08:00
Vincent Koc
b7a7f3fa71 refactor(ai): trim private Responses exports (#105720) 2026-07-13 07:46:35 +08:00
Peter Steinberger
e261fa60ce feat(cloud-workers): gateway inference proxy for worker model turns (#105719)
* refactor: clarify prepared auth value

* feat(cloud-workers): add inference proxy protocol

* feat(cloud-workers): persist inference turns

* feat(cloud-workers): execute gateway inference turns

* fix(cloud-workers): support adaptive inference reasoning

* fix(gateway): constrain worker inference policy options

* test(gateway): cover worker inference SQLite store
2026-07-12 15:35:50 -07:00
pick-cat
840f349d5d fix(terminal): keep C1 CSI and BEL-terminated OSC-8 links intact when wrapping table cells (#103717)
* fix(terminal): keep C1 CSI and BEL-terminated OSC-8 links intact when wrapping table cells

* fix(terminal): close and reopen OSC-8 links at table wrap boundaries

* fix(terminal): carry leading OSC-8 state through table wrap state machine

A cell shaped like `${link} after` left the OSC-8 opener in `prefixAnsi`
(prepended to every wrapped line) while its closer sat inside `coreTokens`.
Continuation lines got an opener with no matching closer, reopening the
hyperlink onto trailing plain text and padding and bleeding link state past
the cell border.

Exclude OSC-8 tokens from `prefixAnsi`/`suffixAnsi` (SGR-only, unchanged)
and seed leading openers / trailing closers into `coreTokens` so the
`flushAt` close/reopen logic owns hyperlink state end to end. Adds a
`${link} after` regression across BEL, ESC-backslash, and C1-ST terminators.

Addresses the ClawSweeper P2 finding on #103717: carry leading OSC-8 state
into wrapped lines.

* chore: trigger CI re-run

* chore: trigger CI re-run

* fix(terminal): preserve ANSI state across table wraps

Co-authored-by: Pick-cat <huang.ting3@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-12 12:10:35 -07:00
Peter Steinberger
1b313dc4d4 chore(tooling): enforce indexed access in core tests (#105375)
* test(tooling): enforce indexed access in core tests

* test(tui): constrain theme environment overrides

* test(doctor): enforce indexed access in migration fixtures
2026-07-12 14:29:52 +01:00
Peter Steinberger
4289c6c16c feat(cloud-workers): replayable worker live-event streaming into the session fanout (#105275)
* feat(protocol): add worker live-event frames

* feat(gateway): fan out replayable worker live events

* feat(gateway): add worker live-event replay receiver

* docs(protocol): document worker live events

* fix(gateway): preserve deferred worker live events

* test(gateway): cover deferred worker event projection

* refactor(gateway): revert async projection layer

* fix(gateway): retain buffered worker live events

* fix(gateway): guard buffered terminal admission

* fix(plugin-sdk): trim worker live-event declarations
2026-07-12 13:47:59 +01:00
Peter Steinberger
dba78584ff fix(ui): preserve rejected first message when session send fails (#105261)
* fix(ui): preserve rejected first session message

* chore: leave changelog to release closeout

* fix(protocol): regenerate session create result
2026-07-12 11:09:38 +01:00
Peter Steinberger
5b56a1f664 feat(gateway): land remaining durable-approvals stack and repair main gates (#104837)
* feat(gateway): propagate approvals to ancestor sessions with replay

Squash-rebased #103921 segment onto the native-clients tip on current main.
Session-scoped approval events publish sanitized pending/terminal
transitions to opted-in session audiences, with authoritative pending
replay on stream subscribe and durable-expiry reconciliation through the
owning manager. SessionApprovalEvent/Replay wire types export from the
approvals owner module; Swift models regenerated.

(cherry picked from commit 2d1dcf9747044710111d0c730fc46ba6013a165c)
(cherry picked from commit ccf88efd56b513d07599ffcee997bf0cddaf9adc)
(cherry picked from commit 8eb33f59f00ec9ee4625259b76bd7ae60d2cd480)
(cherry picked from commit c297cbc93c8401e9c79c20f242245a194f5dd236)
(cherry picked from commit 93d68f28601ff37d863da4db009504993a22533a)
(cherry picked from commit d285ccd8b2f212bb57e814107e7709c896e96b7d)
(cherry picked from commit 5c536982231402b1b58d1683794ea9948b32d077)
(cherry picked from commit 1646e5b6dc4dd20de54e10f110a5909be18d7d50)
(cherry picked from commit 35cf1b705b247fb282f4d56ffe74bd2fb238221f)
(cherry picked from commit 4f8ef3699d)
(cherry picked from commit 74fbdcc99d5fff062d67760a51dba4ee9e84479b)
(cherry picked from commit 222b285502681d2be14b1819798e9ee5555f431e)
(cherry picked from commit b9e744951f676b600e7c5322bfd04b0e99797c07)
(cherry picked from commit 9e904efde5)
(cherry picked from commit 678f2384fa)
(cherry picked from commit 72842e5cf6)
(cherry picked from commit be74c25e80e84a1f065053766f23efb84822e811)
(cherry picked from commit 93ba8c4b09)
(cherry picked from commit 8f23761372)

* feat(gateway): fail-closed plugin and tool approval gates

Squash-rebased #103932 segment onto the ancestor-propagation tip on
current main. Plugin node.invoke approvals claim a one-shot allow-once
decision before handing execution authority to the policy, so observation
or retry cannot replay a consumed approval; sibling tool gates bind
approval ids to their originating reviewer identity.

(cherry picked from commit 122df0d75281f572c012b6484ed5daf085d1d577)
(cherry picked from commit f23d8ac240a8dcf2a42c4daaae962263975a0ae8)
(cherry picked from commit 8632fb6436a224dac7a9a9ef0216884530de2c24)
(cherry picked from commit d9fe2dd5c53665e5732f5f3da5ed1907a686ade8)
(cherry picked from commit bb139f2c8aa36ddad70413e1ef79ff491a6f2ecd)
(cherry picked from commit 9b3e056b68ea515c7d4baef269289b6670570480)
(cherry picked from commit b11e66b59a7af1f3b08712de06864aed64d349e4)
(cherry picked from commit a12916ee592d03dfa35e86a2aaede4476a5d4e5d)
(cherry picked from commit d699de840fc8346892b9ae244fe3c3e8c4413032)
(cherry picked from commit 9b7e5a9608)
(cherry picked from commit 4b507593f1b2f10b4496984c84a2803b853e5c5e)
(cherry picked from commit 56408a186733c4eeb5aa76bd5907cde7b0cd3d5b)
(cherry picked from commit a4051d6d8353d39d6fa0b5d69c36e06c3cd3e796)
(cherry picked from commit 76829805a7)
(cherry picked from commit a8b493f934)
(cherry picked from commit aceb990597)
(cherry picked from commit a29b0e75482470c53a9fb4fe3f204e14cf71868f)
(cherry picked from commit 2e3be08653)
(cherry picked from commit c9ae3d7202)

* fix: main-gate repairs for the durable-approvals stack

- android: capture createdAtMs on the pending exec-approval write at
  registration; canonical readback after a refresh that already replaced
  the visible rows was dropping the approval instead of surfacing the
  still-pending reconciliation message (#104913 merged without this)
- android: generous CI timeout ceilings in GatewayExecApprovalRuntimeTest
- agents: hermetic model-discovery test via the plugins/provider-runtime
  boundary (lazy plugin-runtime resolution hangs vitest workers since #104770)
- cli: usage-cost settle-budget test asserts the budget bound on every call
  instead of pinning the poll count (fast hosts fit a second poll in 50ms)
- protocol coverage: allowlist session.approval for ios/android (native
  review rides exec.approval push/nudge delivery)
- docs map, native i18n inventory, plugin-sdk api baseline regenerated
2026-07-12 10:51:38 +01:00
Peter Steinberger
55254c3a0b feat(nodes): route alerts to the active computer (#105083)
* feat(nodes): route alerts by active computer

* fix(ci): allowlist node presence mobile coverage

* test(prompts): refresh node presence snapshots

* fix(macos): await presence reporter actor hop

* fix(macos): type presence test delivery state

* docs(nodes): add active presence guide

* docs(nodes): format presence troubleshooting
2026-07-12 10:05:50 +01:00
Vincent Koc
73bf1f29f8 refactor(models): trim private catalog exports (#105150) 2026-07-12 16:31:59 +08:00
Peter Steinberger
6fc564278d feat(agents): sessions_search full-text recall over past session transcripts (#105057)
Adds a core sessions_search agent tool backed by a SQLite FTS5 index that
lives next to the transcript rows in the per-agent database. Indexing is
transactional: user/assistant text is indexed inside the same write
transaction that persists the event, deletes drop index rows in the same
transaction, and branch rewinds mark the session dirty so the next search
rebuilds it from the same visible-path resolution sessions_history uses
(which also lazily backfills doctor-migrated databases). Search executes
gateway-side behind an additive sessions.search method with a bounded
session-key allowlist; visibility, sandbox restrictions, and snippet
redaction mirror sessions_history.

Closes #100978
2026-07-12 09:15:41 +01:00
Peter Steinberger
6038480915 feat(ui): browse Gateway and node folders from one root (#105114)
* feat(ui): browse Gateway and node folders

* chore: keep changelog release-owned

* chore: refresh native i18n inventory

* refactor(macos): isolate node filesystem commands
2026-07-12 09:07:07 +01:00
Peter Steinberger
d14bb8ec44 fix: resume replay-safe work after gateway restarts (#104997)
* fix: resume replay-safe work after gateway restart

* chore: leave restart note to release process

* fix: sync restart recovery protocol artifacts
2026-07-12 06:37:22 +01:00
Vincent Koc
982efe51e4 refactor: remove dead UI and parser helpers (#104944)
* refactor(tool-call-repair): remove unused parser wrapper

* refactor(ui): remove dead private helper surfaces
2026-07-12 12:08:56 +08:00
Peter Steinberger
68f0eee5ae fix(ui): harden workspace file editing (#104885)
* fix(ui): retain unsaved workspace file drafts

* fix(ui): reset restored draft hash

* fix(ui): keep all unsaved file drafts

* fix(ui): harden workspace file editing

* fix(ui): canonicalize workspace file identity

* fix(gateway): serialize workspace file saves globally

* chore: keep release notes in PR body

* docs: refresh generated docs map
2026-07-11 19:25:47 -07:00
Peter Steinberger
7a456e362d feat(channels): add typed cross-surface approval actions (#103679)
* fix(gateway): approval registry hardening and protocol-surface follow-ups

Follow-up delta to the merged #103579 head, rebased onto current main:
- gateway-protocol wire types derive from owner-module schema consts
  (types.ts tombstone) and ProtocolSchemas leaves the package index so the
  public plugin-sdk d.ts graph tree-shakes the registry declaration
- approval access authority follows the operator.approvals scope tier with
  reviewerDeviceIds as the opt-in restriction (cross-surface
  first-answer-wins; requester identity gates only legacy adapters)
- plugin node.invoke approvals register directly so unrenderable
  presentations fail closed before request routing
- exec-approval manager reconciliation with #103515 revocation hardening
  (resolution source attribution, one-shot ask-fallback consumption)
- surface-report pins and plugin-sdk API baseline refreshed; Swift models
  regenerated

* feat(channels): add typed operator approval actions

Squash-rebased #103679 segment onto the durable-approval-registry tip on
current main. Typed approval/command/select presentation actions replace
raw-string inference across slack/telegram/discord/matrix/imessage/whatsapp,
approval.resolve carries an explicit kind, and channel adapters map native
callback envelopes through the typed action registry.

Drift reconciliation: deprecated buildExecApprovalInteractiveReply assertions
dropped (#104650 removed the shims); worker_environments bootstrap-column
migration kept alongside the approval resolution_ref backfill; plugin-sdk API
baseline regenerated.

(cherry picked from commit 68765a5d39d2118c88a7a54d00387337912d4494)
(cherry picked from commit 8642ac12af142e4b751f4f30d4b114615e7e5f66)
(cherry picked from commit 036c4bc39499925fc03de16ec9302e346769350a)
(cherry picked from commit 19dc350d6bc34e29a5169c6bc80971b0ad12adde)
(cherry picked from commit fc978b0bad86aef421c79f6a211b25cc1b743c01)
(cherry picked from commit 10de4d1ed5071f9be6ad1ee5d1e32c0fa8c9d11c)
(cherry picked from commit 9a664ced1b1fa740172b258f355f1a82925ae41c)
(cherry picked from commit c5ff69abbf444139e9e007bfa45beb0f00ffea54)
(cherry picked from commit d466a80795)
(cherry picked from commit f5b4fe40dd5c961322f8553cc80b2fdfb3f6503e)
(cherry picked from commit 7340b4749a4cc4c72f7a41cce1bc9cb550cae038)
(cherry picked from commit a151f41808f23ae60b10305ccd2bc959b9169a86)

* fix(approvals): preserve typed transport ownership

* test(imessage): narrow chunked approval text

* refactor(protocol): remove retired type tombstone

* fix(plugin-sdk): align surface budgets after rebase

* docs(changelog): note typed operator approvals

* docs(changelog): defer typed approval release note
2026-07-11 18:31:05 -07:00
Peter Steinberger
82667a66e5 feat(ui): editable file panel with CodeMirror and sessions.files.set hash-CAS writes (#104757)
* feat(gateway): add sessions.files.set workspace file write with hash CAS (#104698)

* feat(ui): CodeMirror file editor panel with CAS save + clickable tool-card paths (#104698)

* fix(gateway): issue the file CAS hash only for strict-UTF-8 text (#104698)

* docs(web): document the editable file detail panel (#104698)

* fix(gateway,ui): round-trip BOM and CRLF bytes through the file editor (#104698)

* fix(ui): keep mixed-line-ending files read-only in the file editor (#104698)

* fix(ui): re-gate editability when a conflict reload returns non-editable content (#104698)

* fix(gateway): reject NUL bytes in sessions.files.set replacement content (#104698)

* fix(gateway,ui): regenerate protocol bindings, fix prod types and lint for file editor (#104698)
2026-07-11 17:36:28 -07:00
Peter Steinberger
04f945fabe feat(cloud-workers): durable transcript commit protocol for worker sessions (#104809)
* feat(cloud-workers): add transcript commit protocol

* feat(cloud-workers): persist transcript commit replay state

* feat(cloud-workers): apply transcript commits to sessions

* fix(cloud-workers): harden transcript commit admission

* fix(cloud-workers): recover branched transcript commits

* fix(cloud-workers): preserve diagnostic semantics
2026-07-11 17:29:07 -07:00
Peter Steinberger
3255b3218a feat: unify external sessions with native catalog pagination (#104717)
* feat(gateway): add generic sessions.catalog surface with plugin SDK registration seam

* feat(agents): support one-shot forked CLI session resume with successor rebinding

* feat(anthropic): adopt local Claude CLI sessions into native chats via catalog continue

* feat(codex): register the session catalog provider independently of supervision

* refactor(ui): delete the retired custom Claude/Codex session tab views

* feat(ui): render external session catalogs as native sidebar sessions and chat panes

* docs: describe the unified native session catalog

* fix: harden forked CLI resume and catalog transcript mapping after review

* fix: satisfy strict typecheck for catalog source guard and imported message cast

* chore(i18n): regenerate session catalog locales

* fix(codex): simplify session source guard type

* fix(ui): paginate sidebar session catalogs

* chore(i18n): refresh catalog metadata after main merge

* fix(ui): harden session catalog pagination refresh

* test(agents): use sqlite session accessor in fork tests

* fix(ci): refresh session catalog generated surfaces

* fix(ui): align session catalog locales

* fix: address session catalog review findings

* fix(sessions): roll back failed plugin catalog adoption

* test(sessions): preserve CLI binding literals

* fix(ui): restore native session pagination label

* docs: note external session catalogs

* Revert "docs: note external session catalogs"

This reverts commit cfb503f160.
2026-07-11 17:26:26 -07:00
snowzlmbot
be373ea516 improve(android): show provider-configured model details (#101912)
* feat(android): show provider model inventory

Co-authored-by: snowzlmbot <293528334+snowzlmbot@users.noreply.github.com>

* fix(gateway): project provider inventory routes

* style(android): satisfy provider inventory ktlint

* chore(android): sync provider inventory i18n

* style(android): finish provider inventory formatting

* fix(android): harden provider inventory refresh

* test(gateway): type provider inventory fixture

* chore(protocol): regenerate Swift model choice

* chore(android): sync provider inventory i18n

* test(gateway): pin provider inventory discovery mode

* chore(android): sync provider inventory landing

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: snowzlmbot <293528334+snowzlmbot@users.noreply.github.com>
2026-07-11 17:22:16 -07:00
Peter Steinberger
02dc25a1b5 feat(gateway): persist operator approvals (#103579)
* feat(gateway): persist operator approvals

* fix(gateway): preserve approval ids exactly

* fix(gateway): enforce approval reviewer bindings

* fix(gateway): reconcile durable approvals with exec revocation hardening

Map #103515 semantics onto the durable lifecycle: resolutionSource and
one-shot consumeAskFallback stay process-local record facts, trusted
auto-review resolves through the durable CAS as a runtime resolver, and
lost races settle with the winner's operator source. Also: derive the
audience walker cap from the store cap, report APPROVAL_ALREADY_RESOLVED
for a resolve that loses the CAS race, document approval.get/resolve in
the protocol docs, and regenerate Swift models on the new base.

* fix(approvals): validate resolver kind

* docs(approvals): explain malformed verdict denial

* fix(protocol): regenerate approval models after rebase

* chore: leave changelog entry to release generation

* fix(gateway): preserve approval registration boundaries

* test(gateway): prove multi-device approval races

* test(gateway): keep approval order assertion stable

* docs: index operator approval architecture

* fix(protocol): bound approval declaration exports
2026-07-11 16:53:49 -07:00
Peter Steinberger
f929fd9865 feat(ui): chat background-tasks rail detects running work eagerly and shows live tool activity (#104776)
* feat(ui): detect background tasks eagerly and show live tool activity in the chat rail

Track tool-start counts and the last tool name per task run in the task
registry, persist them on task_runs, and expose them as additive optional
TaskSummary fields. The chat background-tasks rail now loads its snapshot
eagerly so the collapsed toggle badge detects running work immediately,
and rows show a live elapsed timer, tool-use count, and the tool
currently in use (run duration for finished rows).

Issue: #104775

* fix(ui): translate background-task activity strings and refresh generated protocol models

The singular tool-use label is literal ("1 tool use") because several
locales legitimately drop the count placeholder in singular forms, which
fail-closes the placeholder guard in the i18n sync. Locale bundles are
the authenticated ui:i18n:sync output (fallbacks=0); GatewayModels.swift
is protocol:gen:swift output for the new TaskSummary fields.

* chore(ui): refresh i18n raw-copy baseline after rebase
2026-07-11 16:51:48 -07:00
ZOOWH
fb702e5cae fix(memory): harden embedding batch workflows (#103472)
* fix(memory): harden embedding batch workflows

Co-authored-by: 徐闻涵0668001344 <xu.wenhan1@xydigit.com>
Co-authored-by: ben.li <li.yang6@xydigit.com>

* test(memory): align batch redaction expectation

* test(memory): tighten batch dependency types

* refactor(google): clarify batch state control flow

* test(google): make batch stage fallback lint-safe

* build(plugin-sdk): refresh memory batch surface budget

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: ben.li <li.yang6@xydigit.com>
2026-07-11 16:43:58 -07:00
Peter Steinberger
847460600f feat(macos): redesign device-code sign-in (#104766)
* feat(macos): redesign device-code sign-in

* chore(i18n): refresh native string inventory

* fix(macos): localize device-code completion action

* fix(auth): preserve device-code fallback copy

* fix(xai): report browser launch accurately
2026-07-11 16:43:21 -07:00
Leon Ma
1338b0d0bc fix(ai/gemini): coerce numeric/boolean enum values to strings (#104567)
* fix(ai/gemini): coerce numeric/boolean enum values to strings

Gemini Function Calling only accepts string enum values (see
https://ai.google.dev/gemini-api/docs/function-calling). Tool schemas
containing enum: [1,2,3] or enum: [true,false] were passed through
unchanged, causing Gemini to reject the entire request with 400
TYPE_STRING errors at 'function_declarations[X].parameters...enum[N]'.

Extend cleanSchemaForGeminiWithDefs to coerce enum and const values
via a shared helper (number/boolean/bigint -> string, drop null and
non-coercible entries, de-duplicate), and retype the containing schema
as 'string' since Gemini's validator only accepts enum on string-typed
schemas.

Adds seven vitest cases covering numeric/boolean enum, const, nested
schemas, and dedup/empty-after-coercion edge cases.

Fixes #104566

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

* fix(ai/gemini): make enum retyping property-order independent

Address @clawsweeper review on #104567:

The initial patch set cleaned.type = 'string' inline while visiting the
'enum' or 'const' key. For schemas where 'type' appears AFTER 'enum' /
'const' in the input object — a valid ordering since JSON Schema property
order is not semantic — a later 'type' pass would overwrite the coercion
via the tail 'cleaned[key] = value' branch, and Gemini would still receive
an invalid declaration.

Move the type override out of the loop: track whether any enum/const was
coerced via a boolean flag, and force cleaned.type = 'string' after the
loop finishes. This makes the fix independent of input property order.

Also add curly braces around single-line ifs to satisfy check-lint
(eslint(curly)) which failed on the previous commit.

New reversed-order regression tests added.

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

* fix(ai): preserve Gemini enum schema types

---------

Co-authored-by: leonme <leonme@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-11 16:34:31 -07:00
VectorPeak
f8c7f67bde fix(ai): reject non-finite tool schema numbers (#104470)
* fix(ai): reject non-finite tool schema numbers

Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>

* fix(ai): catch non-finite values from tool schema serializers

Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>

Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>

* test(ai): cover nested tool schema serializers

Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>

* fix(ai): satisfy schema projection lint

Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>

* fix(ai): satisfy schema projection lint

Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>

* fix(ai): preserve empty-key schema diagnostic paths

* fix(ai): reject boxed non-finite schema numbers

* fix(ai): ignore spoofed boxed-number tags

* fix(ai): isolate boxed-number brand probes

* refactor(ai): use intrinsic boxed-number detection

---------

Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-11 14:50:54 -07:00
Josh Lehman
0a8e3604ba refactor: flip sessions and transcripts to sqlite storage (#98236)
* refactor(sessions): migrate runtime storage to sqlite

* test(sessions): fix sqlite CI regressions

* test(sessions): align remaining sqlite fixtures

* fix(codex): require sqlite trajectory recorder

* test(sessions): align orphan recovery sqlite fixture

* test(sessions): align sqlite rebase fixtures

* fix(sessions): finish current-main integration of the sqlite flip

Resolve the whole-store SDK removal across its owner boundary: drop the
loadSessionStore re-export and the registry whole-store wrappers, wire
hasTrackedActiveSessionRun into gateway chat, complete the
preserveLockedHarnessIds cleanup contract, flip the codex thread-history
import to storePath targets, and port remaining main-side tests from
file-store helpers to session accessor reads.

* chore: drop committed pebbles log, revert plugin-inspector bump, refresh generated docs

Remove the 1.8k-line .pebbles/events.jsonl work log from the branch, restore
the plugin-inspector advisory lane to main's pinned 0.3.10 so the supply-chain
bump gets its own review, and regenerate docs_map, the plugin SDK API baseline,
and the export-surface ratchet for the merged tree.

* feat(sessions): keep archived transcripts by default with zstd cold storage

Codex-style retention: deleting or resetting a session archives its
transcript as a zstd-compressed JSONL artifact (plain when the runtime
lacks node:zlib zstd) and keeps it until the disk budget evicts oldest
first. resetArchiveRetention now governs both deleted and reset archives
and defaults to keep; maxDiskBytes defaults to 2gb so retention stays
bounded, with archives evicted before live sessions. The cron reaper
follows the same knob instead of deleting archives on its own timer.

* fix(state): converge agent DB migration lineages and bound database growth

Merge coherence: run both structure-gated legacy memory-schema repairs
(flip-lineage drop, main-lineage identity rebuild) before the flip
migration so pre-flip v1/v2 and pre-merge flip v1/v4 databases all
converge, and hoist foreign_keys=OFF outside the schema transaction
where the pragma was silently ignored and the v1 sessions rebuild
cascade-deleted session_entries.

Growth guards: fresh agent DBs enable auto_vacuum=INCREMENTAL, WAL
maintenance releases freed pages in bounded passes (never a blocking
full VACUUM), and doctor reports state/agent DB bloat from freelist
stats.

* fix(codex): resolve the store path for thread-history import via the SDK

The supervision catalog passed the legacy sessionFile locator to the
storePath-targeted transcript mirror; resolve the agent store path with
the session-store SDK helper instead of a runtime-object seam so test
fakes and headless callers need no extra surface. Drop the obsolete
missing-session-id preprocessing case: sessions rows are NOT NULL on
session_id and upsert repairs id-less patches at write time.

* fix(sessions): fail safe on malformed disk-budget config and doctor stat errors

A malformed explicit maxDiskBytes disables the budget instead of
falling back to the destructive 2gb default the user never chose, and
the doctor bloat check skips databases whose paths stat-fail instead of
aborting doctor.

* fix(sessions): complete sqlite conflict translations

* test(sqlite): align hardening checks with maintenance

* test(sessions): inspect compressed transcript archives

* fix(tests): await session seeds and drop unused helpers flagged by CI lint

The five unawaited writeSessionStoreSeed calls raced their SQLite seeds
against the assertions, failing compact shards; the bloat probe drops a
useless initializer and the merged tests drop now-unused helpers.

* test(sessions): type legacy proof events directly

* test(sessions): align hardening contracts

* perf(sessions): read usage transcript sizes from SQL aggregates

Usage/cost scans walked every session and materialized every transcript
event just to re-stringify it for a byte estimate — the #86718 stall
class reborn on the DB. readTranscriptStatsSync sums stored JSON bytes
in SQLite without loading a single row.

* fix(sessions): re-root foreign-root transcript paths onto the current sessions dir

Restored backups, moved OPENCLAW_STATE_DIR, and rehearsal copies carry
absolute sessionFile paths from the old root; the containment fallback
kept those foreign paths, so migration read (and would archive) files in
the original root and reported local copies missing. Re-root the
canonical agents/<id>/sessions suffix onto the current dir when the file
exists there; genuine cross-root layouts still fall through unchanged.

* test(agents): seed harness admission through sqlite

* fix(sqlite): close agent db on pragma setup failure

* fix(doctor): compact and retrofit incremental auto-vacuum after session import

The migration is the sanctioned offline window: post-import compact
reclaims import churn and applies auto_vacuum=INCREMENTAL to databases
created before the fresh-DB pragma existed, so runtime maintenance can
release pages in bounded passes on every install.

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-11 14:50:37 -07:00
Peter Steinberger
b80ab618c3 feat(cloud-workers): authenticated worker protocol with closed ingress and minted credentials (#104688)
* feat(cloud-workers): add authenticated worker protocol

* feat(cloud-workers): add worker credential primitives

* docs(gateway): document closed worker protocol

* test(cloud-workers): keep protocol fixtures lean

* fix(cloud-workers): bound live worker connections

* fix(cloud-workers): close admission and cleanup gaps

* docs: regenerate docs map for worker protocol page
2026-07-11 13:45:14 -07:00
Peter Steinberger
8fe6ac7fb9 refactor: remove pre-2026.4 compatibility shims and legacy migrations (#104650)
* refactor(matrix): retire pre-2026.4 legacy crypto and flat-storage migrations

* refactor(cli): drop pre-tsdown daemon-cli dist compat shim from the build

* refactor(diffs): remove deprecated image*/format tool params and output aliases

* refactor(ui): drop pre-gateway-scoped localStorage readers and legacy theme map

* refactor: remove assorted pre-2026.4 compat shims and deprecated aliases

* fix(discord): map legacy thread-binding fields in the doctor JSON import

* fix(msteams): keep bot read fallback for legacy imported conversation rows

* test(msteams): cover legacy bot-only imported conversation references

* fix(ui): keep channel-prefixed session key display fallback

* chore: refresh native i18n inventory and build-docker step count

* chore(matrix): drop now-unused migration-config module

* chore: re-pin plugin SDK public export budget after compat removals

* chore: refresh native i18n inventory after rebase

* chore: re-pin plugin SDK callable budget and refresh i18n inventory after rebase
2026-07-11 13:22:27 -07:00
Peter Steinberger
7a466b33f3 feat: add metadata-only message audit events (#103903)
* feat: add metadata-only message audit events

* chore(protocol): restore generated swift models and config baseline after rebase

* fix(state): gate agent-db ownership check before schema version

* fix(cli): sync audit command description into the root-help catalog

* fix(audit): require destination proof before classifying outbound messages as direct

* refactor(audit): drop dead migration guard and add contract comments

* docs(gateway): add dedicated audit history page and cross-links

* test(e2e): enable direct-mode message audit in the telegram proof SUT config

* test(channels): expect declared conversationKind in durable delivery session context

* fix(audit): record the routing channel id for inbound rows from plugin channels

* fix(audit): match channel-prefixed delivery targets in the destination route gate

* fix(audit): validate explicit target kind against the destination route kind

* fix(audit): use the canonical target-prefix grammar in the destination route gate and fail closed on foreign migration tables

* fix(audit): normalize nested provider and kind target prefixes in the destination gate

* fix(audit): strip registered provider aliases and the direct kind prefix in the destination gate

* chore(docs): refresh config baseline after rebase
2026-07-11 13:14:08 -07:00
Peter Steinberger
8310c565e0 feat(onboarding): add provider sign-in (#104502)
* feat(onboarding): add provider sign-in flows

* fix(oauth): keep callback compatibility

* fix(onboarding): reconcile lost auth outcomes

* fix(onboarding): lock auth cancellation at commit

* fix(onboarding): close provider auth lifecycle gaps

* fix(onboarding): make terminal auth failures dismissable

* fix(onboarding): satisfy native app checks

* fix(onboarding): reconcile absent auth sessions

* fix(onboarding): bound provider auth sessions

* fix(onboarding): open provider auth links safely

* test(onboarding): use scanner-safe auth fixtures

* revert: keep established onboarding auth fixtures

* fix(onboarding): close provider auth cancellation gaps

* fix(gateway): retain uncollected wizard results

* fix(onboarding): bind provider reconciliation attempt

* fix(i18n): avoid guessing moved string identities

* style(onboarding): normalize remote auth choices efficiently

* fix(protocol): refresh optional provider auth choices

* test(gateway): cover provider auth dispatch order

* refactor(macos): split onboarding setup support

* fix(macos): refresh merged native checks
2026-07-11 13:00:17 -07:00