Commit Graph

166 Commits

Author SHA1 Message Date
Peter Steinberger 066f5eb83d docs(plugins): register imap in generated plugin inventory (#130363)
The bundled imap plugin landed in #130230 without regenerating the plugin
inventory docs, so pnpm plugins:inventory:check failed on main and the plugin
was absent from the reference index. Regenerate, and register its operator
guide in PLUGIN_DOC_ALIASES so the generated reference page links to
/automation/imap (same mechanism codex and firecrawl use).
2026-08-26 13:33:30 -07:00
Josh Avant 424521a3d3 fix(file-transfer): keep remembered approvals exact (#129762)
* fix(file-transfer): bind standing approvals exactly

* fix(file-transfer): keep validator error lint-safe

* fix(file-transfer): bind directory listing target before I/O

* fix(file-transfer): keep dir list preflight type stable

* test(file-transfer): split directory listing policy coverage

* fix(file-transfer): bind final node effects

* fix(file-transfer): close migration and archive gaps

* fix(file-transfer): bind standing grants before preflight

* fix(file-transfer): bind directory listings to checked target

* fix(file-transfer): bind final effects to filesystem identity

* test(file-transfer): prove exact approval transport

* fix(file-transfer): keep reapproval prompts path-scoped

* chore(config): refresh generated baselines
2026-08-26 09:38:50 -07:00
Peter Steinberger ad1e946c7a feat(a2a): add A2A v1.0 agent-interop channel plugin (#130008)
* feat(a2a): add A2A v1.0 agent-interop channel plugin

Adds `a2a` as a bundled, default-off channel plugin so A2A-compliant agents
(Hermes Agent, LangChain, CrewAI, Google ADK) can discover an OpenClaw gateway
and send it tasks, and so OpenClaw can address configured peers.

Inbound HTTP (`/.well-known/agent-card.json`, `/a2a/v1`) runs through the normal
channel ingress path, so peer messages inherit allowlist admission, provenance
framing, and session routing. The agent reply returns through the channel
delivery callback and resolves the A2A task with its artifact, correlated per
(peer, contextId) FIFO so concurrent sends cannot cross-talk.

Wire format follows the canonical v1.0.0 spec sources (a2aproject/A2A
specification/a2a.proto): PascalCase SendMessage/GetTask/CancelTask,
supportedInterfaces[] rather than the 0.3-era top-level url/protocolVersion,
member-presence Part oneof, TASK_STATE_*/ROLE_* enums, no Task.kind. The 0.3
dotted method names are accepted as explicit compat aliases because shipped
Hermes-generation peers still send them.

Security: per-peer bearer tokens compared in constant time, per-peer sliding
window rate limit, 1 MiB body cap, 64 KiB inbound text cap, tasks scoped to
their owning peer, outbound redirect: "error", and no inbound-controlled target
URLs. With no peers configured the channel stays unconfigured and registers no
routes.

Live-verified against a real gateway on an isolated state dir with a mock
provider: 31/31 proofs, including the agent reply round-tripping into the task
artifact. That run caught two defects fixed here:

- The agent card read `cfg.agents.list` directly, so gateways configured with
  the canonical `agents.entries` roster advertised zero skills. Now uses
  listAgentIds/resolveAgentConfig, which read either roster shape.
- `returnImmediately` dispatches inherited the HTTP request's released work-
  admission root and every async task failed as GatewayDrainingError. Now
  reserves an independent root via runDetachedWebhookWork, matching sms/line/zalo.

* fix(a2a): route outbound sends through the SSRF guard and land setup metadata

CI on the first push surfaced four real defects that local `check:changed` did
not cover (it runs no oxlint or typecheck lane):

- Outbound peer sends used raw `fetch()`, tripping the channel/plugin
  no-raw-fetch boundary. They now go through `fetchWithSsrFGuard` with
  `maxRedirects: 0`, so A2A egress carries the same SSRF policy as every other
  plugin call and a redirect cannot re-target a delivered task.
- The channel declared an empty setup contract while its package manifest
  declared none, so the bundled-channel shape contract failed. The wizard now
  collects `advertisedUrl` plus a first peer name/token pair, which is the
  minimum that leaves A2A actually configured (it stays unconfigured until one
  peer credential exists), and the package manifest mirrors that metadata.
- Six lint errors in the test files: base-to-string on `BodyInit` bodies, an
  unused mock, and a shadowed `options` parameter. Request bodies now go through
  a typed reader that asserts the serialized-string contract before parsing.
- A card assertion referenced `capabilities` without declaring it on the local
  response type, failing test typecheck.

Outbound redirect handling moves from `redirect: "error"` to the guard's
`manual` inspection; the adapter tests assert the new shape.

* fix(a2a): drop route replaceExisting, accept configWrites, register runtime api

CI after the interop run surfaced four more gates:

- `registerPluginHttpRoute` used `replaceExisting: true`, tripping the
  GHSA-RQP8-Q22P-5J9Q rule: a duplicate path can silently replace another
  account's handler. A2A owns fixed global paths on a single account, so a
  duplicate registration means a stale or conflicting owner. It now fails loudly
  through `throwOnFailure` instead.
- The channel schema rejected `channels.a2a.configWrites`, which every bundled
  channel must accept; added to the zod schema, the manifest schema, and the
  config type, then regenerated the channel metadata.
- The new `input` assertion in the setup adapter needed a `// SAFETY:` line for
  the assertion ratchet.
- `extensions/a2a/runtime-api.ts` needed registering in the runtime-api
  classification list, like every other bundled channel barrel.

Also repairs a pre-existing incomplete `vi.mock` factory for `../infra/fs-safe.js`
in the agent-delete suites. Both pass in isolation, but the shared-worker lane
lets a sibling importer reach `readLocalFileSafely`, which the partial factory
never exported; adding this channel changed shard composition and surfaced it.
The factory now spreads the real module and overrides only `movePathToTrash`.

* chore(a2a): refresh config baseline for the configWrites surface

* chore(tests): adopt main's fs-safe mock repair for the agent-delete suites

Main landed the same importOriginal spread for the shared-worker mock-defeat
while this branch carried an equivalent fix; take main's version verbatim so the
two do not conflict.

* fix(a2a): isolate peer sessions and stop faking task cancellation

Addresses both ClawSweeper P1 findings.

Peer sessions: inbound routing never passed `dmScope`, so it fell back to
`session.dmScope ?? "main"` and every authenticated peer converged on
`agent:main:main` under default config. Untrusted remote content was joining the
operator's own session, and peers shared conversation history. A2A now pins
`per-account-channel-peer`; the peer id already embeds the A2A contextId, so each
peer+context pair gets its own session regardless of global session config.

Cancellation: `CancelTask` marked the task `TASK_STATE_CANCELED` and discarded
the late reply, but the dispatched agent run kept going and could still use
tools. The peer was told the work stopped when it had not. There is no
plugin-facing seam to abort a live run, so cancellation is refused with -32004
instead of acknowledged, and the store's cancel path plus its canceled-delivery
tombstone are deleted rather than left as a lying terminal state. Documented as
an explicit limitation.

Live-verified on a real gateway: 34/34 proofs, including three distinct
`agent:main:a2a:default:direct:<peer>:<context>` sessions with zero traffic in
`agent:main:main`, and both cancel spellings refused while the task stays
WORKING. Re-ran the official a2a-sdk 1.1.2 Docker interop afterwards: 9/9.
2026-08-26 08:04:53 -07:00
Peter Steinberger 044c0feb7c fix(crabbox): preserve Machine0 provisioning budget (#128185)
* fix(crabbox): bound Machine0 lifecycle backoff recovery

* fix(crabbox): reserve full Machine0 cleanup budget

* fix(crabbox): allow paced Machine0 inspection

* fix(crabbox): reserve Machine0 readiness retry

* fix(crabbox): pace Machine0 readiness checks

* fix(crabbox): use readiness-aware Machine0 status

* feat(crabbox): forward explicit setup environment

* fix(crabbox): preserve bounded command failure context

* fix(crabbox): enforce exact setup environment
2026-08-25 03:41:06 -07:00
Peter Steinberger 295809df98 feat(geolocation): resolve client addresses to a coarse city via a bundled plugin (#128546)
* feat(geolocation): resolve client addresses to a coarse city via a bundled plugin

The Activity identity card could show a client's IP address but not where it
was, so an operator still had to look the address up by hand.

Add a bundled `geolocation` plugin that owns address-to-place resolution behind
one authenticated route, `GET /plugins/geolocation/lookup?ip=`. It downloads a
MaxMind-format database on first lookup into the state directory, answers from
that local copy, and refreshes it monthly, so a lookup never sends an address
to a third party. The Control UI renders the resolved city on the device row
next to the address and the client-reported time zone.

The default source is DB-IP City Lite under CC BY 4.0. That license requires
attribution, so every response carries the credit and the UI renders it next to
the value; the database is downloaded at runtime and never redistributed.
Plugin code and the `maxmind` reader are MIT. No free city-level IP database is
MIT-licensed, so the obligation lives with the data rather than the code, and
`databaseUrl` plus the attribution fields make the source swappable.

No new core provider kind: with one implementation the plugin owns everything
through the existing HTTP-route seam, keeping core plugin-agnostic. A second
provider is what would justify promoting this to a registry contract.

Availability and lookup failure stay distinguishable: a missing or still
downloading database answers 503, never `found: false`. A failed refresh serves
the cached copy, and a body that does not parse as an MMDB is discarded without
replacing a working database.

* fix(docs): correct geolocation config examples and add zh-CN glossary entries

The config examples used `plugins.<id>` instead of the real
`plugins.entries.<id>.config` shape, which the docs config-example
validator and src/config/docs-config-examples.test.ts both reject.
New doc labels also need zh-CN glossary entries.

* chore(labeler): cover the geolocation extension directory

AGENTS.md requires a labeler entry plus a GitHub label for every new
plugin surface; test/scripts/labeler-extension-coverage.test.ts enforces
the labeler half.

* fix(geolocation): address review findings on caching, download bounds, and scope

Cold-start lookups were permanently suppressed. The loader cached one promise
per address including failures, so the 15s browser deadline expiring against a
first download that takes ~46s cached a blank forever, and a mounted row only
looks up again when its IP changes. Lookups now return a discriminated
located/absent/unavailable result: only definitive answers are cached, and the
element retries an unavailable one on a widening 5s/15s/45s schedule.

Download limits ran after allocation. The size check happened only after
`response.arrayBuffer()` had buffered the whole body, and gunzip had no output
ceiling, so a replaced source or a compression bomb could exhaust Gateway memory
before rejection. The body now streams against a compressed ceiling enforced
per chunk, and inflation uses zlib's maxOutputLength.

Cached placements were not scoped to the Gateway. The cache keyed only by
address while endpoint and credentials come from the shared Gateway context, so
a switch could render the previous Gateway's answer. The shared reset hook now
supports multiple subscribers - a single slot silently dropped whichever
registered first - and the geolocation cache subscribes.

Unresolvable ranges no longer trigger a download. Only loopback suppresses `ip`
at connect, so Tailscale carrier-grade-NAT and LAN addresses are recorded and
displayed. No geolocation database contains them, so a tailnet-only or LAN-only
Gateway was downloading 125 MB to answer nothing. The route now answers those
ranges without loading the database, using the already-public
`isPrivateOrLoopbackHost` seam so the SDK surface budget is unchanged.

The quickstart queried a reserved documentation range while showing a located
response, which cannot happen; it now uses a routable address and documents the
not-found case.

* fix(deps): resync the lockfile after dropping the net-policy dependency

The geolocation plugin briefly depended on @openclaw/net-policy before
switching to the already-public isPrivateOrLoopbackHost SDK seam. The
package.json entry was removed without regenerating the lockfile, so the
frozen-lockfile install failed and every downstream CI job failed with it.
2026-08-24 04:56:03 -07:00
Ayaan Zaidi ca6fea301b refactor(plugins)!: remove OpenProse (#128494)
Remove the bundled OpenProse plugin and /prose command now that upstream owns the maintained Agent Skill. Preserve /prose as migration documentation and let Doctor clean stale plugin configuration.

BREAKING CHANGE: The bundled OpenProse plugin and /prose command are removed.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-24 10:39:46 +05:30
Peter Steinberger 6932897bf9 docs(plugins): show root CLI commands (#126621) 2026-08-20 02:42:05 -07:00
Peter Steinberger 0135046830 refactor(llama-cpp): use one provider for managed and existing servers (#126434)
* refactor(llama-cpp): unify server ownership modes

* test(llama-cpp): preserve shared discovery limits

* fix(plugin-sdk): retain provider auth removal export
2026-08-19 13:57:33 -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
Onur Solmaz c2de3206d4 feat(llama-cpp): support external llama-server
* feat(llama-cpp): add external server provider

* feat(llama-cpp): document external server setup

* refactor(llama-cpp): harden external provider boundaries

* fix(llama-cpp): support external structured output

* fix(llama-cpp): isolate replacement endpoint credentials

* test(llama-cpp): register external live shard

* fix(llama-cpp): preserve explicit endpoint authorization

* fix(llama-cpp): clear disabled inline credentials

* fix(llama-cpp): preserve external local service configs

* test(llama-cpp): cover retained external configs

* test(llama-cpp): cover authorization precedence
2026-08-19 17:32:00 +03:00
Peter Steinberger 97557ec3f5 fix(widgets): route show_widget through Discord Activities (#126294)
* refactor(widgets): unify Discord presentation

* fix(discord): keep incomplete Activity routes private

* fix(discord): require usable Activity accounts

* docs(discord): clarify hidden Activity routes
2026-08-19 05:41:37 -07:00
Dallin Romney adf2ca46bb chore(release): refresh generated preflight artifacts (#125586) 2026-08-18 07:10:49 -07:00
Peter Steinberger 6aa27d6ecd refactor: retire August compat windows (embedding API, pi aliases, target parser, spawning hook, setup exports, WhatsApp inbound aliases) (#124416)
* refactor(plugin-sdk): retire embedded Pi aliases

* refactor(channels): retire explicit target compatibility

* refactor(plugins): retire subagent spawning hook

* refactor(plugin-sdk): retire shipped channel setup exports

* refactor(whatsapp): retire inbound callback aliases

Proof: focused build and WhatsApp E2E green; broad WhatsApp suite 188/189 files green. extensions/whatsapp/src/monitor-inbox.policy.test.ts flakes only in the parallel batch and passes isolated (10/10).

* refactor(plugin-sdk): retire memory embedding registrar

Migrate every bundled provider and manifest to registerEmbeddingProvider and contracts.embeddingProviders. Preserve memory-specific batching, local-service acquisition, index identity, and auto-selection through the canonical generic registry adapter, then remove the parallel registrar, registry, diagnostics, contracts, tests, and docs.

* chore(plugin-sdk): tighten retired surface budgets

Pin the post-retirement public SDK surface to 144 entrypoints, 4,312 exports, 2,564 callable exports, and 1,133 deprecated exports; agent-harness-runtime now permits exactly nine deprecated exports.
2026-08-15 22:43:47 -07:00
Peter Steinberger bd1814bede fix(policy): require --agent for explicit workspaces (#123880)
* fix(policy): require explicit CLI agent owner

* chore(policy): leave release notes to release flow
2026-08-14 16:15:17 -07:00
Peter Steinberger 1348387076 refactor(plugins): replace node-llama-cpp with managed llama-server (#123105)
Move llama.cpp chat and local embeddings onto a verified externally managed llama-server runtime. Remove the in-process native runtime, forked embedding workers, and node-llama-cpp dependency while preserving guided setup, local GGUF models, tool-capable agent runs, diagnostics, and operator docs.
2026-08-13 16:58:20 -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
ClawSweeper eab26ec439 fix(microsoft-foundry): write canonical image model config (#121370)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-09 20:40:11 -07:00
Peter Steinberger f44c5e2e5e fix(plugins): surface manifest-only bundled capabilities (#121354)
Use a manifest-first inventory with independent coverage for manifest-only bundled capabilities.

Retire the undocumented thread-ownership plugin while Doctor removes stale references.

Document Talk voice and persist only provider-scoped voice selection.

Closes #121353
2026-08-09 19:43:49 -07:00
Peter Steinberger c092900e3c fix(plugins): keep OpenCode Go bundled (#120985)
* fix(plugins): keep OpenCode Go bundled

* fix(plugins): mark OpenCode Go dist bundled

* fix(docs): show OpenCode Go as bundled

* fix(release): defer bundled plugin publication
2026-08-09 03:09:47 -07:00
Peter Steinberger 48639663b0 chore(release): prepare 2026.8.1 (#120375) 2026-08-07 18:44:12 -07:00
Patrick Erichsen 05e3ce11ac fix(release): restore Fish Audio ClawHub publishing 2026-08-06 11:31:37 -07:00
Vincent Koc 52b8f9be80 fix(plugins): migrate Fish Audio plugin identity (#119900)
* fix(plugins): migrate Fish Audio plugin identity

* fix(plugins): tighten Fish Audio identity migration

* fix(plugins): follow catalog selector for id replacements

* fix(plugins): reject replacement install collisions

* refactor(plugins): reuse skipped update outcomes
2026-08-06 20:50:36 +08:00
Dallin Romney e9b25aa21d refactor(cua-computer): replace daemon MCP with CUA Driver SDK (#117205)
* chore(cua-computer): freeze CUA Driver 0.14.1 fixtures

* refactor(cua-computer): use CUA Driver SDK directly

* fix(cua-computer): repair CUA CI checks

* style(cua-computer): format driver cleanup

* fix(cua-computer): migrate retired driver path

* fix(cua-computer): start direct driver sessions
2026-08-02 20:03:24 +08:00
Vincent Koc 89aadef6ef feat(plugins): externalize iMessage channel (#117101) 2026-08-01 08:01:18 +08:00
Vincent Koc 61fb29e90a feat(plugins): externalize OpenCode Go provider (#117064) 2026-08-01 06:31:19 +08:00
Vincent Koc e73250f54b feat(plugins): externalize OpenCode provider (#117035)
* feat(plugins): externalize OpenCode provider

* docs: refresh OpenCode provider map
2026-08-01 05:07:35 +08:00
Vincent Koc e84e2a49fc feat(plugins): externalize NovitaAI provider (#117007) 2026-08-01 03:53:46 +08:00
Vincent Koc 8b93fd963c feat(plugins): externalize Mistral provider (#116919)
* feat(plugins): externalize Mistral provider

* fix(update): preserve external provider models during repair

* chore(release): keep Mistral note in PR body
2026-08-01 03:04:12 +08:00
Vincent Koc a1026663ae feat(plugins): externalize ComfyUI provider (#116888) 2026-07-31 23:26:51 +08:00
Vincent Koc e93de36081 feat(plugins): externalize BytePlus provider (#116866) 2026-07-31 22:37:47 +08:00
Vincent Koc fab2c33cad feat(plugins): externalize Xiaomi provider (#116861) 2026-07-31 22:02:07 +08:00
Vincent Koc b2b62b2e1e feat(plugins): externalize Volcengine provider (#116854) 2026-07-31 21:28:01 +08:00
Vincent Koc ba1a6722bb feat(plugins): externalize Vydra provider (#116813) 2026-07-31 20:35:43 +08:00
Vincent Koc eb55c8ea8f feat(plugins): externalize Voyage embeddings (#116785)
* feat(voyage): externalize embedding provider

* fix(voyage): drop stale bundled description
2026-07-31 19:52:33 +08:00
Vincent Koc 6830820755 feat(plugins): externalize DuckDuckGo search (#116740) 2026-07-31 18:49:07 +08:00
Vincent Koc a550827dad feat(plugins): externalize Synthetic provider (#116720) 2026-07-31 17:19:43 +08:00
Vincent Koc fa4cc51a87 feat(plugins): externalize Teams and Zoom meetings (#116682) 2026-07-31 14:10:46 +08:00
Vincent Koc c892a712e6 feat(plugins): externalize Cohere and Meta providers (#116662)
* feat(plugins): externalize Cohere and Meta providers

* docs(changelog): note provider externalization

* chore: keep changelog release-owned
2026-07-31 12:53:01 +08:00
Peter Steinberger e8524a5839 feat: add Fish Audio S2.1 and local MLX speech (#115790)
* feat: add Fish Audio speech support

* chore: remove unused speech exports

* chore: keep Fish API constant private

* test: remove stale code mode import

* style: use bracket access for Fish voice ids

* test: restore QA evidence validator import
2026-07-29 05:15:33 -04:00
Peter Steinberger feb5883089 docs: add Buzz to generated plugin inventory (#114875)
* docs: refresh Buzz plugin inventory

* docs: refresh generated docs map
2026-07-27 22:59:32 -04:00
Jason (Json) 62baf451c1 fix(deepinfra): remove deprecated embedding provider warning (#114727)
* fix(deepinfra): migrate embedding provider registration

* fix(deepinfra): preserve embedding index identity
2026-07-27 14:53:34 -06:00
Peter Steinberger bbc73c36bd feat(plugins): beam local coding sessions into a read-only catalog (#112323)
* feat(plugins): add read-only session beam

* test(plugins): tighten Beam HTTP fixtures

* docs(plugins): refresh Beam inventory counts

* fix(plugins): keep Beam wire types private

* fix(plugins): stabilize Beam transcript paging

* fix(plugins): honor Beam Control UI base paths
2026-07-27 15:37:36 -04:00
Peter Steinberger 9dfb2a1318 fix: show native history in adopted Pi and OpenCode sessions (#114040)
* fix(plugins): import adopted catalog history into the OpenClaw transcript

Import native Pi and OpenCode history when a catalog session is adopted so the OpenClaw transcript reflects the full conversation immediately.

Mark imported user rows with mirrorOrigin because they are transcript mirrors, not new external turns. This preserves watcher deduplication and prevents adopted history from being reported as fresh upstream input.

* refactor(plugins): split catalog history importer

Keep the session catalog contract module leaf-like by moving transcript mutation into a dedicated runtime module. This breaks the registry-to-transcript import cycle while preserving the Plugin SDK entrypoint and importer behavior.
2026-07-26 02:09:48 -04:00
Peter Steinberger e19841c725 feat: continue Pi and OpenCode sessions from the session catalog (#113718)
* feat(plugins): add acpSessionBinding seam for ACP session adoption

* feat(acpx,opencode): adopt existing Pi and OpenCode sessions from the catalog

* fix(ci): satisfy dead-code and temp-path guards

* docs(acpx): record why pi-acp session-root resolution stays strict
2026-07-25 08:35:47 -07:00
sallyom f045f33a62 feat(onepassword): add managed SecretRef integration 2026-07-25 06:03:30 -05:00
Peter Steinberger 5bea268128 feat(anthropic): complete Claude Opus 5 rollout (#113392)
* feat(models): add Claude Opus 5 support

* test(models): align Opus 5 setup fixtures

* test(models): update ambient Opus 5 detection

* fix(models): reconcile Opus 5 support with main
2026-07-24 14:55:36 -07:00
Peter Steinberger edecdbd05e refactor(config): config-surface reduction tranche 3 — product consolidations (review request) (#111527)
* refactor(config): consolidate media model lists

* refactor(config): unify memory configuration

* refactor(config): consolidate TTS ownership

* refactor(config): move typing policy to agents

* refactor(config): retire product-level config surfaces

* refactor(config): share scoped tool policy type

* chore(config): refresh generated baselines

* fix(config): honor agent typing overrides

* fix(config): migrate sibling config consumers

* refactor(infra): keep base64url decoder private

* fix(config): strip invalid legacy TTS values

* chore(config): refresh rebased baseline hash

* fix(doctor): route legacy messages.tts.realtime voice to talk during tts move

* refactor(config): polish final layout names

* refactor(config): freeze retired tuning defaults

* feat(config): add fast mode default symmetry

* refactor(config): key agent entries by id

* docs(config): update final layout reference

* test(config): cover final layout migrations

* chore(config): refresh final layout baselines

* fix(config): align final layout runtime readers

* fix(config): align remaining readers

* fix(config): stabilize final layout migrations

* fix(config): finalize config projection proof

* fix(config): address final layout review

* docs(release): preserve historical config names

* fix(config): complete keyed agent migration

* fix(config): close final migration gaps

* fix(config): finish full-branch review

* fix(config): complete runtime secret detection

* fix(config): close final review findings

* fix(config): finish canonical docs and heartbeat migration

* fix(config): integrate latest main after rebase

* refactor(env): isolate test-only controls

* refactor(env): isolate build and development controls

* refactor(env): collapse process identity indirection

* refactor(env): remove duplicate config and temp aliases

* docs(env): define the operator-facing allowlist

* ci(env): ratchet production variable count

* fix(env): remove stale provider helper import

* fix(env): make ratchet sorting explicit

* test(env): keep test seam in dead-code audit

* test(env): cover ratchet growth and boundary; document surface budgets

* docs(config): document tier-eval consolidations

* docs(config): clarify speech preference ownership

* test(memory): align retired tuning fixtures

* refactor(memory): freeze engine heuristics

* refactor(config): apply tier-eval tranche

* refactor(tts): move persona shaping to providers

* refactor(compaction): move prompt policy to providers

* test(config): align hookified prompt fixtures

* chore(deadcode): classify test-only exports

* chore(github): remove unused spawn helper

* chore(deadcode): classify queue diagnostics

* chore(deadcode): remove unused lane snapshot export

* chore(plugin-sdk): ratchet consolidated surface

* fix(config): integrate latest main after rebase
2026-07-21 20:28:43 -07:00
Peter Steinberger f695be341c feat(cua-computer): add experimental Windows/Linux computer-use fulfiller (#112267)
* feat(cua-computer): add experimental Windows/Linux computer-use fulfiller

Bundled plugin that fulfills the capability-based computer.act + screen.snapshot
node contract on Windows and Linux by supervising a pinned cua-driver 0.10.x
daemon over MCP stdio. macOS keeps the Peekaboo fulfiller; this plugin is
disabled by default and never available on darwin.

Grounded in cua-driver 0.10.0 source (tool schemas, refusal codes, coordinate
spaces, session/daemon lifecycle). Notable safety and correctness properties:
- Deny-by-default env allowlist so OpenClaw secrets (provider/channel tokens,
  CUA_API_KEY) never reach the separately installed daemon; telemetry and
  update checks forced off.
- Version-gated handshake (exact-minor pin + capability/schema version),
  time-bounded so a corrected driver recovers without a node restart.
- Robust daemon supervision: full readiness-budget polling, startup-race
  tolerance, signal-death and spawn-error recovery, shared-daemon lifecycle
  (never killed on dispose).
- Frame authorization preserved within upstream limits (generation + full live
  geometry; capture refused when screen and screenshot geometry diverge).
- Action mapping refuses inputs cua-driver cannot faithfully deliver:
  layout-shifted keys, modifier-held drag/scroll, Linux modifier clicks,
  hold_key/mouse down-up, non-positive scroll; drag duration clamped.

* fix(cua-computer): satisfy lint, test-types, dead-code, and docs-map gates
2026-07-21 05:58:04 -07:00
Peter Steinberger be5e427f56 feat(dashboard): plugin-declared widget data bindings and action verbs (#112083)
* feat(dashboard): add plugin capability declarations

* docs(dashboard): describe plugin capabilities

* fix(plugins): preserve registry map cloning

* fix(dashboard): make plugin grant ids unambiguous

* fix(dashboard): align generated plugin grant ids

* chore(boards): internalize verb ids and refresh protocol snapshots
2026-07-20 22:43:04 -07:00
Peter Steinberger 5420c5c409 feat(clickclack): session discussions — bound channels, side agent, lifecycle sync (#111503)
* feat(clickclack): add session discussions

* chore: remove release-owned changelog entry

* refactor(clickclack): split discussion service workflows

* fix(clickclack): satisfy plugin surface gates

* fix: narrow routing peer in inbound test and refresh docs map
2026-07-19 14:47:14 -07:00