Commit Graph

1337 Commits

Author SHA1 Message Date
Peter Steinberger
0d7fb8eb39 refactor(fs): adopt fs-safe 0.5 core primitives (#113705)
* refactor(fs): unify exclusive file publication

* fix(fs): fence stale lock reclamation

* refactor(fs): bound wiki scans and secret reads

* chore(fs): finalize fs-safe 0.5 compatibility

* fix(fs): preserve publication ownership and legacy mode

* fix(fs): fail closed on unverifiable lock owners

* fix(fs): preserve concurrent backup publications

* refactor(fs): preserve ambiguous backup outputs

* fix(fs): preserve mixed-version lock coordination

* refactor(file-transfer): adopt fs-safe archive extraction

* refactor(fs): add bounded walk and secret seams

* refactor(auth): replace proper-lockfile with fs-safe

* fix(fs): honor Windows mode override casing

* refactor(snapshot): adopt fs-safe publication

* refactor(memory-wiki): adopt prunable root walks

* refactor(fleet): adopt bounded archive restore

* fix(fs): preserve post-publication ownership receipts

* refactor(fs): harvest final fs-safe primitives

* style(fs): clean harvest lint

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

* refactor(snapshot): adopt native Windows ACL facts

* refactor(fs): adopt hardened atomic outputs

* fix(fs): scope lock reentrancy to logical owners

* chore(config): lower env var count budget

* fix(deps): adopt published fs-safe 0.5.0

* fix(ci): align SDK surface ratchets

* fix(ci): regenerate SDK API baseline after rebase

* fix(fs): preserve owner-scoped file lock nesting

* fix(ci): refresh SDK API baseline for file locks

* fix(fs): separate SQLite and file lock reentrancy

* fix(imessage): bound pinned attachment reads

* fix(agents): narrow session-key lock options

* fix(fs): preserve fs-safe 0.5 compatibility contracts

* fix(windows): retain private SQLite directory owner

* refactor(sqlite): centralize exclusive coordinator

* refactor(snapshot): isolate Windows ACL policy

* fix(windows): retain snapshot ACL inspector

* chore(config): realign env budget after rebase

* test(agents): accept canonical sandbox escape error

* docs(changelog): defer fs-safe release note
2026-07-28 03:41:47 -04:00
Peter Steinberger
6dbe7ff1e2 perf(catalog): memoize probes and single-flight identical list requests (#114961) 2026-07-28 02:00:27 -04:00
Peter Steinberger
27f62f3e8e fix(codex): verify native patches and honor fast mode (#114907) 2026-07-28 00:00:49 -04:00
Peter Steinberger
f036ed43a2 fix(codex): prevent long conversations slowing on thread resume (#114882)
* fix(codex): reduce native thread resume overhead

* test(codex): register native attempt connection shard

* fix(codex): keep oversized rollouts on bounded fast path
2026-07-27 23:56:44 -04:00
Peter Steinberger
577a0642fa fix(plugin-sdk): classify loopback hosts consistently (#114832)
* fix(plugin-sdk): expose loopback host classifier

* fix(ollama): remove stale host normalizer import

* chore: keep release notes in PR context
2026-07-27 22:55:44 -04:00
Peter Steinberger
f2a12916d7 fix(codex): refuse Platform routes on a subscription-signed native Codex home (#114719)
A user-home app-server keeps its native Codex account, and OpenClaw verified only
half of that contract. A subscription route was checked against the native
account, but a Platform (API-key) route was not: an operator signed in to Codex
with a ChatGPT subscription who selected an API-billed model silently spent their
plan. Both directions of the same billing boundary now share one account/read
check. An absent account is left alone, since a native home may serve a custom
model provider that reports no OpenAI account at all.

The home-scope rule behind #114397 was also expressed four times: two
prepared-auth call sites spread it in conditionally from raw plugin config, two
others read resolved start options, and the supervision connection applied its
own default inline. resolveCodexAppServerHomeScope now owns it, and homeScope is
a required argument of resolveCodexAppServerPreparedAuthHandoff, so a new call
site that forgets it fails to compile instead of failing every turn.

Docs dropped the stale user-home paragraph that still described the startup
failure #114397 removed and told operators to delete a working OpenAI profile.
2026-07-27 22:42:18 -04:00
Peter Steinberger
4273ca9dbd refactor(sessions): remove file-era transcript runtime (#113233)
* refactor(sessions): keep helper transcripts in memory

* refactor(sessions): remove file-era transcript storage

* test(sessions): use SQLite identity in attempt persistence

* test(codex): isolate legacy transcript fixtures

* fix(sessions): preserve SQLite transcript identity

* fix(sessions): harden transcript lifecycle invariants

* fix(sessions): validate transcript identities

* fix(sessions): close identity compatibility gaps

* fix(sessions): preserve leaf and plugin identities

* fix(sessions): retain dispatch transcript targets

* fix(sessions): preserve active transcript context

* fix(sessions): isolate artifact accounting

* fix(sessions): bound SQLite usage accounting

* fix(sessions): retain bounded latest usage

* fix(sessions): align rebased transcript targets

* test(sessions): align accessor scope fixture

* fix(telegram): derive SQLite transcript identity

* refactor(sessions): remove file-era compaction residue

* chore(sessions): lower max-lines baseline

* fix(sessions): preserve structured transcript identity

* test(sessions): align doctor identity assertions

* fix(sessions): isolate default SDK database

* refactor(sessions): remove dead file-era exports

* fix(sessions): reconcile SQLite transcript identity

* fix(sessions): pass checkpoint identity explicitly

* test(sessions): make entry field probe explicit

* test(sessions): satisfy transcript cleanup lint

* test(sessions): align diagnostics identity proof

* fix(sessions): finish transcript runtime teardown

* fix(sessions): preserve transcript identity invariants

* fix(sessions): harden transcript compatibility edges

* fix(sessions): preserve checkpoint transcript anchors

* fix(sessions): preserve SQLite lifecycle invariants

* fix(sessions): retarget compaction successors

* test(sessions): preserve transcript fixture semantics

* feat(plugin-sdk): add command transcript targets

* fix(sessions): serialize transcript rewrites

* fix(sessions): validate legacy successor identity

* fix(sessions): normalize compaction ownership

* fix(sessions): validate successor identity before adoption

* fix(sessions): preserve plugin transcript ownership

* fix(sessions): carry transcript identity through commands

* fix(sessions): import legacy checkpoint artifacts into SQLite

* fix(sessions): preserve successor transcript ownership

* fix(sessions): align transcript consumers with target identity

* fix(sessions): scope transcript token estimates

* fix(sessions): retain agent identity across lifecycle hooks

* fix(sessions): resolve scoped SQLite targets

* fix(sessions): isolate lifecycle transcript targets

* fix(sessions): validate compaction agent ownership

* fix(sessions): preserve reset and cleanup lifecycle

* fix(sessions): serialize prompt cleanup lifecycle

* fix(sessions): remove stale lock import

* fix(sessions): preserve reset target context

* fix(sessions): fence prompt reload takeover

* fix(sessions): unblock abort and default lifecycle reads

* fix(sessions): validate legacy successor scope

* fix(sessions): reject metadata-only runtime rows

* fix(sessions): propagate custom transcript stores

* fix(sessions): preserve adopted retry targets

* fix(sessions): allow unkeyed usage reads

* fix(sessions): harden runtime target boundaries

* fix(sessions): serialize retry transcript writes

* fix(sessions): bound prompt reload disposal

* fix(sessions): complete retry marker identity

* fix(sessions): keep legacy marker identity minimal

* test(sessions): tighten teardown fixture types

* fix(sessions): preserve compatibility target identity

* test(sessions): persist post-checkpoint boundary turn

* test(sessions): align runtime store mock contracts

* style(sessions): simplify persisted identity guard

* fix(sessions): prefer complete typed targets

* fix(sessions): recover legacy marker targets

* test(sessions): align marker lookup fixture scope

* fix(sessions): validate partial transcript targets

* fix(sessions): reconcile partial transcript identities

* fix(sessions): canonicalize compatibility identities

* test(sessions): cover compatibility aliases

* fix(sessions): adopt legacy successor identity

* fix(sessions): preserve usage read identity

* fix(sessions): preserve partial marker compatibility

* fix(sessions): validate legacy successor mappings

* fix(sessions): reconcile marker store mappings

* fix(sessions): preserve legacy fallback identity

* fix(sessions): harden marker alias resolution

* fix(sessions): prefer verified successor aliases

* fix(sessions): resolve preferred marker aliases

* fix(sessions): serialize cleanup admission

* fix(sessions): align marker lookup scopes

* fix(codex): type marker alias summaries

* style(sessions): satisfy changed lint

* test(sessions): align structured target assertions

* fix(sessions): reconcile latest identity contracts

* fix(sessions): validate transcript identity boundaries

* docs(sessions): explain stable registry keys

* fix(sessions): harden compatibility target round trips

* fix(sessions): port usage identity to split modules

* test(sessions): align subagent transcript identity

* fix(sessions): finish transcript identity migration

* fix(agents): route subagent completion capture through transcript targets

* fix(agents): settle SQLite prompt handoff during cleanup

* chore: shrink max-lines baseline after teardown

* fix(sessions): port teardown across split runtime owners

* fix(sessions): carry transcript targets through split owners

* test(agents): use SQLite compaction target in abort coverage

* chore: retain unrelated max-lines suppressions

* chore: shrink max-lines baseline after main splits

* style(agents): const compaction checkpoint locals

* fix(sessions): harden SQLite teardown boundaries

* test(sessions): use typed metadata in predicate isolation fixture

* test(agents): cover malformed settlement rejections lint-safely

* fix(sessions): close remaining SQLite identity races

* fix(agents): fail closed on incomplete successor targets

* fix(sessions): preserve transcript identity fallbacks

* fix(agents): preserve session-key abort admission

* fix(trajectory): validate incomplete export targets

* test(sessions): drop retired pricing cache imports

* fix(sessions): validate partial transcript identities

* fix(sessions): close transcript identity edge cases

* fix(plugins): reserve retired transcript locator slot

* fix(sessions): scope transcript locks by target

* style(sessions): simplify SDK initialization error

* fix(sessions): preserve initialized transcript state

* fix(codex): verify mirrored history session keys

* fix(sessions): reject stale transcript ownership

* fix(sessions): anchor asynchronous transcript ownership

* fix(sessions): measure active transcript state

* fix(sessions): preserve scoped transcript compaction

* fix(sessions): harden transcript identity and lifecycle

* fix(sessions): resolve scoped command transcript stores

* fix(sessions): make transcript appends failure-atomic

* fix(sessions): enforce scoped transcript ownership

* fix(sessions): reject cross-owner transcript handoffs

* fix(sessions): fence cleanup transcript ownership

* fix(sessions): retire stale write ownership contexts

* fix(sessions): preserve pending session migration state

* fix(sessions): validate migrated transcript ownership

* fix(sessions): validate usage transcript targets

* fix(sessions): clear predecessor transcript metadata

* fix(sessions): align durable session event targets

* fix(sessions): fence late prompt handoffs

* fix(sessions): fence lifecycle transcript fallbacks

* fix(sessions): bound zero-length memory capture

* fix(sessions): preserve transcript teardown ownership

* fix(sessions): reject duplicate cleanup ownership

* fix(sessions): serialize runtime writes with sqlite leases

* fix(sessions): close sqlite teardown concurrency gaps

* fix(sessions): preserve nested lifecycle failures

* fix(sessions): canonicalize sqlite transcript ownership

* fix(sessions): settle disposed prompt handoffs

* fix(sessions): resolve canonical attempt lock targets

* test(sessions): align canonical target fixtures

* test(sessions): retire redundant jsonl parser coverage

* refactor(sessions): split active transcript cursors

* test(memory): retire legacy marker fixture

* fix(sessions): preserve canonical transcript access after rebase

* fix(sessions): fence prompt lease and return transcript targets

* fix(sessions): colocate transcript leases with target store

* fix(sessions): canonicalize transcript lease and worker targets

* fix(sessions): preserve plugin and fork identity markers

* fix(sessions): complete sqlite transcript target migration

* fix(sessions): integrate canonical followup identity

* fix(sessions): preserve bounded transcript topology

* fix(sessions): validate transcript identity boundaries

* fix(context): separate caller and successor targets

* test(sessions): split persistence compatibility coverage

* test(sessions): preserve fixture topology efficiently

* chore(sdk): refresh plugin api baseline

* test(agents): align compaction lock target mocks

* test(sessions): seed malformed transcript fixtures directly

* fix(agents): canonicalize transcript compatibility inputs

* fix(agents): type optional tool result ids

* test(ci): stabilize loaded process timing

* test(tui): wait for collect queue admission
2026-07-27 22:33:24 -04:00
Peter Steinberger
b2f137797b fix(codex): isolate QA sandbox from production policy (#114830) 2026-07-27 21:05:41 -04:00
Peter Steinberger
37cf0c6064 improve: reduce GPT-5.6 coding harness overhead (#114574)
* improve: reduce GPT-5.6 coding harness overhead

* refactor: extract runtime parity timing helpers

* fix(qa): verify native apply-patch runtime parity

* fix(qa): use mock patch execution evidence

* fix(qa): preserve workspace templates in full syncs

* fix(qa): make rejected patch fixtures deterministic

* fix(qa): prove apply-patch workspace containment

* fix(qa): expose runtime prompt-cache usage

* fix(codex): confine forced private QA patch turns

* fix(qa): verify native patch execution and sandbox precedence

* fix(qa): execute native patches and prove disk mutation

* fix(codex): avoid duplicate native patch registration

* perf(agents): keep code mode catalog guidance compact

* fix(qa): make native Codex patch evidence deterministic

* fix(qa): recognize native sandbox denial errors

* fix(qa): advertise native Codex mock model capabilities

* fix(qa): seed native Codex mock model catalog at startup

* fix(qa): recognize native Codex patch denial results

* fix(ci): repair Codex harness parity checks

* fix(qa): distinguish unknown prompt-cache measurements

* fix(qa): accept native Codex project patch denials

* fix(ci): isolate runtime parity report contracts

* fix(codex): eliminate native runtime transport overhead

* fix(qa): consume runtime parity report contract

* fix(qa): compare matched runtime timing captures

* fix(qa): type native response delta context

* fix(qa): satisfy native codex websocket lint
2026-07-27 19:24:52 -04:00
Peter Steinberger
960b050add refactor(extensions): remove orphaned shadow trial and retired config aliases (#114709)
* refactor(memory-core): remove orphaned shadow trials

* refactor(qqbot): migrate direct voice upload formats

Release note: QQBot configs using voiceDirectUploadFormats now migrate through openclaw doctor --fix to audioFormatPolicy.uploadDirectFormats at root and account scope. Existing nested uploadDirectFormats values win conflicts, and runtime reads only the nested policy.

* refactor(feishu): migrate tools base alias

Release note: Feishu configs using tools.base now migrate through openclaw doctor --fix to tools.bitable at root and account scope. Existing bitable values win conflicts, and runtime accepts only the canonical key.

* refactor(extensions): remove dead runtime state

* chore(config): refresh bundled channel metadata

* refactor(codex): keep realtime fallback type private

* test(ci): align QA compatibility scenario count
2026-07-27 17:12:41 -04:00
Peter Steinberger
f4058528e5 refactor(agents): centralize message-tool and direct-visibility predicates (#114720)
* refactor(agents): centralize message-tool and direct-visibility predicates

* refactor(agents): unexport classifyTool and drop redundant union
2026-07-27 16:51:20 -04:00
ClawSweeper
e073d17be1 perf(codex): prewarm app server during attempt setup (#114551)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-27 11:02:16 -07:00
Peter Steinberger
8f8e40dabe perf(gateway): share one node.list snapshot across session catalog providers (#114646) 2026-07-27 13:14:07 -04:00
Peter Steinberger
3f37731175 docs(agents): surface hidden tool capabilities in model-facing descriptions (#114516) 2026-07-27 07:20:25 -04:00
Peter Steinberger
a854cea4f7 fix(codex): stop supervision flag from gating the whole plugin config (#114413)
The plugin re-resolved its own enable state with supervision.enabled as
enabledByDefault, so an operator who only declared plugins.entries.codex.config
(auto-enabled by core) silently lost every codex setting, including
appServer.homeScope=user, whenever supervision was absent or off.

Use a live plugin config block as the plugin-side default, matching core's
plugin-tool-configured auto-enable and the onepassword convention. Supervision
stays gated in its own tool surface.
2026-07-27 04:34:38 -04:00
Peter Steinberger
669db2968f refactor(agents): retire TOOLS.md into an AGENTS.md section with a doctor migration (#113966)
* fix(agents): stop retired attestation hashes from faking a vanished workspace

* feat(agents): migrate TOOLS.md content into the AGENTS.md tools section

* refactor(agents): drop TOOLS.md from the workspace bootstrap set

* refactor(policy): read tool policy entries from AGENTS.md

* docs: describe local tool notes as an AGENTS.md section

* test(codex): drop TOOLS.md developer-instruction coverage with the removed path

* test(agents): cover the TOOLS.md doctor migration behaviors

* refactor(doctor): satisfy TOOLS.md migration lint

* test(agents): split workspace attestation survival coverage

* refactor(codex): simplify workspace context basenames

* refactor(doctor): keep TOOLS.md migration helpers module-local

* docs: regenerate docs map

* fix(doctor): keep migration claims fresh

* fix(doctor): preserve nested tool notes

* refactor(doctor): split tools migration helpers

* refactor(doctor): limit TOOLS.md migration to workspace root

* style(doctor): keep migration under line limit

* fix(doctor): recover interrupted AGENTS publish

* docs(hooks): describe root-only TOOLS.md migration accurately

* fix(doctor): preserve migrated tool guidance visibility

* test(agents): regenerate prompt snapshots after rebase

* fix(policy): block evaluation while TOOLS.md is unmigrated

* fix(doctor): check merged bootstrap budget per agent

* fix(doctor): keep budget helper internal

* refactor(doctor): keep migration budget helpers to their consumers
2026-07-27 03:56:30 -04:00
Peter Steinberger
65cce37480 fix(codex): keep user-home app-servers on native Codex auth (#114397)
A prepared OpenClaw auth handoff was still resolved for connections that
target the operator's native Codex home, so every turn failed with
"Prepared Codex auth requires an isolated app-server home." once a stored
OpenAI profile produced a prepared model route. User-home mode now keeps
its native account for both subscription and Platform routes, matching the
documented contract; the shared-client guard stays as the backstop.
2026-07-27 03:19:06 -04:00
Peter Steinberger
7b71d5608e perf(gateway): reuse session catalog entry snapshots per request (#114358)
* perf(gateway): reuse session catalog entry snapshots

* chore(gateway): satisfy knip and typed-test lanes for catalog snapshot
2026-07-27 02:14:11 -04:00
Peter Lee
0406e66369 fix(ui): keep stable chat rows in insertion order and only sort live tool/stream items by timestamp (#113266)
* fix(ui): keep stable chat rows in insertion order and only sort live tool/stream items by timestamp

* fix(ui): keep live rows within current turn

* fix(ui): keep current work above queued turns

* fix(ui): keep streamed replies above queued turns

* fix(ui): preserve reconnecting run order

* fix(ui): preserve causal terminal ordering

* fix(ui): bound replay rows to owning turns

* fix(ui): keep question summaries in owning turns

* fix(ui): scope question run ownership to session

* fix(ui): restore reconnecting chat run identity

* fix(ui): remove unused chatItemTimestamp import in chat-thread-build.ts

* fix(ui): correlate question summaries with agent runs

Co-authored-by: Peter Lee <li.xialong@xydigit.com>

* chore(i18n): refresh native source baseline

Co-authored-by: Peter Lee <li.xialong@xydigit.com>

* fix(ui): remove unused chatItemTimestamp export and split tool-stream test file

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-27 02:08:22 -04:00
Jesse Merhi
d7627d6f4c refactor(prompt): use plain inbound context labels and drop system-tag sanitizer (#112000)
* refactor(prompt): plain inbound context labels with a provenance marker

Replaces trust-worded inbound context labels ("(untrusted metadata)",
"(untrusted, for context)") with plain labels plus a fixed provenance
marker suffix appended to every OpenClaw-injected context header.

Detection keys on the marker, not label text, so strippers stay correct
across UI, TUI, replay, /trace segmentation, memory recall, and the Swift
chat preprocessor. Drops sanitizeInboundSystemTags in favor of the marker
boundary plus trusted system-prompt narration.

Renames the untrusted-named plugin SDK context identifiers to
channel-provenance names, keeping deprecated aliases registered for
removal after 2026-09-08.

Adds `openclaw doctor --fix` migrations that rewrite legacy inbound
labels in stored SQLite transcripts and purge legacy envelope-
contaminated LanceDB recall rows.

* fix(ci): resolve gate failures for plain inbound context labels

- doctor sqlite readers: open read-only connections via openNodeSqliteDatabase
  so the Kysely connection-boundary guardrail holds; unexport the now-internal
  transcript snapshot type (Knip unused-export gate).
- compat registry: split the record table into registry-records.ts and
  plugin-sdk-subpath-records.ts. The new compat record pushed registry.ts past
  the 700-line oxlint cap; suppressions are disallowed, so follow the existing
  sibling record-module pattern. Public exports and PluginCompatCode literals
  unchanged.
- acp-runtime test: assert current finalization behavior (newline normalization
  only). The bracket de-fang and System: rewrite it expected were removed with
  sanitizeInboundSystemTags; forged system lines are neutralized at the
  system-event queue, the single chokepoint feeding the System:-per-line render.
- regenerate docs_map and the plugin SDK API baseline manifest.

* fix(prompt): harden inbound context label migration and drop in-band sanitizer

Review follow-ups on the plain-label + provenance-marker change:

- Remove src/security/system-tags.ts. Rewriting inbound text to neutralize
  look-alike `System:`/`[System]` markers corrupted legitimate user text and is
  not a real injection boundary; role separation plus external-content wrapping
  is. Explicit product decision, recorded at the system-event queue.
- Narrow the LanceDB legacy-row purge so it cannot delete benign memories. It
  now requires a complete known legacy sentinel line, a legacy label followed by
  a fenced JSON body, or the complete legacy external-content header. The prior
  predicates matched ordinary prose such as `Notes (untrusted metadata):`, and
  deletion is irreversible.
- Make explicit-empty canonical ChannelStructuredContext win over the deprecated
  alias via a present/absent result instead of collapsing `[]` to undefined.
- Keep `\r?` in the active-memory doctor rule. It is the only rule spanning the
  header's line break, migrated assistant rows skip newline normalization, and
  without it the marked-header replace wins and the body strips to empty. Added
  a CRLF regression test.
- Fix stale comments that described removed behavior, and cover the Swift
  prose-block strip path.

Claude-Session: https://claude.ai/code/session_01WNzsPddQmxy9Y7jKD4wAxH
2026-07-27 11:27:53 +10:00
keshavbotagent
46f4018ff9 fix(codex): recover in-place session resets (#114056)
* fix(codex): recover in-place session resets

* fix(codex): preserve retired generation fences

---------

Co-authored-by: Josh Lehman <josh@martian.engineering>
2026-07-26 16:49:57 -07:00
Peter Steinberger
f6131a4fbf build(deps): remove npm shrinkwrap; mirror pnpm lock into transient package locks (#114006)
* build(deps): remove npm shrinkwrap; mirror pnpm lock into transient package locks

npm 12 removed shrinkwrap (command + tarball/root loading). Delete all 82
committed npm-shrinkwrap.json files and stop publishing lockfiles; keep
pnpm-lock.yaml as the single reviewed dependency boundary. The generator
becomes scripts/generate-npm-package-lock.mjs and feeds plugin bundling via
a transient package-lock.json + npm ci (works on npm 11 and 12). Tarball
validation treats the published 2026.7.2 beta train as a shrinkwrap
transition; self-update npm detection now uses install topology instead of
the shipped shrinkwrap.

* fix(deps): repair lint, deadcode, and test-type lanes for the npm 12 migration

- sort integrity comparisons with an explicit comparator (oxlint)
- keep resolveBunGlobalNodeModules module-local (knip unused-export gate)
- model npm pack --json as npm<=11 array / npm 12 name-keyed object
- default calver destructuring in the tarball test fixture
2026-07-26 01:29:55 -04:00
Peter Steinberger
3a72688ce6 test(codex): preserve realtime test owner (#113962) 2026-07-25 18:25:17 -07:00
Colin Johnson
de9ed64c29 feat(talk): enable GPT Live with Codex OAuth (#113354) 2026-07-25 20:41:27 -04:00
Peter Steinberger
1bce047953 fix(ci): repair plugin prerelease contracts (#113820) 2026-07-25 12:38:31 -07:00
Peter Steinberger
332006bc1f test: consolidate OpenClaw test state fixtures (#113576)
* test: consolidate OpenClaw test state fixtures

* test(plugin-sdk): expose isolated test state

Promote the isolated OpenClaw test-state lifecycle through a narrow published Plugin SDK subpath so extension tests no longer import private core helpers. This intentional SDK surface addition is maintainer-approved.

* test: use SDK test-state seam in extensions

Route bundled extension suites through the focused repo-local Plugin SDK test-state entrypoint and remove the Codex projector harness exports made stale by fixture consolidation. Keep the seam out of production builds and published package artifacts while auditing its real consumers in the full-tree deadcode scan.

* test(plugins): map test-state in package boundaries
2026-07-25 05:30:52 -07:00
Masato Hoshino
bdcc5d54a5 fix(agents): honor run abort signal in image and pdf tools (#112644)
* fix(agents): honor run abort signal in image and pdf tools

The image and pdf agent tools declared `execute: async (_toolCallId, args)`
and dropped the run abort signal that `wrapToolWithAbortSignal` supplies as
the third execute argument. The wrapper only races the execute promise, so an
aborted run kept sequentially downloading images/PDFs (up to the per-tool cap,
each up to the byte cap) and still issued a paid vision/PDF-model call for a
dead run.

Thread the signal into the existing `requestInit: { signal }` seam (which the
media fetch layer already merges into the download fetch) and add
`signal.throwIfAborted()` between sequential loop items and before the paid
model call. No new media-options signal field; non-abort behavior is unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(agents): keep the pdf test suite under the lint ceiling; guard model dispatch

Follow-up on the abort-signal change, resolving the check-lint failure and a
review finding on the same seam.

max-lines
---------
Adding the two pdf abort tests pushed src/agents/tools/pdf-tool.test.ts to 1018
effective lines against a ceiling of 1000, failing check-lint. Resolved without
touching config/max-lines-baseline.txt — a suppression there would also have
tripped the max-lines ratchet.

- The new tests declared their own `describe` with `beforeEach`/`afterEach`
  hooks identical to the existing `describe("createPdfTool")`. They exercise
  that same tool, so they now live in it and the duplicated scaffolding is gone.
- `stubPdfToolInfra`, `createPdfModelRegistry` and `FAKE_PDF_MEDIA` moved to
  pdf-tool.test-support.ts, which already exists for exactly this. They go
  through `createPdfToolInfraStub(completeMock)` rather than being exported
  directly, because the stub wires the suite's own `complete` mock into the
  model registry and vi.mock handles are file-scoped. All 21 existing call
  sites are unchanged.

Abort propagation into model dispatch
-------------------------------------
The previous revision stopped cancellation at download boundaries and before
the first model call, but `runImagePrompt`/`runPdfPrompt` never saw the signal.
A run cancelled while the first provider request was in flight could still
issue the remaining ones — the image path dispatches `describeImage` once per
image in a sequential loop, so a dead run kept paying for every later image.

Both now take an optional `signal` and check it immediately before each
provider dispatch (3 sites in image-tool, 4 in pdf-tool).

Forwarding the signal further, into the provider transports themselves, is a
different seam and is deliberately left out of this PR.

Also declares `requestInit` on `ImageToolLoadWebMediaOptions`. The local facade
omitted it while the underlying loader accepts it (web-media.ts declares it and
forwards it to readRemoteMediaBuffer), so the option worked at runtime and only
compiled because spread properties skip excess-property checking. A non-spread
call site would not have.

tsgo core + core-test, oxlint, oxfmt clean; pdf-tool and image-tool suites 266
tests pass.

* test(agents): prove in-flight media aborts

* test(agents): narrow PDF loader options

* test(agents): reject abort mocks with errors

* fix(agents): propagate media cancellation

* test(agents): type PDF abort fixture

* test(agents): type prepared runtime snapshot

* fix(agents): normalize abort rejection errors

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-25 05:17:09 -07:00
Peter Steinberger
9e9615d7c1 refactor(codex): prune migration pipeline (#113536) 2026-07-25 00:58:11 -07:00
Vincent Koc
749dbcb2a7 refactor(media): consolidate generated media byte limits (#113556) 2026-07-25 15:39:49 +08:00
Peter Steinberger
4f1b5da9d8 refactor(codex): split app-server config (#113552)
* refactor(codex): split app-server config

* refactor(codex): keep config helper types private
2026-07-25 00:36:50 -07:00
Peter Steinberger
d734df9d0f test(codex): read canonical steering terminal outcome (#113416) 2026-07-24 14:39:27 -07:00
Jason (Json)
ee606def49 fix(codex): stop Computer Use readiness stalls across fallbacks (#113393)
* fix(codex): bound computer use readiness preflight

* chore(codex): keep service status internal
2026-07-24 14:27:53 -06:00
scotthuang
2900026b33 fix: stop selected channel sessions from WebChat (#111108)
* fix: stop selected channel sessions from WebChat

* fix: clear channel working state after stop

* fix: cancel queued turns before session abort

* fix: replay pending stops after reconnect

* fix: align stop lifecycle test fixtures

* fix(ui): bind pending aborts to gateway client

* test(ui): keep chat pane specs within line limit

* chore(ios): refresh native i18n inventory

* chore: retrigger PR checks

* fix(system-agent): avoid blocking TUI catalog discovery

* fix: preserve session abort ownership

* test: align abort coverage with current main

* test: assert scoped session abort broadcast

* fix(agent-runs): expose SDK runtime abort state

* fix(ui): clear queued main-session stops by scope

* fix(ui): replay only exact run aborts

* fix(gateway): protect session abort cleanup

* fix(ui): narrow session abort intent

* test(ui): avoid unbound request assertions

---------

Co-authored-by: scotthuang <scotthuang@tencent.com>
Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>
2026-07-24 14:36:18 -05:00
Peter Steinberger
756b6f7009 fix(release): repair plugin prerelease regressions (#113373) 2026-07-24 10:20:32 -07:00
Peter Steinberger
6235ea55ac refactor(codex): split command handlers (#113335)
* refactor(codex): split command handlers

* refactor(codex): keep helper types private
2026-07-24 07:29:44 -07:00
Peter Steinberger
7584d9585b refactor(codex): consolidate app-server test fixtures (#113246)
* test(codex): consolidate app-server fixtures

* test(codex): align legacy heartbeat coverage
2026-07-24 01:54:55 -07:00
Jason (Json)
aee46707ba feat(plugins): support manifest-declared MCP Apps in native plugins (#113224)
* feat(plugins): load native manifest MCP servers

* fix(gateway): advertise proxied plugin surface ports

* fix(codex): retain MCP App transcript previews

* fix(codex): render native MCP apps inline

* fix(mcp-apps): resolve harness-native views by session

* fix(codex): normalize null MCP result metadata

* fix(ui): give inline MCP apps full message width

* test(codex): use generic native MCP App fixtures

* chore(plugin-sdk): refresh harness runtime baseline

* refactor(codex): isolate native MCP App contracts

* fix(codex): satisfy native app CI contracts

* fix(ci): scope automation app tokens

* chore(ci): defer token scopes to current main
2026-07-24 01:43:48 -06:00
joshavant
bd559a98ed fix(cron): migrate scheduled authority provenance 2026-07-24 01:24:03 -05:00
joshavant
5d21ba0a2a fix(cron): bind scheduled authority to creator accounts 2026-07-24 01:24:03 -05:00
joshavant
d8f1f098e5 fix(cron): honor explicit authority for senderless runs 2026-07-24 01:24:03 -05:00
Peter Steinberger
3b7b2a2a1f chore: update dependencies and migrate major contracts (#112963)
* build(deps): complete latest dependency migrations

* fix(deps): satisfy updated dependency types

* fix(deps): hold incompatible build tooling

* fix(deps): preserve portable tooling contracts

* build(deps): allow reviewed fresh transitive releases

* fix(deps): repair major upgrade validation

* build(deps): regenerate current dependency graph

* fix(logging): keep tslog adapter type private

* fix(agents): narrow grep subprocess handle

* fix(codex): prefer pinned managed binary

* fix(codex): fence managed native provenance

* build(deps): align codex ACP with managed harness

* fix(slack): use socket-mode Undici runtime

* fix(slack): detect cross-runtime responses

* fix(slack): bridge package-owned fetch types

* fix(deps): retain tslog v4 JSON contract

* build(plugin-sdk): refresh logging API manifest
2026-07-23 21:21:01 -07:00
Peter Steinberger
61f036f748 refactor(agents): close embedded attempt terminal outcomes (#113201)
* refactor(agents): close embedded attempt outcomes

* test(agents): align trajectory terminal fixture

* refactor(codex): share attempt failure type

* fix(codex): retain projector result contract

* test(agents): keep terminal projections test-only

* chore(plugin-sdk): refresh attempt terminal baseline
2026-07-23 19:56:03 -07:00
Peter Steinberger
bb657eec93 refactor(config): retire redundant settings (#113174)
* refactor(config): retire redundant settings

* style: apply current formatter

* chore: update plugin sdk baseline

* fix: keep Codex tool caps context-aware

* chore: remove stale imports

* test: align WhatsApp QA debounce config

* fix(config): clean up retired config checks

* fix(ci): align config cleanup checks
2026-07-23 17:45:02 -07:00
Jason (Json)
09c6d66d19 fix(ui): render managed chat media under base paths (#113163) 2026-07-23 16:49:14 -06:00
Peter Steinberger
3e2b3ea4d5 feat(cron): database-backed heartbeat monitor scratch replaces HEARTBEAT.md (#112967)
* feat(cron): move heartbeat context into database-backed per-job cron scratch

- new additive cron_job_scratch SQLite table (revision tombstones keep
  compare-and-swap monotonic across unset/recreate; 256KiB cap)
- heartbeat runner reads monitor scratch instead of workspace HEARTBEAT.md;
  heartbeat_respond gains a private scratch replacement parameter
- openclaw doctor --fix migrates HEARTBEAT.md into scratch (hash-verified,
  archived under state backups, idempotent, symlink-contained)
- gateway cron.scratch.get/set admin RPCs + openclaw cron scratch CLI
- workspace bootstrap no longer seeds HEARTBEAT.md; Codex heartbeat file
  guidance removed; docs and prompt snapshots updated

* fix(cron): review round 2 — shared-workspace heartbeat migration and non-default agent monitors

- doctor migration groups agents by heartbeat source file and imports into
  every monitor before archiving/removing the shared file once
- exempt heartbeat payloads from the main-session default-agent restriction:
  monitors only poke the wake bus, so non-default agents converge again
- document why disabled monitors retain their last cadence (config default
  already resolves before the fallback)

* fix(cron): honor configured cron store, legacy heartbeat fallback, and safer doctor claim

* fix(cron): claim HEARTBEAT.md before committing scratch and restore without clobbering

* fix(cron): pin migration CAS to precondition revision, re-verify claim on release, archive first, report scratch as pending

* docs(heartbeat): remove retired config options

* fix(cron): crash-recoverable migration claims, partial-import rollback, latest-response scratch pairing

* test(heartbeat): keep latest scratch proposal paired

* fix(cron): roll back committed scratch on changed-claim release and restore no-row state

* fix(cron): revision-guarded rollback delete and recreated-file detection on claim release

* fix(cron): treat every failed claim re-verification as a migration conflict

* test(heartbeat): rename ack test after ackMaxChars retirement

* fix(heartbeat): keep monitor scratch out of bypass-scope runs

* fix(cron): resolve claimed symlinks on release and gate legacy fallback on proven scratch state

* fix(cron): strict claim-name recovery and per-entry migration grouping

* fix(ci): heartbeat scratch gate repairs — lint causes, dead exports, since-train, inventory path, prompt snapshot, regenerated docs map, SDK baseline, protocol bindings

* fix(cron): live-owner claim guard and canonical entry-key migration grouping

* fix(cron): archive claimed inode on release and flag orphan claims beside recreated files

* docs(cron): document process-global state-db invariant for scratch service ops

* chore(i18n): refresh native inventory line numbers after protocol binding regen
2026-07-23 11:10:49 -07:00
Peter Steinberger
3608baa853 test(codex): deduplicate run-attempt scenarios (#113076)
* test(codex): deduplicate run attempt scenarios

* test(codex): satisfy run-attempt lint
2026-07-23 09:27:44 -07:00
Peter Steinberger
acd92f6a3d chore(deps): refresh repository dependencies (#112453)
* build(deps): update QA broker dependency

* build(deps): refresh repository dependencies

* build(deps): reconcile rebased shrinkwraps

* test(plugins): remove stale loader test state

* test(deps): stabilize updated dependency coverage

* fix(swift): use caller-isolated TaskLocal overload

* build(deps): regenerate rebased shrinkwraps

* test(msteams): preserve DNS validation in fetch helper

* fix(deps): avoid vulnerable optional image stack

* test(deps): validate generated LRU override

* refactor(ui): extract chat resizable divider

* test(ui): update divider ownership path

* fix(matrix): retain restart-compatible SDK

* style(cron): format update test
2026-07-23 16:17:13 +00:00
Peter Steinberger
09672312c4 feat(gateway): incognito sessions for the web Control UI (#113006)
* feat(gateway): add web-only incognito sessions held in process memory

* feat(ui): add incognito toggle and badges to the web new-session flow

* fix(sessions): classify incognito by key shape, fail closed on stale keys, and gate memory writes

* fix(codex): start harness threads ephemeral for incognito sessions

* fix(sessions): reshape internal-effects incognito keys and add doctor repair for reserved key collisions

* refactor(plugin-sdk): export canonical incognito key classifier and guard the sentinel path

* fix(state): classify incognito DB handles from the recorded open-time set

* fix(gateway): isolate incognito sessions from durable lineage and allocation on read-only misses

* docs(sessions): pin the reserved incognito namespace ownership decision

* feat(gateway): admin-scope incognito visibility and incognito-blind cross-session surfaces

* fix(ci): repair kysely guardrails, dead export, docs map, protocol bindings, and ACP reset rotation

* fix(gateway): remove non-admin observability side channels for incognito sessions

* fix(gateway): enforce admin-scope incognito access and cover all parent-reference creation paths
2026-07-23 09:04:36 -07:00
Peter Steinberger
88963299e7 test(codex): deduplicate turn watch scenarios (#113061) 2026-07-23 09:03:05 -07:00
Peter Steinberger
ad505a7b55 fix(swarm): keep collector results reliable through races and restarts (#112989)
* fix(swarm): harden collector lifecycle and dashboards

* fix(swarm): initialize collector completion state

* test(swarm): satisfy cross-environment type checks

* test(codex): allow direct request handler calls

* style(ui): avoid Swarm widget shadowing

* test(swarm): keep internal helpers private

* refactor(ui): own Swarm roster helpers in runtime
2026-07-23 06:26:31 -07:00