Commit Graph

66 Commits

Author SHA1 Message Date
Vincent Koc b7cafbe7e8 fix(test): expose diagnostics when Vitest stalls (#128020)
* fix(test): print Vitest timeout process diagnostics

* fix(test): bound Vitest timeout diagnostics

* fix(test): classify Vitest diagnostic commands

* fix(test): unify Vitest command diagnostics
2026-08-22 14:37:40 -07:00
Peter Steinberger ae55a4090c refactor(canvas): make the panel a widget presenter (#126030)
* refactor(canvas): retire legacy host and commands

* refactor(apple): narrow shared Canvas contracts

* refactor(macos): keep Canvas as widget presenter

* refactor(ios): remove Canvas client

* refactor(android): remove Canvas client

* refactor(linux): remove Canvas client

* fix(ci): isolate native locale artifacts

* fix(linux): regenerate companion lockfile

* fix(canvas): refresh native tool display metadata

* test(canvas): align coverage with presenter surface

* test(canvas): remove obsolete asset root seam

* test(canvas): stabilize retirement CI coverage

* refactor(swift): remove orphaned resource wrapper

* test(ios): remove retired canvas layout assertion

* fix(macos): reserve retired canvas command namespace

* refactor(macos): isolate canvas command policy

* fix(canvas): select only eligible macOS panels

* fix(canvas): keep panel selection plugin-owned
2026-08-19 08:21:07 -07:00
Peter Steinberger f8ba65636c feat(control-ui): simplified settings experience for non-admin operators (#125492)
* test(control-ui): add --operator-scopes flag to the mock dev server

* feat(control-ui): simplified settings experience for non-admin operators

Non-admin browsers previously saw every settings page, many of which
dead-ended or rendered enabled controls whose RPCs fail with
'missing scope: operator.admin'.

- config.schema drops from operator.admin to operator.read: the schema is a
  static document describing options whose values are already readable via
  read-scoped config.get; admin-only schema only broke read-only settings
  rendering (Automation/Infrastructure/AI Agents/Communications showed
  'Schema unavailable. Use Raw.').
- Settings sidebar and settings search hide admin-only routes (custodian,
  labs, updates, automation, infrastructure, mcp, security, secrets,
  cloud-workers, communications, ai-agents, model-setup) for non-admin
  viewers; legacy gateways without advertised scopes keep the full UI.
- Channels, Devices, Worktrees, Memory Import, Profile gate their mutation
  controls on actual scopes with 'Browsing only…' notices instead of
  enabled-but-failing buttons; Devices no longer fires device.pair.list /
  exec.approvals.get without the scopes to call them (kills the two red
  error callouts on page load).
- Scope-upgrade banner: dismissing it in the guidance phase (no in-app
  upgrade path) now hides it fully instead of leaving a permanent chip.
- Config write coordinator surfaces scope refusals as a visible
  admin-required error instead of silently resolving false.

* test(control-ui): advertise config.schema in the mock dev gateway

ensureSchemaLoaded now checks method advertisement + scope before loading
the schema; the mock harness must advertise config.schema like a real
gateway does or schema-driven settings pages render empty in the mock.

* fix(control-ui): close the worktree create draft on scope downgrade

* perf(doctor): isolate memory health artifact

Doctor lint loaded the broad Memory Core API barrel only to register health checks and read isolated check IDs. That synchronously pulled the full memory public graph into the first lint run, consuming most of the 120-second test budget.

Load a dedicated doctor-health public artifact instead and verify it is packaged. The bisect boundary was 9de3ca5fc9 (#125571); because that commit only adds upgrade-test assets, it exposed a pre-existing runner-sensitive cost rather than introducing the expensive import path.

* test(control-ui): restore device lifecycle test boundary

* perf(control-ui): lazy-load settings sidebar

* fix(ui): recheck access after confirmations

* fix(control-ui): gate presence-driven device reloads on pairing access

The presence connectivity-change path still called device.pair.list without
operator.pairing, the same invariant the pair-event and poller paths already
guard; a limited browser got a doomed RPC on every connectivity change.

* fix(control-ui): fail open on schema loads for legacy scope-less gateways

canCallGatewayMethod hardened to strict advertisement+scope checks (#125478),
which made the new ensureSchemaLoaded gate silently skip config.schema for
legacy hellos without advertised scopes or a method list. Schema loads now
skip only on a definitive denial (method advertised absent, or advertised
scopes without operator.read), reusing the fail-open hasOperatorReadAccess
semantics the rest of the non-admin UI uses; regression test pins the
legacy snapshot path.

* test(control-ui): split schema-access coverage into its own file

runtime-config-capability.test.ts crossed the max-lines cap; the legacy
fail-open regression and its denial counterpart move to a colocated
schema-access test file.

* fix(scripts): keep mapped Vitest lanes at their measured no-output floor

The codex extension shard legitimately works in silence beyond 300s under
the default reporter (measured 61s import + 293s testing at ~95% CPU); the
CI-wide OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=300000 env override shrank the
lane below that and the watchdog killed healthy runs, flipping with
incidental flake output (#125825). Per-config entries in
VITEST_CONFIG_NO_OUTPUT_TIMEOUT_MS now act as measured silence floors: a
global env value may widen a mapped lane's window but no longer shrinks it;
unmapped configs and the explicit '0' disable keep env verbatim. Adds the
codex extension lane to the map at the extra-long tier (same class as the
discord entry from #123025).
2026-08-18 10:15:10 -07:00
Peter Steinberger b934625d80 fix(test): name Vitest unhandled errors instead of burying them (#125615)
* fix(test): surface Vitest unhandled errors

* fix(test): keep Vitest error helpers private
2026-08-17 22:49:19 -07:00
Peter Steinberger d437a4a4b4 fix(test): route extension roots through bounded planner (#124553)
* fix(test): route extension roots through bounded planner

* test: cover bounded Codex fallback shards
2026-08-16 05:35:17 -07:00
Peter Steinberger 1610771b1d test(tooling): remove obsolete runner facades (#124159) 2026-08-15 04:47:33 -07:00
Peter Steinberger 20be26cfe2 refactor(test): remove residual test-only seams (#123168)
* refactor(test): remove residual test-only seams

* fix(test): fresh-load Vitest ownership configs

* test(infra): repair boundary test routing

* test(infra): use landed Codex test owner
2026-08-13 17:16:55 -07:00
Vincent Koc af49764206 fix(ci): ignore zombie-only Vitest process groups (#122759) 2026-08-13 08:46:22 +08:00
Peter Steinberger 94c28e093d fix(test): route agent directory runs to owning shard (#122514)
* fix(test): route agent directories to owner projects

* fix(test): preserve invalid signal diagnostics
2026-08-12 00:44:49 -07:00
Peter Steinberger c70aee247e refactor(scripts): migrate JavaScript tools to TypeScript (#121005)
* refactor(scripts): migrate JavaScript tools to TypeScript

* fix(ci): keep changed-scope preflight zero-install

* fix(ci): preserve zero-install script owners

* fix(ci): complete script migration follow-through

* fix(release): keep stable closeout zero-install

* fix(scripts): preserve standalone execution boundaries

* fix(scripts): repair standalone loader boundaries

* fix(scripts): normalize gateway observation ids

* fix(scripts): keep Docker packager standalone

* test(scripts): preserve rebase cleanup helpers

* test(sessions): use tracked temp directory
2026-08-09 07:21:35 -07:00
Peter Steinberger b5d41f9005 fix(test): bound direct gateway server runs (#119184) 2026-08-04 03:38:39 -07:00
Peter Steinberger 9b8e50b9f6 refactor(scripts): consolidate redundant tooling paths (#118259) 2026-08-02 16:20:09 -07:00
Peter Steinberger c9f43d950f fix(ci): prevent sequential Vitest shards from overlapping (#117755)
* fix(ci): join Vitest process groups before next shard

* fix(ci): join detached Vitest process groups
2026-08-01 21:56:54 -07:00
Peter Steinberger deabae48d3 fix(ci): keep PTY tests observable and wait for completed turns (#117405)
Co-authored-by: Peter Steinberger <steipete@macos.shared>
2026-08-01 07:46:46 -07:00
Peter Steinberger f3c4b120e2 fix(tooling): prevent silent test filters and local dependency reconciliation (#113236)
* fix(tooling): harden changed checks and test filters

* test(tooling): align temp report with helper lanes
2026-07-24 00:55:52 -07:00
Peter Steinberger b78cf56349 improve(ci): persist warm Vitest and Node caches (#109425)
* perf(ci): harden persistent test caches

* ci: document trusted cache cleanup trigger

* ci: harden composite cache inputs

* perf(ci): isolate Node build bytecode cache
2026-07-16 17:22:28 -07:00
Peter Steinberger fecd11fdc9 perf(test): unref process watchdogs (#108643) 2026-07-16 00:39:08 -07:00
Peter Steinberger 4ae06b8c8e test: tighten more async polling (#108454) 2026-07-15 13:37:53 -07:00
Peter Steinberger b363d5a293 feat(linux): canvas UI via CLI-node + Tauri app IPC bridge (#107633)
* feat(linux): canvas via CLI-node + Tauri app IPC bridge

* refactor: extract gateway helper modules

* build(linux-canvas): register plugin package in lockfile

* fix(linux-canvas): move canvas advertise test out of core, regen docs/protocol/deadcode

* fix(gateway): break node-catalog/registry import cycle via leaf normalize module; add canvas glossary term

* style: oxfmt invoke.ts and runtime.ts after buildNodeEventParams extraction

* fix(linux): load Canvas WebView via dedicated data_directory context

Wry's Linux/WebKitGTK incognito mode discards Tauri's registered
WebContext (wry webkitgtk/mod.rs), so the Canvas window got a fresh
ephemeral context without the openclaw-canvas:// scheme handler — the
bundled A2UI page never committed (stayed about:blank) and every A2UI
command timed out. Use an isolated cache-backed data_directory instead,
which keeps the protocol handler while still isolating Canvas storage
from the dashboard window.

* fix(linux): keep Canvas WebView ephemeral via incognito + data_directory

Autoreview flagged that a dedicated data_directory alone persists Canvas
browser state (cookies, localStorage, IndexedDB, service workers) across
restarts, so an agent that navigates Canvas to a site could leak an
authenticated session into a later session. iOS uses a non-persistent
store; Linux should match.

Add .incognito(true) alongside .data_directory(): the distinct directory
gives Tauri a fresh WebContext key so it still attaches the
openclaw-canvas:// protocol closure, and incognito makes Wry swap in a
fresh *ephemeral* context carrying those protocols. Live-verified on a
Wayland/WebKitGTK box: the bundled page still loads
(location.href=openclaw-canvas://localhost/index.html, openclawA2UI
present, A2UI renders) and the canvas-webview dir holds no persistent
cookie/storage files.
2026-07-14 16:05:14 -07:00
Peter Steinberger 69a578034f test: isolate provider auth parity suite (#107167) 2026-07-14 00:16:49 -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 6268eeef15 test: wire Control UI suite into CI, fix its broken tests, drop dead harness surface (#104361)
* test: wire Control UI suite into CI, fix its broken tests, drop dead harness surface

- fix 7 Control UI tests broken on main: module-mock factories are unreliable
  under isolate:false shared workers; use RealtimeTalkSession prototype spies
  and real jsdom storage instead (chat-realtime, chat-pull-requests)
- add gated checks-ui CI job (runUiTests changed-scope output): chromium
  provisioning, lint:ui:no-raw-window-open, pnpm --dir ui test; ~30s on a
  4vcpu runner, runs only when ui-affecting paths change
- add weekly node22-compat workflow exercising the supported lower Node bound
  with the same command set as the dispatch-only ci.yml job
- delete the unreachable channels entry in EXTENSION_TEST_CONFIG_ROUTES and
  the never-populated extensionRoutedChannelTestFiles override machinery
  (born empty in 2ccb5cff22); resolved globs are provably identical
- guard run-vitest.mjs hardcoded path maps with existence tests so renames
  cannot silently drop extended stall watchdogs
- remove unenforced coverage thresholds; test:coverage is informational, docs
  updated (reference/test, help/testing, plugins/sdk-testing)

Closes #104321

* test: pin OPENCLAW_CI_RUN_UI_TESTS in the manifest env expectation

* test(ui): capture the realtime start spy instead of referencing the unbound prototype method

* test(ui): raise ui vitest timeouts for real-browser layout tests on small CI runners
2026-07-11 03:04:11 -07:00
Peter Steinberger a04b6ced4f test: stabilize load-sensitive test families that break gates under parallel load (#100420)
* test: stabilize process-heavy fixtures under load

* test: stabilize channel mocks under load
2026-07-05 12:53:06 -07:00
Peter Steinberger 1f484a8dbd test: speed up and stabilize full suite 2026-07-05 08:00:23 -04:00
Shakker 65e12328aa feat: refactor the Control UI architecture
Refactor the Control UI around route-owned page lifecycle and state while preserving existing behavior and design.

Prepared head SHA: bd51b6fa76
Co-authored-by: Shakker <165377636+shakkernerd@users.noreply.github.com>
Reviewed-by: @shakkernerd
2026-07-04 23:19:38 +01:00
Peter Steinberger ed098c6550 refactor(test): drop redundant linked-worktree bundled-plugins pin from run-vitest
The node_modules package-root boundary fix anchors bundled plugin
discovery to the running checkout in nested worktrees, so the wrapper
no longer needs to pin OPENCLAW_BUNDLED_PLUGINS_DIR for symlinked
node_modules layouts. Verified live in a .claude worktree: with the
boundary fix and no pin, vitest workers resolve the worktree's own
extensions in both no-node_modules and symlinked layouts, and linked
worktrees now follow the same canonical dist-preferred discovery as
normal checkouts. The trust env remains owned by test/setup.shared.ts.

Must land together with or after the boundary fix commit directly below.
2026-07-04 21:52:09 +01:00
Vincent Koc bc754b3160 fix(ci): restore Vitest watchdog cleanup 2026-06-20 23:42:22 +08:00
Vincent Koc 730c7269ef fix(test): clean Vitest runner child groups on signal 2026-06-20 15:35:33 +02:00
Vincent Koc 3a1e49dbaa fix(test): preserve vitest force kill after idle timeout 2026-06-20 09:44:02 +02:00
Vincent Koc 6fc0a3a9bd fix(test): chunk broad script test routing 2026-06-20 01:32:13 +02:00
Vincent Koc f7c3775140 fix(test): prefer local bundled plugins in linked Vitest worktrees 2026-06-19 14:00:32 +02:00
Vincent Koc f5194c4647 fix(test): reject loose Vitest wrapper limits 2026-06-16 21:50:19 +02:00
Vincent Koc 45056a463a fix(test): extend watchdog for gateway core shard 2026-06-13 23:01:11 +08:00
Vincent Koc 27e24ca683 fix(test): extend watchdog for slow vitest shards 2026-06-13 21:37:57 +08:00
Vincent Koc f1401b2cac perf(ci): isolate Docker tooling tests 2026-06-11 18:13:36 +09:00
Vincent Koc 286772e930 test: shorten vitest no-output heartbeat 2026-06-05 09:00:02 -07:00
Peter Steinberger 58c663920d docs: document script tests 2026-06-04 20:49:50 -04:00
Vincent Koc 8e9a4e99f5 test(gateway): extend vitest idle watchdog 2026-06-04 06:49:43 -07:00
Vincent Koc 344e04b5d5 fix(testing): route source targets through test planner 2026-06-03 18:07:32 +02:00
Vincent Koc 8f6f2617ec test(vitest): extend full agentic watchdog 2026-06-03 07:35:39 -07:00
Vincent Koc 9dc1694eb7 test: lengthen ARM contracts shard watchdog 2026-06-03 05:05:35 -07:00
Vincent Koc 14f61d0637 fix(test): clean delegated vitest runners 2026-06-02 00:09:20 +02:00
Vincent Koc fb17986af5 fix(ci): preserve hydrated Windows test deps 2026-06-01 06:08:10 +02:00
Vincent Koc a753e6bc86 fix(test): extend e2e vitest watchdog 2026-05-31 11:50:18 +02:00
Peter Steinberger a20b2dc740 refactor: extract web content core package (#88346)
Extract web-content shared runtime helpers into packages/web-content-core, move the focused tests with the new package, and split quiet CI shards so the node matrix no longer stalls past the no-output watchdog.\n\nVerification: node scripts/run-vitest.mjs test/scripts/ci-node-test-plan.test.ts test/scripts/run-vitest.test.ts src/infra/restart.test.ts src/infra/os-summary.test.ts src/infra/gateway-processes.test.ts src/infra/inline-option-token.test.ts src/infra/map-size.test.ts src/infra/machine-name.test.ts src/commands/doctor-whatsapp-responsiveness.test.ts; autoreview clean; manual CI https://github.com/openclaw/openclaw/actions/runs/26693962844; dependency guard https://github.com/openclaw/openclaw/actions/runs/26693959937. Admin merge used because optional Mantis Telegram Desktop proof was cancelled after blocking merge outside this PR's required proof.
2026-05-30 21:38:29 +01:00
Peter Steinberger 602364f1c7 ci: stabilize changed checks 2026-05-30 20:07:38 +01:00
Dallin Romney 7de025eacd fix: route explicit vitest files through project runner (#88127) 2026-05-29 20:38:52 -07:00
Vincent Koc 117af11a6f fix(test): route tooling vitest files narrowly 2026-05-30 05:32:13 +02:00
Vincent Koc 7615c3137d fix(test): fail explicit empty vitest runs 2026-05-27 09:41:53 +02:00
Vincent Koc 373b3bfe54 fix(test): explain missing vitest dependency 2026-05-26 18:33:50 +02:00