Commit Graph

37751 Commits

Author SHA1 Message Date
Peter Steinberger 218dcd815a feat(tooling): enforce noUncheckedIndexedAccess in the extensions lane (NUIA phase 4) (#105132)
* fix(extensions): make indexed access explicit across channel plugins

Transport-payload-safe burn-down: malformed Telegram/Discord/QQ/LINE
and sibling channel input keeps existing skip paths; no synthesized
fields, no new throws in delivery loops. Zalo escape sentinels preserve
literal matches instead of undefined replacements.

* fix(extensions): make indexed access explicit across provider and memory plugins

Stream and model iteration, tool-block guards, capture guards, and
sparse accumulators; singleton model reads carry named invariants.

* fix(extensions): make indexed access explicit across tooling plugins, flip the extensions lane

Remaining plugins (oc-path, qa-lab, browser, logbook, and siblings) plus
the tsconfig.extensions.json flag flip. Cleanup: logbook sampleFrames
NaN index at max=1, QA retry clamp at non-positive attempts, dead Canvas
probe and OpenShell no-op slice removed, twitch test setup leak excluded
from the prod lane.

* refactor(plugin-sdk): expose expectDefined via a focused SDK subpath

Extensions imported @openclaw/normalization-core directly, crossing the
external-plugin packaging boundary (it only worked because the runtime
builder bundles undeclared workspace helpers). expect-runtime joins the
canonical entrypoints JSON, generated exports, API baseline, docs, and
subpath contract test; all 78 extension imports now use the SDK seam.
Two scanner-shaped locals renamed for review-bundle hygiene.

* chore(plugin-sdk): raise surface budgets for the expect-runtime subpath

One new entrypoint with one callable export, added intentionally as the
packaging-honest seam for extension invariant helpers.
2026-07-12 09:17:31 +01:00
Vincent Koc a381b50643 test(agents): skip region-blocked xAI models 2026-07-12 16:15:44 +08:00
Peter Steinberger 6fc564278d feat(agents): sessions_search full-text recall over past session transcripts (#105057)
Adds a core sessions_search agent tool backed by a SQLite FTS5 index that
lives next to the transcript rows in the per-agent database. Indexing is
transactional: user/assistant text is indexed inside the same write
transaction that persists the event, deletes drop index rows in the same
transaction, and branch rewinds mark the session dirty so the next search
rebuilds it from the same visible-path resolution sessions_history uses
(which also lazily backfills doctor-migrated databases). Search executes
gateway-side behind an additive sessions.search method with a bounded
session-key allowlist; visibility, sandbox restrictions, and snippet
redaction mirror sessions_history.

Closes #100978
2026-07-12 09:15:41 +01:00
Vincent Koc d6d7c19c9d fix(tasks): fail closed when task-flow state cannot restore (#105088)
* fix(tasks): fail closed on task-flow restore errors

* fix(tasks): keep maintenance checks behind owner seam

* fix(tasks): gate runtime startup on flow restore

* test(tasks): prove runtime restore gate failures

* fix(tasks): gate cancellation on flow readiness
2026-07-12 16:08:29 +08:00
Vincent Koc c293fef3a8 refactor(sessions): remove obsolete file projection path (#105136) 2026-07-12 16:08:04 +08:00
Peter Steinberger 10371ff475 fix(gateway): suspension waits for accepted node work (#105134)
* fix(gateway): retain node event work during suspension

* chore: leave gateway release note to release closeout
2026-07-12 09:07:23 +01:00
Peter Steinberger 6038480915 feat(ui): browse Gateway and node folders from one root (#105114)
* feat(ui): browse Gateway and node folders

* chore: keep changelog release-owned

* chore: refresh native i18n inventory

* refactor(macos): isolate node filesystem commands
2026-07-12 09:07:07 +01:00
Peter Steinberger 1c9a2f6a9d perf(gateway): skip completed startup migrations (#105099) 2026-07-12 09:03:45 +01:00
Peter Steinberger d325b6c76b fix: preserve parent abort reasons through timeouts (#105071) 2026-07-12 09:02:12 +01:00
Peter Steinberger b6c171901e fix(secrets): harden exec provider diagnostics (#105082) 2026-07-12 09:01:33 +01:00
Vincent Koc 55679d88c6 test(agents): budget Grok reasoning live probes 2026-07-12 15:55:29 +08:00
Vincent Koc 68f2874126 chore(ui): refresh locales and repair cron lifecycle fixtures (#105100)
* chore(ui): refresh control ui locales

* test(cron): keep lifecycle fixtures in memory

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-12 15:53:06 +08:00
Vincent Koc 8f3fe36e28 test(gateway): match current-bound cron probes 2026-07-12 15:52:21 +08:00
Peter Steinberger e77cf7d44e fix(audit): correlate prefixed outbound conversations (#104816)
* fix(audit): normalize outbound conversation refs

* chore(audit): leave release notes to release tooling
2026-07-12 08:46:52 +01:00
Vincent Koc b0455c9323 test(gateway): assert sqlite trajectory capture 2026-07-12 15:41:35 +08:00
Kushida 9b057036e3 fix(gateway): keep channels stopped during shutdown and reload (#104811)
* fix(gateway): stop retired health monitor restarts

* style(gateway): format health monitor regression

* fix(gateway): stop retired monitor account scans

* refactor(gateway): coordinate health monitor handoff

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-12 08:27:45 +01:00
Vincent Koc 5839c2e04b fix(plugins): avoid native ESM fallback races 2026-07-12 15:16:07 +08:00
Vincent Koc ee17910f2a fix(cron): persist fast-mode session state (#105094) 2026-07-12 14:58:56 +08:00
chengzhichao-xydt 789e7e2e36 fix(security): preserve UTF-16 boundaries in secret mask (#104800)
Co-authored-by: chengzhichao-xydt <chengzhichao-xydt@users.noreply.github.com>
2026-07-12 07:50:46 +01:00
Peter Steinberger 0086763ba4 feat(fleet): harden create, port allocation, drift visibility, and audit guidance (#104814) 2026-07-12 07:02:42 +01:00
Vincent Koc e680b3dbeb fix(tasks): fail closed on registry restore errors (#105031) 2026-07-12 13:50:28 +08:00
Shubhankar Tripathy 86cd9786c8 fix(google-meet): actually leave the Meet call in the browser on leave (#103386) (#103522)
* fix(google-meet): leave browser calls on session end

Co-authored-by: lonexreb <reach2shubhankar@gmail.com>

* fix(google-meet): keep agent browser control in gateway

* chore(google-meet): move release note to pr

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-12 06:50:13 +01:00
Vincent Koc c8427919b9 refactor(acpx): remove redundant probe plumbing (#105023) 2026-07-12 13:49:32 +08:00
Peter Steinberger 05e95b7b45 fix: hide external files from the session workspace rail (#105015)
* fix(ui): hide external files from workspace rail

Co-authored-by: 赵旺0668001248 <zhao.wang1@xydigit.com>

* chore: leave release notes to release workflow

---------

Co-authored-by: 赵旺0668001248 <zhao.wang1@xydigit.com>
2026-07-12 06:42:49 +01:00
Ayaan Zaidi 47ce757c0f fix(auto-reply): adopt the target run slot when command turns continue into agent turns
Native command turns keep #104144 source-keyed admission, but a turn that
continues into a full agent turn (/steer fallback, /goal, /learn, unhandled
body) now moves its reservation and lifecycle lease to the target session
before running. Concurrent target inbounds see the owner and queue/steer
instead of double-admitting and splitting the session into two conversation
families; steering also targets the registered run owner instead of a stale
source-keyed reservation.

Fixes #104844
2026-07-12 11:12:04 +05:30
thomas.szbay 4dfffeb4ce fix(infra): bound ed25519 base64url decode input length (#104921) 2026-07-12 06:39:35 +01:00
Peter Steinberger d14bb8ec44 fix: resume replay-safe work after gateway restarts (#104997)
* fix: resume replay-safe work after gateway restart

* chore: leave restart note to release process

* fix: sync restart recovery protocol artifacts
2026-07-12 06:37:22 +01:00
Vincent Koc f696430fd8 refactor(tts): split complex command handlers (#105005) 2026-07-12 13:23:27 +08:00
RickLin 4cfe0077ff fix(models): redact synthetic auth credentials from models status --json (#104734)
The provider auth overview passed the caller's synthetic-auth object
through to the JSON payload. Status hands it the full runtime shape,
which also carries the raw credential, so structural typing let live
API keys/tokens ship in a diagnostic surface (#104713). Re-project to
the declared value/source fields at the overview boundary.

Fixes #104713
2026-07-12 06:20:28 +01:00
Peter Steinberger 3d9b912b88 feat: sidebar session state slot, worktree/automation badges, archive disables bound cron jobs (#104730)
* feat(gateway): flag sessions with attached automations and disable bound cron jobs on archive

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

Refs #104700

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

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

Refs #104700

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

The shard shares one process; session-store state from earlier tests can make
the row load return null, which legitimately produces a keyless refresh
payload. Row-field projection stays covered by session-utils and
session-automation-index tests.
2026-07-12 06:19:01 +01:00
Vincent Koc 66cd7b1f4c refactor(acp): share runtime option action handling (#104998) 2026-07-12 13:13:31 +08:00
Vincent Koc 16d9ef5848 refactor(tasks): centralize managed flow mutations (#104994) 2026-07-12 13:11:03 +08:00
Vincent Koc b67417909b refactor: remove dead core and extension exports (#104963)
* refactor(agents): remove obsolete exec eligibility helper

* refactor(diffs): internalize viewer-only state

* refactor(qa-lab): internalize implementation helpers
2026-07-12 13:06:23 +08:00
Vincent Koc dd084b29dd fix(tasks): make registry reads index-safe (#104990) 2026-07-12 13:05:51 +08:00
Vincent Koc 2ff8fcab07 refactor(agents): share top-level resource collection (#104988) 2026-07-12 13:05:34 +08:00
Sally O'Malley f3971bbd56 feat(mcp): support sandboxed MCP Apps (#69039)
Implement stable opt-in MCP Apps negotiation, caller-specific tool
visibility, bounded ephemeral UI resources, a dedicated-origin double
iframe host, restrictive CSP, configuration, docs, and regression tests.

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Sally O'Malley <11166065+sallyom@users.noreply.github.com>
2026-07-11 22:04:38 -07:00
Peter Steinberger 4b82e1af19 test(plugins): move auth parity integration coverage (#104974) 2026-07-11 21:55:33 -07:00
Vincent Koc fbfa1378c0 test(sqlite): allow schema version pragma (#104960) 2026-07-12 12:36:57 +08:00
Ayaan Zaidi 33186b0f54 test(plugins): fail closed when an api-key auth method cannot be probed
An unprobeable api-key choice left its flag/env literals unchecked while CI
stayed green (ClawSweeper finding). The probe now supplies a real agent dir
and placeholder preflight opts (sentinel still bound to the declared
optionKey only, preserving the key-correctness proof), so every api-key
method must reach resolveApiKey — this immediately exercised
cloudflare-ai-gateway's account/gateway preflight path.
2026-07-12 10:06:26 +05:30
Ayaan Zaidi fe9af7dfc7 test(plugins): keep auth-literal parity test out of the unit-fast lane
Loading built plugin dists pulls large module graphs into the shared vitest
worker cache and broke co-resident vi.mock unit tests (memory-host-sdk
embeddings, checks-node-compact-large-2). An explicit dynamic import of the
surface loader trips the lane classifier's dynamic-import rule, moving the
file to the plugins project where dist loading is the norm.
2026-07-12 10:06:26 +05:30
Ayaan Zaidi 8f14f88690 test(plugins): fail auth-literal parity when a declared provider never registers
Silent skip on missing runtime registration recreated the drift class the
test guards (ClawSweeper finding); capability-only plugins now must register
zero text providers to be exempt.
2026-07-12 10:06:26 +05:30
Ayaan Zaidi 0e154d0467 fix(auto-reply): keep typed overloaded failures on the surfaced-copy path
Shipped behavior pins overloaded FailoverErrors to immediate dedicated copy
(agent-runner-execution.test.ts 'surfaces typed overloaded failures'); only
timeout and server_error reasons join the transient retry gate.
2026-07-12 10:06:26 +05:30
Ayaan Zaidi 57e0ea8f75 fix(auto-reply): honor structured FailoverError reasons in terminal catch classification
context_overflow and transient (timeout/server_error/overloaded) FailoverError
reasons now classify structurally like billing/rate_limit already do, instead
of relying on message text that may lack overflow or HTTP-status tokens. A
typed transient failure without a leading status token now takes the single
transient retry; typed context overflow suppresses the generic failure reply.
Part of #104219 (row 12).
2026-07-12 10:06:26 +05:30
Ayaan Zaidi d03defb8b4 refactor(plugins): single-source CORE_BUILT_IN_MODEL_APIS and add provider auth-literal parity test
gateway-startup-plugin-ids duplicated the built-in model-API set byte-for-byte
with nothing enforcing sync; provider-config-owner now owns it. New parity
test proves bundled provider manifests and runtime provider.auth declare the
same optionKey/cliFlag/envVar/method literals, guarding against silent
wizard-vs-runtime auth drift. Part of #104219 (row 12).
2026-07-12 10:06:26 +05:30
Ayaan Zaidi 596603f7d3 refactor(sessions): route get-reply-run session refresh through the accessor
Drops the last non-doctor whole-store resolveSessionStoreEntry read in the
reply pipeline; exact working-set key plus accessor disk read match the
sibling refresh sites in runPreparedReply. Part of #104219 (seam 8).
2026-07-12 10:06:11 +05:30
Vincent Koc 46aa7aed3a fix(sqlite): validate state before writable setup (#104952) 2026-07-12 12:13:37 +08:00
Vincent Koc a4cc24d113 fix(sqlite): reject corrupt backup and compact sources (#104938) 2026-07-12 11:53:03 +08:00
Vincent Koc 630a8c256e test(cli): require numeric retry timeouts 2026-07-12 11:49:18 +08:00
Vincent Koc 97d4ee9c51 refactor(agents): centralize attempt terminal outcome (#104936) 2026-07-12 11:49:09 +08:00
Peter Steinberger 6b95f98fe7 fix(core): make indexed access explicit across remaining src (NUIA phase 3b) (#104773)
* fix(core): make indexed access explicit in auto-reply, infra, and config

Part 1/3 of the src NUIA phase-3b burn-down (#104600): iteration and
destructuring over index reads, boundary guards on parsed input, and
named invariants. Config path walkers bind the path head once; SQLite
migration key handling is hoisted without query-shape changes.

* fix(core): make indexed access explicit in cli, gateway, commands, security, shared

Part 2/3: argv/token selection restructured, gateway event/attachment
invariants named, security parsers stay fail-closed (invariant
violations throw), edit-distance matrices access checked entries.

* fix(core): make indexed access explicit across remaining src surfaces

Part 3/3: channels, plugins, process, cron, plugin-sdk, media, logging,
tui, hooks, daemon, and small directories. Latent bug fixed: a tailnet
resolver could leak undefined through a string|null contract and now
fails with a descriptive local error.

* fix(core): keep optional boundaries optional after per-commit review

Review findings: expectDefined misused where absence is a legitimate
state. CLI --profile/route-args missing next tokens take their existing
miss paths; help normalization compares --help against the last
positional again; first-time plugin install spreads absent cfg.plugins;
denylist scan iterates manifest dependency entries instead of throwing
on omitted sections; tailnet resolver returns a guaranteed string at
the source instead of a caller-side undefined throw.

* refactor(core): closed-key provider labels and honest optional passthroughs

PROVIDER_LABELS becomes a satisfies-typed closed record (static reads
provably defined; dynamic lookups go through providerUsageLabel with
honest string|undefined). Status-scan overview passes its optional
params through unchanged instead of asserting them.

* fix(channels): make getChatChannelMeta honestly optional

The original signature claimed ChatChannelMeta while leaking undefined
on bundled channel id metadata drift; three of four callers already
handled absence. The return type now says so, and the one assuming
caller falls back to the raw channel label.

* fix(core): index-safety for post-rebase main drift

Covers the sqlite-sessions flip and auth-source-plan code that landed
mid-phase, plus the channel-validation test consuming the now honestly
optional getChatChannelMeta.

* refactor(channels): split chat-meta accessors along the SDK contract

getChatChannelMeta keeps its shipped plugin-SDK signature (defined for
bundled ids, fail-loud on impossible misses); new findChatChannelMeta
carries the drift-tolerant optional contract for core auto-enable and
formatting paths.

* fix(qa-channel): own channel metadata instead of a guaranteed-undefined catalog lookup

qa-channel spread getChatChannelMeta over an id that is never in the
bundled catalog, shipping an empty setup meta by accident; the fail-loud
SDK accessor exposed it. The channel now declares its metadata once.

* fix(gateway): heartbeat projection lookahead is optional at the transcript tail

expectDefined wrapped messages[i + 1] whose absence on the final message
is the normal case; the adjacent ternary already handled it. Restores
the plain optional read with an explicit guard in the pair condition.

* fix(plugin-sdk): channel plugin factory tolerates non-bundled channel ids again

createChannelPluginBase spreads bundled catalog meta for ANY channel id,
where absence is the normal case for external plugins; the resolver is
honestly optional again while the exported bundled-id accessor keeps the
fail-loud contract.

* fix(core): spreads of optional config sections stay optional

Fresh-setup and first-install paths (crestodian setup inference, hook
installs, agent config base, target agent models) legitimately lack the
section being rebuilt; spreading undefined is the shipped {} semantics.
Removes the remaining gratuitous assertion wraps found by tree audit.
2026-07-11 20:47:34 -07:00