Commit Graph

7753 Commits

Author SHA1 Message Date
Peter Steinberger 37b4fc8621 feat(backup): recorded runs, scheduled backups, and git-backed versioned snapshots (#122485)
* refactor(infra): extract shared git exec and verified snapshot-copy helpers

Moves the worktrees git wrapper to src/infra/git-exec.ts (with optional
maxOutputBytes for large buffered reads) and the online-backup/sanitize/
VACUUM/verify snapshot step into src/snapshot/openclaw-snapshot-copy.ts so
snapshot backends share one hardened copy path. Behavior-identical moves;
all importers updated.

* feat(snapshot): git-backed versioned SQLite snapshot engine

Deterministic per-table JSONL dumps (PK-ordered, lossless bigint/blob
encoding), verbatim DDL preservation, virtual/shadow-table skipping with
FTS rebuild on restore, secret-table redaction policy, manifest with
per-table row counts and content hashes, and restore verification by
re-serialization. Unchanged data produces no commit.

* feat(backup): recorded runs, freshness surfacing, and scheduled git backups

Every backup attempt is recorded in the previously writer-less backup_runs
table (bounded to 200 rows). openclaw status gains a Backups overview row
and JSON payload; doctor prints an informational hint when no successful
backup is recorded or the newest is stale. New commands: backup git
init/create/log/verify/restore and backup enable/disable, which provision
one idempotent gateway cron job running scheduled git backups.

* fix(state): stop bumping schema_meta.updated_at on unchanged opens

updated_at now records when schema metadata actually changed instead of
when the database was last opened; unconditional bumps dirtied the row on
every open and defeated no-change backup detection.

* docs: document versioned git backups, scheduling, and backup freshness

* fix(backup): satisfy CI ownership checks

* fix(backup): complete CI contract coverage

* fix(backup): complete credential table redaction

* fix(backup): isolate git repository ownership

* fix(backup): persist push degradation

* fix(backup): atomically converge schedules

* fix(status): isolate backup freshness environment

* fix(status): carry scan environment to freshness reads

* fix(backup): harden Git repository ownership

* docs(backup): document Git repository safety

* fix(backup): non-creating outcome log and origin preflight for pushed schedules

Recording a backup outcome never bootstraps an absent state database (a
failed backup on a fresh host would otherwise create a blank DB that a
retry treats as real input), and backup enable --push now requires the
repository to have an origin remote, pointing at backup git init --remote
instead of scheduling permanently degraded pushes.

* refactor(worktrees): use shared git exec helpers

* refactor(worktrees): remove unused git buffer wrapper

* refactor(worktrees): consume buffered git helper

* feat(backup): redact pushed schedules by default

Unattended recurring pushes retain credential-bearing tables durably in
remote Git history, so backup enable --push now defaults to
--exclude-secrets; --include-secrets is the explicit full-fidelity
override (still warned). Local non-push schedules keep full fidelity for
complete restores.

* fix(backup): redact audit HMAC and OAuth pending state; tolerate absent backup_runs

Adds audit_identity_keys (audit HMAC key) and mcp_oauth_pending_authorizations
(live OAuth callback state) to the redaction inventory, and makes read-only
backup freshness treat a same-version database without the additive
backup_runs table as no recorded backups instead of failing before a
writable open converges the schema.

* fix(backup): restrict schedules to local gateways

* fix(snapshot): harden Git restore and redaction

* fix(backup): block pushes of adopted history

* fix(backup): contain commits and pairing secrets
2026-08-12 08:11:22 -07:00
Amp 85b063f732 chore(scripts): reuse file scan helpers
Amp-Thread-ID: https://ampcode.com/threads/T-019ff438-3b93-77b8-9828-1d3c586cb127
2026-08-12 07:58:43 -07:00
Amp 0f72905381 refactor(test): consolidate comparison row traversal
Amp-Thread-ID: https://ampcode.com/threads/T-019ff438-3b93-77b8-9828-1d3c586cb127
2026-08-12 07:54:03 -07:00
Peter Steinberger 4fcd9e12d9 fix(build): cancel stalled CLI metadata renderers (#122634)
* fix(build): drain startup metadata renderers

* fix(build): preserve undrained metadata state
2026-08-12 07:01:46 -07:00
Peter Steinberger df707a9670 feat: view this machine in the Desktop panel (#122545)
* feat(gateway): add gateway-host desktop source behind desktop.host lab

Introduce the host as a first-class desktop source so operators can view
the machine OpenClaw runs on, not just cloud-worker environments:

- protocol: desktop.observe / desktop.launch with a discriminated
  DesktopSource union (host | environment) plus an additive auth hint;
  EnvironmentSummary gains a top-level desktop flag
- config: desktop.host { enabled, port?, passwordFile? }, Labs-gated
- rfb-probe: pure RFB version/security-type parser used to detect an
  already-running loopback VNC server and classify its auth
- host-source: attaches to 127.0.0.1:<port>, refuses unauthenticated
  (None) and unsupported (VeNCrypt) servers, and refuses ARD with the
  supported alternative until the macOS milestone
- host-guidance: per-OS enablement text so no path dead-ends
- doctor + status report host desktop availability and auth type only

worker.desktop.observe/launch stay as delegating aliases with identical
behavior. Also drops the now-unused WorkerDesktopTunnels type export.

Live-verified against macOS Screen Sharing: probe reads RFB 003.889,
returns security types [30,33,36,35], classifies ard-account.

* test(gateway): probe RFB handshakes through the socket boundary

The probe's banner and security-offer parsers were exported solely so
unit tests could call them, which the dead-export gate rejects and which
tests internals rather than behavior. Keep them module-local and drive
the probe through a scripted loopback server instead.

The boundary tests also cover what pure-function vectors could not:
handshakes split across packets, legacy RFB 3.3 single-word security,
server-rejected handshakes, early hangups, and connect timeouts.

* feat(ui): let the Desktop panel view this machine, not just cloud workers

The Desktop panel was gated on a cloud-worker session placement, so an
operator running OpenClaw locally had no way to see the machine hosting
their main session even with a VNC server running on it.

Availability now follows the advertised desktop.observe method plus
operator.admin instead of session placement, and the picker lists every
environment whose summary reports a desktop, with the gateway row shown
as "This machine". Sources are passed to the generic desktop.observe /
desktop.launch RPCs; the app launcher stays worker-only. When a host
attach needs a password the gateway did not supply, the panel prompts and
keeps the value in memory for that connection only.

Adds the hostDesktop Labs toggle for desktop.host.enabled.

* fix(scripts): keep the env-var ratchet usable in shallow checkouts

The env-var budget check resolved its base ref, then hard-failed when
`git merge-base` found no shared ancestor. Shallow clones and grafted
agent checkouts resolve origin/main but truncate the history behind it,
so an advisory growth ratchet took down the whole check:changed gate
with "Could not resolve env-var count merge base for: origin/main".

Only the growth comparison needs a baseline, and the script already has
a no-baseline path. Treat git's exit 1 with empty output (no shared
ancestor) as that case and say so on stderr; a genuine failure still
exits 128 and still throws, and the absolute count-vs-budget check runs
either way.

* test(ui): measure the inline-code chip against its line box

The inline-code spacing test compared the chip's height to a prose text
rect, so it silently measured the monospace font's default line spacing.
That is ~17px on macOS and several px shorter on Linux, so the assertion
passed on CI and failed locally at 4.5 against a 3.75 bound -- after the
bound had already been widened once to chase browser font metrics.

Compare the chip to the paragraph's CSS line box instead, which is what
"the chip must not disrupt the line" actually means and is platform
independent. The horizontal gap stays as-is: it is em-derived padding
plus border, and it is the assertion that catches detached punctuation.

Verified both directions on macOS: the file is fully green, and
restoring the pre-fix 0.15em/0.35em padding still fails the gap
assertion at 5.41.

* feat(gateway): view macOS Screen Sharing from the Desktop panel

Modern macOS only offers ARD account authentication for Screen Sharing,
so the host desktop source refused every Mac. The Gateway now performs
the ARD handshake itself against the loopback server and hands the
browser a plain RFB 003.008 no-auth handshake, so the operator's macOS
account password authenticates the desktop without ever reaching the
browser, the observe result, a URL, or a log.

- rfb-preauth: ARD (type 30) Diffie-Hellman with MD5-derived AES-128-ECB
  credentials, and VncAuth (type 2) bit-reversed DES, both under a single
  10s negotiation deadline; Apple's RFB 003.889 maps to 3.8
- observe-bridge: runs pre-auth before splicing and starts the view-only
  filter at clientInit, since the browser handshake is consumed here;
  worker tokens keep the original version start phase
- host-source: attaches ARD, requiring per-observation credentials that
  live only in the one-shot observer token and are dropped after use
- doctor: offers an explicitly confirmed sudo launchctl repair when
  Screen Sharing is off, and prints the System Settings path otherwise

Live-verified against this Mac's Screen Sharing: the DH exchange and
credential framing are accepted and the server returns SecurityResult.
The VncAuth DES vector is confirmed against OpenSSL independently.
2026-08-12 06:58:30 -07:00
Peter Steinberger cc99d99f24 fix(installer): resolve relative CLI install paths (#122626) 2026-08-12 06:32:15 -07:00
Peter Steinberger 2cb9a75648 improve(gateway): compose live session stress probes (#122519)
* test(gateway): compose live session stress probes

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

* fix(ai): resume after Responses compaction checkpoints

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

* test(gateway): compose multi-session subagent probes

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

* fix(test): invalidate inlined schema transforms

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

* test(ai): cover empty compaction owners

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

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-12 06:22:08 -07:00
Vincent Koc c702bf2796 fix(ci): repair Slack enterprise fixture routing (#122589) 2026-08-12 20:32:41 +08:00
Peter Steinberger 786c646d88 improve(ci): rebalance compact Node shards from hosted medians (#122547)
* ci: refresh compact Node shard timings

Amp-Thread-ID: https://ampcode.com/threads/T-019ff3db-c467-70ad-8ed3-81f2ba94b0c0

* docs(ci): clarify compact planner counts

Amp-Thread-ID: https://ampcode.com/threads/T-019ff3db-c467-70ad-8ed3-81f2ba94b0c0

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-12 03:41:34 -07:00
Peter Steinberger fa4a197177 perf: accelerate sqlite reliability proof (#122576)
Co-authored-by: Amp <amp@ampcode.com>
2026-08-12 03:07:19 -07:00
Vincent Koc 9324843d42 fix(release): trust frozen beta Telegram candidates (#122575) 2026-08-12 18:03:15 +08:00
Peter Steinberger 30131a572b perf: speed changed-test import scans (#122572)
Co-authored-by: Amp <amp@ampcode.com>
2026-08-12 02:30:32 -07:00
Vincent Koc 7e2ec43e54 fix(ci): keep hosted gate verifier standalone (#122561)
Punchcard-Session: silver-valley-orchard-nq
2026-08-12 17:08:09 +08:00
Peter Steinberger 5a643e3543 fix(plugins): keep packed entries consistent through package lifecycle (#121174)
* fix(plugins): own packed entry lifecycles by package

Persist package ownership per runtime child, route lifecycle actions through one closed resolver, reconcile removed child policy during updates, and retain rollback generations until durable config/index commit.

* fix(plugins): break uninstall policy import cycle

* test(plugins): model package ownership in lifecycle fixtures
2026-08-12 00:49:29 -07: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 0de17482ae feat(gateway,ui): quiet Where picker, placement chip, and projects read model (#120804)
* feat(gateway): projects.list groups known checkouts by repo identity

Implements docs/plan/runners.md milestone 4 derived projects read model.

* feat(ui): regroup the Where picker by gateway, devices, and cloud

* feat(ui): placement chip shows where a session runs with reclaim

Implements docs/plan/runners.md milestone 4 placement display and reclaim.
2026-08-12 00:21:23 -07:00
Peter Steinberger 6f39f953ec fix(ui): show each chat panel button once, in the pane header (#122507)
* test(ui): advertise terminal and browser panels in the mock harness

The mocked Control UI never advertised browser.request or terminal.open and
left terminalEnabled false, so the chat header's panel toggles were invisible
in the harness and could not be visually verified.

* fix(ui): give the chat pane header the only panel toggle row

The session workspace rail header rendered Terminal, Browser, Ask OpenClaw and
Changes alongside its own dock/refresh/collapse controls. Terminal and Changes
already lived in the chat pane header, so both rendered twice at once, while
Browser was reachable only from inside a files rail and Ask OpenClaw sat in a
per-session rail despite being a global surface that already owns a sidebar
entry (settings route 'custodian').

The rail header now owns workspace-file actions only. Browser moves up to the
pane header beside Terminal and into the narrow-header overflow menu; the
duplicated Terminal and Changes buttons and the Ask OpenClaw toggle are gone.

Production LOC: +21 -84.

* test(ui): stop the vite stub from shadowing the mock bootstrap config

ui/vite.config.ts registers a placeholder /control-ui-config.json middleware
and config-file plugins load before inline ones, so the mock gateway plugin's
bootstrap body never reached the app and every scenario bootstrap field was
silently dropped. Marking the mock plugin 'pre' lets it answer first.
2026-08-12 00:13:13 -07:00
Peter Steinberger 8190c326ce feat(gateway): add /startupz startup probe and fix deployment template admission (#122477)
* feat(gateway): add /startupz startup probe with auth-gated version detail

Startup/traffic-admission probe that excludes downstream channel health:
200 started once startup work completes and the gateway is not draining,
503 starting/draining otherwise. Version and uptime are only included for
local-direct or authenticated callers, reusing the /readyz detail gate.

* fix(deploy): use /startupz for traffic admission in bundled templates

fly.toml gains its missing HTTP check; render.yaml stops using pure
liveness as admission; k8s pins an immutable image tag, seeds config
only when missing, and adds a startupProbe; stale Fly healthcheck-port
doc corrected (healthcheck follows the active gateway lock port since
bc4221a07e).

* docs(k8s): make persistent-file config ownership explicit with reseed path
2026-08-11 23:36:33 -07:00
Peter Steinberger b080dd1e76 refactor: consolidate coercion contracts (#122458)
* refactor: consolidate coercion contracts

Centralize exact string, record, numeric, date, Boolean, argument, and structured-error coercions while preserving call-site semantics.

Migrate canonical-name collisions and deprecated internal SDK bypasses, deleting 55 net production/tooling lines. Expand declaration ownership enforcement to 101 allowed helpers and add a narrow export-completeness audit.

* fix: preserve standalone script coercions

Keep copied Control UI tooling self-contained and retain the trusted release harness module-relative source seam when the harness runs against an old target cwd.
2026-08-11 23:26:37 -07:00
Peter Steinberger 66fe424590 fix(release): trust canonical beta Telegram QA candidates (#122480)
Canonical beta branch head exact-SHA provenance; unique merged-PR attribution for GitHub web-flow signed transport; extract duplicated gate into one trusted helper.
2026-08-11 23:25:56 -07:00
Peter Steinberger 1afb5e64a5 improve: reduce provider auth parity test time (#122445)
* test: trim provider auth parity runtime probes

* test: keep parity shards in tooling owner

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-11 22:37:06 -07:00
Peter Steinberger 72e42eed48 improve(ci): reduce main gating delays and add timing trends (#122441)
* ci: stop publishing warm dependency snapshots

Amp-Thread-ID: https://ampcode.com/threads/T-019ff3db-c467-70ad-8ed3-81f2ba94b0c0

* ci: isolate the high-variance source test shard

Amp-Thread-ID: https://ampcode.com/threads/T-019ff3db-c467-70ad-8ed3-81f2ba94b0c0

* ci: guarantee rebuilt dependency snapshot publication

Amp-Thread-ID: https://ampcode.com/threads/T-019ff3db-c467-70ad-8ed3-81f2ba94b0c0

* ci: add balanced main timing trends

Amp-Thread-ID: https://ampcode.com/threads/T-019ff3db-c467-70ad-8ed3-81f2ba94b0c0

* fix(ci): fall back when Crabbox CLI is unavailable

Amp-Thread-ID: https://ampcode.com/threads/T-019ff3db-c467-70ad-8ed3-81f2ba94b0c0

* Revert "fix(ci): fall back when Crabbox CLI is unavailable"

This reverts commit 0583ac8a9d.

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-11 22:26:39 -07:00
Peter Steinberger 722e20b675 test(agents): prune final Responses duplicates (#122424)
* test(agents): prune final Responses duplicates

* fix(tooling): honor inclusive compat removal dates
2026-08-11 21:22:42 -07:00
Peter Steinberger a89b88ec0e docs(qqbot): point install docs at the Tencent package (#122417)
The externalization left the docs inventory seed and the channel page
advertising the retired @openclaw/qqbot npm package; the catalog already
resolves qqbot to @tencent-connect/openclaw-qqbot. Regenerates the
plugin reference and inventory pages from the corrected seed.
2026-08-11 21:20:00 -07:00
Peter Steinberger f6fff4f7fd refactor: canonicalize aliases and classify test suites (#122407)
* refactor: use canonical re-export names

* fix(test): classify suite support as test source

* fix(agents): retarget gateway stub session-entry import

* test(gateway): retarget session-utils mock keys after alias removal
2026-08-11 21:18:34 -07:00
Peter Steinberger 8876528f7c feat: clone GitHub projects from session picker (#121818)
* feat(projects): add managed GitHub clones

* feat(ui): clone GitHub projects from session picker

* fix(projects): integrate current gateway owners

* fix(protocol): derive Swift error detail accessors

* fix(ui): gate project cloning by scope

* test(gateway): isolate session prewarm probes

* revert: drop duplicate session prewarm repair
2026-08-11 18:49:16 -07:00
Peter Steinberger a5420dfd91 fix(windows): launch npm-installed native session CLIs (#122334)
* fix(windows): resolve runnable npm launchers

* fix(windows): preserve npm shim argv in terminal sessions
2026-08-11 18:41:35 -07:00
joshavant 49dabadf86 fix(ci): avoid unrelated iOS release-gate runs 2026-08-11 20:35:35 -05:00
Peter Steinberger 964c8c84c1 refactor: consolidate coercion ownership (#122299)
* refactor: consolidate coercion ownership

Centralize four canonical coercion helpers, migrate exact core and plugin duplicates through narrow Plugin SDK facades, and enforce declaration and plugin-normalization ownership boundaries.

The sweep adds eight focused SDK exports while deleting more production and tooling code than it adds. User-visible behavior is unchanged except for safer equivalent object and UI parsing at existing boundaries.

* fix: guard integer option ownership

Register resolveIntegerOption with the canonical function owner and extend the declaration-guard fixture so future local duplicates fail validation.

* fix: keep integer helpers on numeric facade

Remove the unshipped duplicate string-coerce exports and route every affected plugin consumer through the existing number-runtime contract.

* fix: point numeric coercion to number runtime

Make boundary and declaration diagnostics recommend the canonical numeric facade, with failing-before coverage for both guidance paths.
2026-08-11 17:14:53 -07:00
Jason (Json) 72d55fc12a fix(scripts): rewrite transitive OCM workspace packs (#122214) 2026-08-11 17:01:06 -07:00
Peter Steinberger cd0a1235a3 feat: sync new-session preferences and recents by identity (#121816)
* feat(gateway): add identity preferences and project recents

* feat(ui): sync new-session identity state

* docs: explain identity-scoped session state

* test: track preference temp directories

* fix(gateway): preserve identity preference boundaries

* chore(protocol): refresh identity preference bindings

* test: refresh historical schema hashes

* style(gateway): format method order assertion

* fix(protocol): emit project recent Swift models

* test(gateway): track preference RPC release train

* fix(gateway): harden identity preference state

* fix(state): keep preference errors internal

* chore: refresh split plugin SDK baseline

* fix(gateway): use core session store loader

* refactor(state): fold additive migration checks

* chore: regenerate plugin SDK baseline

* chore: regenerate plugin SDK baseline

* chore: regenerate plugin SDK baseline

* chore: regenerate plugin SDK baseline

* chore: regenerate plugin SDK baseline

* chore: regenerate plugin SDK baseline

* chore: regenerate plugin SDK baseline

* test(ui): relocate identity recents e2e

* chore: regenerate plugin SDK baseline

* chore: regenerate plugin SDK baseline

* chore: regenerate plugin SDK baseline

* chore: regenerate plugin SDK baseline

* chore: regenerate plugin SDK baseline
2026-08-11 16:52:59 -07:00
joshavant 5f7ea6b548 fix(ui): lazy-load run inspector copy 2026-08-11 18:44:38 -05:00
Peter Steinberger b350f76484 fix(channels): preserve failed agent run reactions (#122009) 2026-08-11 15:26:44 -07:00
Peter Steinberger c525f1a549 fix(windows): preserve Unicode LAN route aliases (#122263) 2026-08-11 15:21:37 -07:00
Sliverp 84c7d45f15 refactor(qqbot): install plugin from Tencent package (#107295)
* refactor(qqbot): remove bundled extension source

Mechanical deletion half of the #107295 squashed rebase; the catalog
repoint and host integration land in the follow-up commit.

Co-authored-by: sliverp <870080352@qq.com>

* refactor(qqbot): install plugin from Tencent package

Squashed rebase of #107295 onto current main. Repoints the official
external channel catalog at @tencent-connect/openclaw-qqbot@2.0.1 and
adapts onboarding, doctor migrations, secrets, build guards, and tests.

Documents the known limitation that the external package does not
support structured SecretRef clientSecret values; operators move those
to QQBOT_CLIENT_SECRET or clientSecretFile before upgrading.

Co-authored-by: sliverp <870080352@qq.com>

* fix(doctor): reuse shared hasOwnKey record helper

The rebased QQBot migration carried its own hasOwnKey export, colliding
with the one main now ships in legacy-config-record-shared.ts.

Co-authored-by: sliverp <870080352@qq.com>

* fix(plugins): carry catalog integrity through the update bridge

The externalized-bundled-plugin bridge dropped the official catalog's
expectedIntegrity pin, so bundled-user updates installed the external
npm package without integrity verification. The bridge now carries the
pin for the catalog's exact npm spec and both bridge install calls pass
it through; update-channel spec overrides intentionally skip the pin
since it only covers the pinned version.

Co-authored-by: sliverp <870080352@qq.com>

* chore(plugin-sdk): refresh per-entrypoint API baselines

The QQBot compat export and bundled-type removal shift 26 entrypoint
closure hashes in the new split baseline layout.

Co-authored-by: sliverp <870080352@qq.com>

* refactor(qqbot): drop helper reintroduced during rebase

Main's coercion consolidation added this file after the deletion
commit's base; its only consumers were the removed qqbot sources.

Co-authored-by: sliverp <870080352@qq.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-11 15:10:27 -07:00
Josh Lehman d035dba6c7 chore: scope SQLite session lifecycle CI (#121917)
* oc-358: scope SQLite lifecycle CI

* chore(ci): cover shared session lifecycle owner
2026-08-11 15:06:46 -07:00
Mariano edb7a1692e fix(telegram): expose live location updates to hooks (#122185)
* fix(telegram): expose live location updates to hooks

* test(telegram): keep location coverage focused

* fix(telegram): emit stopped live locations

* test(plugin-sdk): refresh location hook contracts

* docs(changelog): note Telegram live location hooks

* fix(telegram): complete live-location observer path

---------

Co-authored-by: mbelinky <mbelinky@users.noreply.github.com>
2026-08-11 23:26:23 +02:00
Peter Steinberger e74be5d41d refactor: eliminate final wrapper-shadowing hazards (#122157)
* refactor: disambiguate wrapper-shadowed exports

* test: align renamed session and facade boundaries

* test: cover renamed runtime mock exports

* refactor: align remaining wrapper owner call sites

* test: align overlap-rebased runtime mocks

* refactor: preserve public SDK names after overlap rebase

* chore: regenerate wrapper shadowing baselines

* test: align cron model selection mocks
2026-08-11 13:34:24 -07:00
Peter Steinberger 8f4a90a518 fix(media): decode local file URLs safely (#122192)
* fix(media): decode local file URLs safely

* refactor(media): remove obsolete helper exports
2026-08-11 13:19:09 -07:00
Peter Steinberger a40df57bae refactor(agent-runner): split run policy ownership (#122209)
* refactor(agent-runner): split tool-call normalization ownership

* refactor(agent-runner): split incomplete-turn ownership

* test(agent-runner): hide incomplete-turn test helper

* test(ci): route split incomplete-turn tests

* test(ci): enumerate split incomplete-turn tests

* test(vitest): route split incomplete-turn tests to their serial shard
2026-08-11 13:06:29 -07:00
Jason (Json) 09c39e0ec5 fix(scripts): keep bundled channel smoke standalone (#122212) 2026-08-11 13:05:46 -07:00
Peter Steinberger 8c567306ba fix(openai): remove duplicate GPT-5.6 picker entry (#122178)
* fix(openai): remove duplicate GPT-5.6 picker entry

* test(gateway): split OpenAI model picker coverage

* test(openai): align canonical model fixtures

* chore(plugin-sdk): refresh agent harness API baseline
2026-08-11 12:29:36 -07:00
Ayaan Zaidi 746a188c90 refactor(media): collapse attachment byte classification into media-core (#122168)
Attachment MIME gating and extraction dispatch used nine separate byte policies across five files; the allowlist could approve one MIME while dispatch observed another after a second sniff. @openclaw/media-core/attachment-classify now owns byte sniffing, text heuristics, extension mapping, and the seven attachment classes; the cache stores one classification that gates and dispatch share. Channel-declared MIME leads with the transport Content-Type as a byte-arbitrated hint, normalizeMimeType folds YAML/XML synonyms so existing configured allowlists keep matching, and input_file API callers keep declared-MIME precedence over cosmetic filenames. Net -135 production LOC.

Proof: 2,153 focused tests across media-core/media-understanding/media plus boundary-contract and deadcode-mirror suites; ClawSweeper local review clean (round 5, zero findings); live Telegram default-turn probe green.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-11 19:10:49 +00:00
Peter Steinberger 3d76246792 refactor: eliminate final export name collisions (#122083)
* refactor: resolve final export name collisions

* refactor: update remaining collision rename consumers

* style: format rebased auth helpers

* test: update remaining session entry mocks

* test: update remaining runtime mock exports

* test: update delivery info path mock

* refactor: reconcile combined collision sweeps

* chore: regenerate collision and sdk baselines
2026-08-11 11:18:24 -07:00
Peter Steinberger ebb2770000 refactor: eliminate export name collisions (#122084)
* refactor: eliminate export name collisions

* chore(scripts): burn resolved collision baselines

* refactor: narrow legacy session load options

* chore: refresh SDK and session debt baselines

* refactor: adopt upstream secrets collision fix

* test(plugin-sdk): mock renamed session store core

* fix(scripts): track renamed session accessor core
2026-08-11 10:41:50 -07:00
Vincent Koc 653ab3b2aa fix(ci): restore duplicate scans with jscpd 5 (#122124) 2026-08-12 01:39:40 +08:00
Vincent Koc 1fb715853c fix(qa): resolve Docker harness script entrypoints (#121548)
Punchcard-Session: amber-workshop-workshop-36
2026-08-12 01:23:20 +08:00
Peter Steinberger cad77fb39c refactor: consolidate remaining coercion helpers (#122020) 2026-08-11 10:22:01 -07:00
Peter Steinberger a580c2afa1 fix(windows): parse tasklist CSV for port hints (#122126) 2026-08-11 10:08:08 -07:00
Peter Steinberger 6792921dea refactor: finish commitments retirement bookkeeping (#122143)
* refactor(commitments): remove remaining retired references

* refactor(state): track schema retirements
2026-08-11 09:59:11 -07:00