Commit Graph

1416 Commits

Author SHA1 Message Date
Peter Steinberger 2a895ca8db fix(cron): prevent completed runs retrying after claim conflicts (#108682)
* fix(cron): avoid replay after lifecycle conflicts

* test(cron): type lifecycle race fixture

* chore: leave changelog to release flow

* fix(protocol): sync Swift session creation model
2026-07-16 00:45:59 -07:00
Hosan 7bf6bf3150 fix(cron): detect configured Brave search during preflight (#108636)
* fix(cron): use secrets config for web search preflight

* fix(cron): reuse prepared web search provider

Co-authored-by: Hosan <200961079+hosanxiv@users.noreply.github.com>

---------

Co-authored-by: Hosan <200961079+hosanxiv@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 00:03:41 -07:00
ToToKr 29475988da fix(cron): keep valid command env vars when a sibling value is non-string (#105433) (#106100)
* fix(cron): keep valid command env vars when a sibling value is non-string (#105433)

normalizeTrimmedStringRecord returned undefined whenever any env value was non-string, so payload normalization deleted the entire env map before gateway schema validation, silently dropping valid siblings (e.g. env {DEBUG:true, PATH:'/bin'} lost PATH). It now filters invalid entries and only normalizes the map away when no valid entries remain, matching the sibling normalizeTrimmedStringArray behavior in the same file.

* fix(cron): reject malformed command env maps

Co-authored-by: MoerAI <friendnt@g.skku.edu>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-15 23:20:24 -07:00
Peter Steinberger bae9752c5a refactor(deadcode): enforce repository hard zero (#108641) 2026-07-15 22:40:00 -07:00
Peter Steinberger 9497450511 refactor: eliminate dead-export baseline (#108376)
Burn the grandfathered unused-export baseline to zero and enforce a hard-zero Knip gate.
2026-07-15 17:05:07 +01:00
Peter Steinberger 3d76a4af92 refactor(deadcode): privatize runtime test seams (#108338)
* refactor(sessions): privatize runtime test seams

* refactor(commitments): privatize extraction test seams

* refactor(flows): privatize doctor health seams

* refactor(tasks): privatize registry test seams

* build(commitments): bundle Docker test support

* chore(deadcode): shrink runtime export baseline
2026-07-15 07:27:10 -07:00
Peter Steinberger 2808507c3b refactor(agents): privatize runtime test seams (#108295)
Shrinks the dead-export baseline from 156 to 151 entries.
2026-07-15 05:36:35 -07:00
Peter Steinberger b6989cbaf2 refactor(cron): isolate creator tool caps (#108122)
* refactor(cron): isolate creator tool caps

Co-authored-by: yetval <yetvald@gmail.com>

* fix(cron): keep creator cap plan internal

* test(cron): derive internal patch plan type

---------

Co-authored-by: yetval <yetvald@gmail.com>
2026-07-15 01:25:41 -07:00
Yuval Dinodia 864bb18738 fix(cron): cap trigger script tool access (#104430)
* fix(cron): cap trigger script tool access

Persist the creator tool cap for any cron job with a trigger script and pass it to the headless trigger runtime. System event and command payloads retain the cap across cron updates.

* fix(cron): persist trigger tool cap for systemEvent and command payloads

The creator tool cap is stamped on systemEvent and command payloads whenever a
cron job carries a trigger script, but the SQLite codec dropped
payload.toolsAllow for those kinds. After a gateway restart the reloaded job
carried no cap and the trigger regained the full coding surface. Persist and
restore toolsAllow through the existing payload_tools_allow_json column for all
payload kinds, and add restart-aware round-trip coverage.

* ci: re-trigger workflows (transient self-hosted runner flake)

* fix(cron): use expectDefined for store test job access

* refactor(cron): hoist cron tool types, payload merge, and wire types into companion modules

Keeps the oversized cron files at or below their baseline line counts for the
changed-file TypeScript LOC ratchet on main. No behavior change.

* fix(cron): retain freshly stamped cap markers

* test(ci): align compact shard count

* fix(cron): make trigger cap updates atomic

* fix(cron): preserve explicit cap provenance

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-15 00:01:26 -07:00
Peter Steinberger cb60e0a667 ci: stabilize release validation checks (#106959) 2026-07-15 05:03:43 +01:00
Peter Steinberger 24fb23d96f refactor(compat): trim internal naming exports (#107758)
* refactor(compat): privatize legacy naming constants

* chore(deadcode): refresh unused-export baseline
2026-07-14 13:46:59 -07:00
Peter Steinberger f81f9d8570 chore: enforce max-lines suppression ratchet (#107315)
* ci: enforce max-lines suppression ratchet

* chore: prune stale max-lines suppression

* fix: close max-lines ratchet enforcement gaps

* fix: harden max-lines ratchet checks

* fix(ci): satisfy max-lines ratchet checks

* style: format max-lines declarations

* fix(ci): match oxlint suppression grammar

* test: isolate max-lines git fixtures

* chore: prune resolved max-lines debt

* test: skip newline path fixture on Windows

* fix: harden max-lines suppression ratchet

* chore: refresh max-lines baseline

* fix: close max-lines ratchet bypasses

* fix: derive ratchet base from PR merge tree

* fix: support older Git in staged ratchet

* fix: align max-lines declarations and baseline

* chore: refresh max-lines baseline for current main

* fix: exclude generated wizard locales from max-lines

* chore: prune resolved max-lines debt
2026-07-14 09:27:02 -07:00
Peter Steinberger b146ef8a59 refactor(cron): trim internal export surface (#107640)
* refactor(cron): trim internal export surface

* chore(deadcode): refresh cron export baseline
2026-07-14 09:02:18 -07:00
Peter Steinberger 98de5832a7 refactor(process): remove internal export seams (#107456) 2026-07-14 05:23:29 -07:00
Ayaan Zaidi 319a796079 fix(gateway): never leave the restart admission fence closed without a restart
A failed, refused, superseded, or thrown restart emission could leave the
reversible restart-signal admission fence closed forever: concurrent emitters
could overwrite the live rollback lease with a dead stand-in, the fenced body
had no try/finally, and the outer catch swallowed errors precisely because the
stuck fence made isGatewayRestartDraining() true. The gateway then rejected
every new task with GatewayDrainingError - silently - until an operator
restarted the process.

beginGatewayRestartSignalAdmission now returns null instead of stand-in
leases (single fence owner), emitPreparedGatewayRestart reopens the fence on
every non-delivery path via try/finally while preserving it whenever a queued
SIGUSR1 is unconsumed, refused-signal cleanup force-clears orphaned fences,
and admission close/reopen transitions are logged with their reason. The
self-contained SQLite restart-intent persistence moves to restart-intent.ts
to keep restart.ts within the LOC ratchet.

Fixes #107322
2026-07-14 16:14:48 +05:30
SL4N 45e651314c fix(cron): retry session lifecycle claim conflicts (#107236)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: SL4N <272086617+SL4N@users.noreply.github.com>
2026-07-14 02:02:39 -07:00
Peter Steinberger 9bf994f399 refactor(cron): trust Croner run results 2026-07-14 00:22:14 -07:00
zengLingbiao 692cb8dd9b fix(cron): reject non-string values in delivery target validation (#106952)
* fix(cron): reject non-string values in delivery target validation

assertNonBlankStringField had inverted logic — non-string values
(number, boolean, object) were silently accepted because typeof !== 'string'
was grouped with the undefined/null early return. The function name says
'assert non-blank string field' but it was bypassing validation for any
non-string type, defeating the purpose of input validation.

* test(cron): cover invalid delivery fields at entrypoints

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-13 21:48:15 -07:00
Vincent Koc dbf48c0df9 refactor(cron): privatize task history helpers (#106950) 2026-07-14 09:04:16 +08:00
Peter Steinberger 0934f561b3 test: consolidate cron model override coverage (#106938) 2026-07-13 17:47:08 -07:00
Wynne668 78305b65b1 fix(commitments): reject calendar-invalid due timestamps (#106236)
* fix(commitments): reject calendar-invalid due timestamps

* test(commitments): fix calendar validation clock

* fix(commitments): preserve timestamp interpretation

* fix(commitments): preserve valid RFC 3339 dates

* chore(commitments): remove contributor changelog edit

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-13 17:08:53 -07:00
wuqxuan 04b684c0da fix(cron): drop plain-text format from announce delivery footer (#106596)
* fix(cron): drop plain-text format from announce delivery footer

* test(cron): assert restricted tool policy forwarding

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-13 17:06:12 -07:00
Peter Steinberger cf8b57e7d0 feat(skills): scan session history for workshop ideas (#106766)
* feat: scan past sessions for skill proposals

* feat(ui): add progressive skill history scans

* fix(ui): keep skill history scans synchronized

* refactor: split skill history scan ownership

* style: fix mock helper formatting

* style: format skill history scan

* build: refresh skill history schema baselines

* build: refresh plugin SDK baseline after rebase

* perf(ui): keep startup request budget bounded

* fix(skills): satisfy history scan integration gates

* fix(ui): bound control ui startup chunks

* build: refresh plugin SDK API baseline

* build(ui): refresh self-learning translation memory

* refactor(ui): split skill workshop state

* fix(ci): refresh skill workshop gates

* fix(ci): satisfy skill history lint

* build: refresh plugin SDK baseline after main rebase
2026-07-13 16:15:50 -07:00
Peter Steinberger 334e7f3f21 feat(apps): add native mobile Automations parity (#106355)
* fix(apps): address native Skills review feedback

* feat(apps): add native Automations parity

* fix(ios): preserve automation editor selection

* fix(android): page automation discovery

* chore(apps): refresh native source inventory

* fix(ios): refresh invalid automation diagnostics

* chore(apps): sync native localization

* fix(cron): stabilize paginated snapshots

* refactor(cron): split pagination helpers

* fix(apps): address final native review feedback

* chore(apps): refresh native source inventory

* fix(ios): dedupe automation list actions

* chore: keep release note in PR context

* fix(ci): repair current main architecture gates

* fix(ios): default new skill requirement fields

* fix(ios): retain queued automation reservations
2026-07-13 15:35:32 -07:00
Peter Steinberger d1684f48a3 refactor: delete dead infra and config exports (#106019)
* refactor: delete dead infra and config exports

* refactor: preserve live infra and config contracts

* refactor(config): remove obsolete file-store lifecycle APIs

* refactor(infra): finish current-main dead export cleanup
2026-07-13 12:00:47 -07:00
Peter Steinberger 59003634ad refactor(cron): retire cron_run_logs; ledger-owned retention and cancellation
Stops the legacy run-log dual-write, auto-imports remaining rows and drops
the table at state-DB open (table-presence guard: self-heals downgrade
round-trips), keeps the newest 2000 terminal runs per job in the ledger,
retires cron.runLog config via doctor, and moves live-run cancellation to
src/cron behind the shared task control seam.

Part 2 of 2 for #106041.
2026-07-13 11:41:27 -07:00
Peter Steinberger bb273034f3 fix(cron): decouple cron history codec/migration from the agents sandbox tree
CI caught two real PR1 regressions. (1) Wiring the cron-run-logs migration
into state-db open transitively pulled agents/sandbox via the run-log error
codec, breaking ~13 tests that mock config/paths without STATE_DIR: split the
event->entry write codec into task-run-event-codec.ts and dependency-inject
the failover reason resolver so live run-log reads keep recompute while the
ledger read + migration stay dependency-light. (2) cron/service/task-runs.ts
reached into task-registry internals: route through the task-executor facade.
Known bounded limitation documented in the migration: legacy rows lacking a
stored errorReason are imported without a recomputed one (write-time authoring
is canonical going forward).
2026-07-13 11:32:57 -07:00
Peter Steinberger b842be157a chore(cron): decompose oversized modules for the changed-file LOC ratchet
Extracts startup-run repair, timer outcome finalization, task record
normalization, legacy task-sidecar row codec, and state-schema helpers
into focused modules; exempts .generated.d.ts files from the ratchet
(policy gap: schema evolution regrows generated Kysely types).
2026-07-13 11:32:57 -07:00
Peter Steinberger 4d9052929b feat(cron): serve cron run history from the task ledger
Cron executions now write full-fidelity task_runs rows (detail_json column,
store-key scoped) and cron.runs/CLI/task-maintenance read from the ledger;
legacy cron_run_logs dual-write stays as a revert safety net. Existing
history auto-imports at first state-DB open (verified against a production
DB copy: 2750/2750 rows, byte-identical parity, idempotent). Startup crash
recovery restores finished runs from finalized ledger rows instead of
reporting synthetic interruptions.

Part 1 of 2 for #106041.
2026-07-13 11:32:57 -07:00
Peter Steinberger dd4f36690a refactor: replace remaining worker pools with p-map (#106489)
* refactor: replace remaining worker pools with p-map

* test(tui): retry session rollover until accepted
2026-07-13 09:37:55 -07:00
Peter Steinberger 7a0efada74 improve: speed up lifecycle tests (#106501)
* test: remove fixed waits from lifecycle tests

* test: harden cron process liveness probe
2026-07-13 09:14:04 -07:00
Peter Steinberger e98c7dfbcb feat(cloud-workers): session placement, dispatch, and worker turn routing (#106332)
* feat(gateway-protocol): add session placement schema

Closed state discriminator for session execution placement (local/requested/provisioning/syncing/starting/active/draining/reconciling/reclaimed/failed), sessions.dispatch params, and worker-admission transcript/live cursor extensions. Swift protocol models mirror the schema.

* feat(state): add worker session placement table

worker_session_placements rows carry placement state, transition generation, worker ownership metadata, ACK cursors, and the turn claim columns used for atomic admission.

* feat(cloud-workers): add durable placement state machine store

SQLite-backed placement store split by concern: state table (placement-state), discriminated record types + shape invariants (placement-record), row codec + CAS transition values (placement-row-codec), atomic turn-claim admission/release/waiters (placement-turn-claims), and lifecycle CAS transitions (placement-store).

* feat(cloud-workers): sync workspaces and attach sessions to worker environments

Environment service session attachment + turn credentials, tunnel workspace commands over a dedicated SSH runner, and git/plain workspace sync into $HOME/.openclaw-worker/workspaces with an immutable manifest. Symlink escapes are rejected locally before transfer (macOS openrsync stat-fails them opaquely) and again by the remote manifest guard.

* feat(worker): run one-shot embedded turns from launch descriptors

Worker runtime executes a single embedded turn from a stdin launch descriptor and reports completed/failed/fenced on stdout for the gateway launcher. Terminal lifecycle live events are deferred past the final transcript flush; transcript projection helpers are shared via transcript-message instead of duplicated in the runtime.

* feat(cloud-workers): dispatch placements and route worker turns

Dispatch service drives local->requested->provisioning->syncing->starting->active with failure teardown (placement-dispatch-failure) and restart/runtime recovery incl. lost-worker reclaim (placement-dispatch-recovery). Worker turn launcher claims the placement turn atomically, builds a windowed launch descriptor (worker-turn-payload), runs the remote one-shot worker, and reconciles the committed transcript; agent runners route turns through the session placement admission provider.

* feat(gateway): expose session placement RPCs and startup reconciliation

sessions.dispatch RPC with lifecycle admission barriers, operator-facing placement projection on session listings, placement-aware session reset guard, and startup/interval reconciliation wiring for worker placements.
2026-07-13 08:03:53 -07:00
Peter Steinberger 26312fd0b0 refactor: remove gateway and channel dead exports (#106038)
* refactor: remove gateway and channel dead exports

* style: format config reload test

* refactor: remove newly dead gateway exports

* test: preserve approval audience coverage

* refactor: preserve gateway contracts while pruning exports

* test: retain gateway regression coverage

* test: restore gateway policy coverage

* test: close dead-export CI gaps

* fix: reconcile dead exports with latest main

* refactor: remove newly dead gateway runner export

* test: remove private worker verifier coverage

* test: preserve weak secret docs coverage

* fix: avoid gateway health import cycle

* fix: preserve node pairing type contract

* style: format talk relay test

* fix: preserve gateway protocol generation contract

* chore: refresh dead export baseline

* fix: preserve loaded target compatibility exports

* fix: preserve plugin SDK declaration resolution

* chore: refresh dead export baseline

* chore: refresh dead export baseline

* test(gateway): derive private worker service options
2026-07-13 05:47:05 -07:00
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 98e3f729bc refactor: remove dead plugin loader exports (#105937)
* refactor(plugins): trim activation and contract exports

* test(plugins): restore fixture cleanup

* refactor(plugins): trim install and loader exports

* test(plugins): fully reset loader caches

* refactor(plugins): trim metadata and catalog exports

* test(plugins): preserve catalog trust coverage

* refactor(plugins): trim provider and plugin exports

* refactor(plugins): trim runtime and tool exports

* test(plugins): update dead-export consumers

* test(plugins): remove empty dead-export suites

* refactor(plugins): align exports with split registry

* refactor(plugins): trim drifted loader exports

* style(plugins): format test fixtures

* refactor(scripts): use supported plugin APIs

* refactor(plugins): finish dead export cleanup

* chore(deadcode): refresh export baseline

* test(cli): mock production memory state

* chore(deadcode): sync latest export baseline

* fix(tests): keep plugin fixtures inside core

* chore(deadcode): refresh rebased export baseline

* chore(deadcode): sync current ratchets

* fix(plugins): retain reserved slot invariant

* fix(plugins): preserve dead-export invariants

* test(plugins): use neutral catalog query fixture

* test(plugins): satisfy catalog lint

* test(plugins): preserve integrity drift coverage

* fix(ci): register skill experience live proof
2026-07-13 01:29:33 -07:00
Peter Steinberger e2ec8283c4 refactor(deadcode): trim mid-size src exports (#105888)
* refactor(deadcode): trim auto-reply and CLI exports

* refactor(deadcode): trim cron and task exports

* refactor(deadcode): trim fleet and process exports

* test(deadcode): exercise live task and process seams

* test(fleet): cover stream redaction through owner module

* refactor(security): trim dead internal exports

* refactor(secrets): trim dead internal exports

* refactor(deadcode): trim remaining src exports

* refactor(deadcode): remove test-only runtime exports

* refactor(deadcode): trim pairing test exports

* refactor(deadcode): reconcile refreshed baseline

* test(auto-reply): deduplicate queue state imports
2026-07-13 00:42:56 -07:00
Peter Steinberger 4638b06454 refactor(runtime): remove deprecated timing aliases 2026-07-13 00:35:08 -07:00
Peter Steinberger 6f0072d574 improve(channels): reuse loaded plugin lookup view (#105977)
* perf(channels): memoize loaded plugin lookups

* chore(channels): update deadcode export baseline

* test(channels): preserve loaded registry mock exports
2026-07-12 22:35:23 -07:00
Peter Steinberger ac31549853 fix(cron): avoid ambiguous direct delivery retries (#105941) 2026-07-12 21:56:47 -07:00
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
Peter Steinberger 3616fba951 fix(gateway): make hot reload transactional (#105289)
* fix(gateway): make hot reload transactional

Replace partial reload side effects with a deferred transaction that publishes config, secrets, auth, and subsystem state together, and drains in-flight reload work before shutdown.

Co-authored-by: LZY3538 <293718838+LZY3538@users.noreply.github.com>

* fix(auth): preserve state-only credential ownership

Keep derived runtime snapshots in place for main-store state mutations so order refreshes do not look like credential replacement.

* fix(gateway): close reload transaction gaps

* fix(gateway): close merged reload gaps

* chore: move reload note to PR context

* fix(gateway): exclude restart emission root

---------

Co-authored-by: LZY3538 <293718838+LZY3538@users.noreply.github.com>
2026-07-12 18:16:15 -07:00
ZOOWH a2b55b5721 fix(cron): throttle session reaper after persistence errors (#105386)
* fix(cron): throttle session reaper after persistence errors

* refactor(cron): record session reaper attempts eagerly

* docs: keep release notes in PR context

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-12 17:36:40 -07:00
AnthonyStainer e3c338f664 fix(cron): keep memory search available with agent overrides (#104196)
* fix(cron): preserve memory search defaults

* test(cron): fix resolved agent config fixture

* refactor(cron): clarify agent config ownership

* test(cron): use redacted credential fixture

* test(cron): normalize redacted credential fixture

* chore(changelog): append cron memory fix

* chore(pr): defer release note ownership

---------

Co-authored-by: AnthonyStainer <18058056+AnthonyStainer@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-12 12:55:07 -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 9bdb2a5ac0 fix(cron): preserve successful run status after delivery failure (#105215)
* fix(cron): keep isolated run status ok when delivery fails

A successful isolated cron agentTurn whose post-run delivery phase returns
an error collapsed the execution status into the delivery error, so the
outer scheduled run persisted status=error even though the isolated session
ended successfully.

Decouple execution status from delivery outcome in finalizeCronRun: when the
agent payload is non-fatal and the run was not aborted, a delivery dispatch
error now keeps status=ok and records the failure separately via
delivered/deliveryAttempted plus delivery diagnostics, which drive the
already-decoupled run-log deliveryStatus (not-delivered). Aborted runs and
fatal agent payloads keep their error status.

Fixes #94058

* fix(cron): keep deliberate delivery-target refusals as error status

The #94058 fix kept isolated turn status=ok when post-run delivery
fails, but the broad `status === "error"` check also caught the
#91613 keyless implicit last-target refusal, which is a deliberate
delivery-target guard (errorKind "delivery-target") and must stay
status=error. Exclude that errorKind so genuine delivery dispatch
failures still become ok while target-guard refusals remain errors.

* fix(cron): surface successful run delivery errors to run logs

A successful isolated agent turn keeps status=ok when post-run delivery
fails (#94058), but the ok/not-delivered resolveRunOutcome branch only
forwarded delivery diagnostics and dropped the delivery dispatch error.
That left lastDeliveryError empty and the finished-event deliveryError
field blank, so CLI/UI/API run logs could not show why delivery did not
land for an otherwise successful run.

Thread the delivery error on a dedicated CronRunOutcome.deliveryError
field from resolveRunOutcome through executeDetachedCronJob and
applyJobResult into resolveDeliveryState, so it persists as
lastDeliveryError and reaches the finished event (and thus the run log)
without conflating it with a run-level error (lastError stays empty on a
successful run).

Add a service/run-log readback test proving the delivery error survives
the cron boundary into a persisted run-log entry, and extend the
isolated-turn regression to assert the dedicated deliveryError field.

* fix(cron): preserve successful delivery outcomes

* fix(cron): preserve startup delivery errors

* fix(cron): retain best-effort delivery errors

* fix(cron): preserve delivery errors on fallback paths

* fix(cron): preserve delivery errors on fallback paths

---------

Co-authored-by: Alix-007 <li.long15@xydigit.com>
2026-07-12 10:20:53 +01:00
Vincent Koc 68f2874126 chore(ui): refresh locales and repair cron lifecycle fixtures (#105100)
* chore(ui): refresh control ui locales

* test(cron): keep lifecycle fixtures in memory

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-12 15:53:06 +08:00
Vincent Koc ee17910f2a fix(cron): persist fast-mode session state (#105094) 2026-07-12 14:58:56 +08:00
Peter Steinberger 3d9b912b88 feat: sidebar session state slot, worktree/automation badges, archive disables bound cron jobs (#104730)
* feat(gateway): flag sessions with attached automations and disable bound cron jobs on archive

Session rows now carry hasAutomation, derived from a lifecycle-owned index
over the cron service's in-memory jobs; cron events push refreshed rows so
badges stay live. sessions.patch { archived: true } disables enabled cron
jobs bound to the session (locked binding re-check, internal/operator-admin
callers only); restore intentionally does not re-enable them.

Refs #104700

* feat(ui): sidebar session state slot and worktree/automation badges

The run spinner moves into a leading state slot shared with the unread dot,
keeping the timestamp visible during runs; muted fork/clock badges sit after
the title (outside the trail/action overlap so pinned rows and touch devices
keep them). New strings localized via ui:i18n:sync (English fallback pending
a keyed translation run).

Refs #104700

* test(gateway): pin cron binding broadcast test to the event mechanism

The shard shares one process; session-store state from earlier tests can make
the row load return null, which legitimately produces a keyless refresh
payload. Row-field projection stays covered by session-utils and
session-automation-index tests.
2026-07-12 06:19:01 +01:00
Vincent Koc b67417909b refactor: remove dead core and extension exports (#104963)
* refactor(agents): remove obsolete exec eligibility helper

* refactor(diffs): internalize viewer-only state

* refactor(qa-lab): internalize implementation helpers
2026-07-12 13:06:23 +08:00