Commit Graph

300 Commits

Author SHA1 Message Date
Peter Steinberger e9d3cf1a64 fix(daemon): preserve file-backed gateway auth secrets across service regeneration (#120458) 2026-08-07 21:19:33 -07:00
Peter Steinberger f4387b7a5e feat(plugins): support the Agent Plugins bundle format (#120115)
* feat(plugins): support the Agent Plugins bundle format

* docs(plugins): document the Agent Plugins bundle format

* test(agents): preserve agent bundle runtime discovery

* fix(plugins): isolate Agent Plugins data-dir failures and align MCP support reporting

* docs(plugins): list Agent Plugins in the canonical plugin-format guides

* fix(plugins): gate Agent Plugins detection on schema, pure inspection, root-relative cwd

* fix(plugins): record Agent Plugins data-dir ownership explicitly

* docs(plugins): cover Agent Plugins in the CLI install detection guide

* fix(plugins): carry Agent Plugins data-dir and transport contracts through external MCP projections
2026-08-07 02:55:08 -07:00
Vincent Koc b8b878ed33 fix(plugins): preserve startup release during repair (#120085)
* fix(plugins): preserve startup compatibility version

* chore(ci): refresh merge context
2026-08-07 09:37:33 +08:00
Vincent Koc ef11eae39b fix(plugins): preserve install index state across failures (#119228)
* fix(plugins): preserve install index policy config

* fix(plugins): restore complete install index state

* fix(plugins): fence install index rollback

* fix(plugins): fence generic install index rollback

* fix(plugins): keep lifecycle lease context private

* test(cli): align plugin index rollback mocks

* test(plugins): enforce index rollback receipts

* fix(plugins): serialize install rollback with config commit

* test(plugins): keep legacy index writer mock private
2026-08-05 01:04:17 +08:00
Peter Steinberger 6ee406b1bf fix(plugins): repair stale host packages after OpenClaw upgrades (#118304)
* fix(plugins): repair stale registered host package links

* refactor(plugins): isolate authoritative host-link repair owners

* fix(plugins): constrain host repair to registered install roots
2026-08-02 18:10:26 -07:00
WhatsSkiLL 428a9e9cbc fix(update): return failure when dirty checkout blocks update (#117452)
Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
2026-08-01 11:11:19 -07:00
Peter Steinberger d88c338a82 fix(update): keep rolled-back Git installs runnable (#117294)
* fix(update): restore runtime after git rollback

* chore(update): leave changelog to release automation

* test(update): cover rollback restart policy

* test(update): satisfy caller fixture types
2026-08-01 02:20:13 -07:00
Sasan 6938f7dddb fix: allow gateway service commands for named profiles (#116314)
* fix: gateway service commands refuse a named profile or relocated OPENCLAW_HOME

- Resolve the default install identity against the canonical state directory
  for the active OpenClaw home and profile instead of the unprofiled OS
  account default.
- `--profile <name>` / `--dev` project `.openclaw-<profile>` state and config
  paths, so every named profile was classified as isolated state and refused
  `install`, `start`, `stop`, `restart`, `uninstall`, Doctor service repair,
  and self-update service handling.
- `OPENCLAW_HOME` relocates all OpenClaw path defaults and is documented for
  running as a dedicated service user; a relocated home is now an install
  identity. `HOME` alone still is not.
- An `OPENCLAW_STATE_DIR` or `OPENCLAW_CONFIG_PATH` pointing outside those
  canonical paths is still treated as isolated state.
- Recovery guidance in the refusal message now names the paths that must match.

Verified: focused vitest shards for the changed suites plus the daemon, CLI,
and doctor suites that consume the identity check; tsgo core and core-test
lanes; oxlint; docs format, MDX, link, and map checks.

* fix(gateway): keep relocated homes isolated

* fix(config): validate service profile identity

* fix(daemon): enforce named-profile service ownership

* fix(update): reject drifted service selectors before probes

* test(windows): prove scheduled task lifecycle

* test(windows): harden scheduled task proof cleanup

* test(windows): bind lifecycle proof to checkout

* test(windows): normalize cleanup exit status

* test(windows): verify effective task privilege

* test(windows): protect scheduled task proof roots

* test(windows): prove listener-owned task lifecycle

* test(windows): fix scheduled task proof contracts

* test(windows): remove redundant mock coercions

* test(windows): measure fallback before task probes

* test(windows): prove scheduled task process origin

* fix(gateway): preserve unmanaged restart fallback

* test(gateway): cover denied restart ownership

* test(gateway): keep restart helper types private

* test(gateway): classify lifecycle helpers as test code

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-08-01 11:28:39 +08:00
Harjoth Khara 895b691c55 fix(daemon): refuse duplicate launchd gateway managers (#97285)
* fix(daemon): block duplicate launchd owners

Co-authored-by: Harjoth Khara <harjoth.khara@gmail.com>

* fix(ci): satisfy launchd docs and lint gates

* fix(ci): remove unused launchd exports

* docs: refresh gateway map

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-29 13:31:22 -04:00
Simranjit Singh 26b236dae3 fix(update): gateway restart survives inherited cross-user D-Bus environment (#111534)
* fix(update): repair mismatched user bus for restart

* fix(update): preserve custom user bus on restart

* fix(update): preserve effective-user D-Bus transports

* fix(update): preserve effective-user D-Bus transports

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-29 10:25:10 -04:00
Peter Steinberger 8ec4a059fc fix(codex): keep stressed inference turns isolated and observable (#115893) 2026-07-29 09:11:20 -04:00
Vincent Koc 38abf500ba fix(update): stabilize cross-version dev upgrades (#115651)
* fix(e2e): stabilize cross-version Parallels upgrades

* fix(e2e): avoid inline macOS guest probes

* fix(e2e): detach Windows dev updates

* fix(e2e): detach macOS guest updates with Node

* fix(e2e): initialize skipped upgrade config

* fix(update): use partial clone for dev checkout

* fix(update): keep Windows dev checkouts clean

* fix(e2e): pin Parallels dev update targets

* fix(e2e): own Parallels gateway restarts

* fix(e2e): verify pinned Parallels checkouts

* fix(e2e): forward Parallels update budgets

* fix(e2e): use canonical provider auth choices

* chore: leave changelog to release automation

* test(ui): stabilize route waits on loaded runners
2026-07-29 19:52:34 +08:00
Peter Steinberger 5fe07e4ae8 fix(update): honor declared plugin entrypoints during repair (#115610) 2026-07-29 01:43:30 -04:00
Peter Steinberger 5457165289 fix(cli): honor help, dry-run, and plugin pin contracts (#115464) 2026-07-28 23:01:24 -04:00
Vincent Koc 4ee399c714 fix(update): finalize install switches in fresh process 2026-07-29 00:24:09 +08:00
Peter Steinberger d68ebc8932 fix(cli): keep update dry runs free of mutations (#114803) 2026-07-27 20:10:35 -04:00
Peter Steinberger 9e2ffea0de fix(cli): reject empty update timeout arguments (#114700) 2026-07-27 16:08:00 -04:00
Peter Steinberger c6b2ec28c8 refactor: mechanical dedup batch (protocol types, update-cli bridge, talk fallback) (#114432)
* refactor(onboarding): remove search setup barrel

* refactor(plugins): reuse detected package manifest

* test(update): replace global helper bridges

* refactor(talk): remove dead legacy response fallback

* refactor(protocol): derive root types from schema

The maintainer approved broadening the additive schema-backed type surface without a protocol version bump.

* fix(plugins): drop stale package path import

* test(protocol): type dynamic registry lookups

* docs(talk): explain canonical response boundary

* refactor(talk): enforce canonical response input

* fix(protocol): keep root type exports registry-free

* refactor(update): expose helpers through test facades

* fix(protocol): keep result types on leaf schema modules
2026-07-27 06:55:07 -04:00
Vincent Koc 8029b3bbb8 fix(update): repair plugin config during upgrade finalization (#113324)
* fix(update): repair configured plugins during finalization

* fix(update): allow legacy config through migration
2026-07-25 00:18:59 +08:00
Vincent Koc 218c2fe3a5 fix(update): preserve JSON output during resume (#113298) 2026-07-24 18:56:20 +08:00
Vincent Koc 741ed2d6a8 fix(update): migrate config before plugin convergence (#113280) 2026-07-24 16:55:38 +08:00
Peter Steinberger a12e0f26ee fix(plugins): serialize lifecycle mutations and preserve setup-required installs (#112763)
* fix(plugins): harden concurrent lifecycle mutations

* fix(update): preserve post-core restart snapshot

* fix(update): retain authoritative plugin records on resume

* fix(update): reconcile plugin records after handoff
2026-07-22 23:25:48 -04:00
Jesse Merhi 4a2a600809 feat(channels): add channel-owned setup contracts (#112176)
* feat(channels): add channel-owned setup contracts

* test(channels): align legacy setup fixtures

* chore(channels): regenerate config and SDK baselines after rebase

* fix(update): run fresh doctor after current-process core changes

* fix(channels): align add pre-scan with execution precedence

* style(cli): format channels-cli test additions

* fix(channels): restore option-before-positional channel resolution via metadata arity scan

* fix(channels): keep help flags out of metadata arity escalation

* test(update): mock fresh post-update doctor in current-process suites

* style: format review fixes and correct entrypoint mock type

* fix(channels): register only modern contract options for dual-publishing plugins

* test(update): align downgrade suites with fresh-doctor child invocation

* docs(channels): record empty-contract and input-forwarding invariants

* fix(line): keep the shipped --token switch as a channel access token alias

* fix(signal): stop treating exact cross-family loopback endpoints as bind-aligned

* chore(config): regenerate docs config baselines after second rebase

* style: format rebased channels add tests

* fix(channels): enforce field-key and flag-name agreement in setup contracts

* fix(signal): detect container endpoints for bare --http-url setup

* fix(signal): ignore unconfigured accounts in transport collision checks

* fix(channels): validate negated setup flags in contract and normalizer

* fix(signal): preserve existing transport kind when setup detection is unreachable

* style(signal): use direct boolean check in collision guard

* style(signal): type test config literals

* docs(update): record two-read design of fresh-doctor validation gate

* fix(channels): satisfy post-rebase architecture gates

* docs: refresh channel setup map

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-22 19:57:42 -04:00
zw-xysk 1ee91d4484 fix(cli): silent drop of malformed post-core install-records JSON (#109989)
* fix(cli): fail closed on malformed post-core install-records JSON

Missing handoff files stay optional. Corrupt JSON previously returned
undefined and dropped parent recovery context during update resume.

* test(cli): cover post-core install-records missing vs malformed JSON

Includes live temp-file proof that corrupt handoff is rejected.

* fix(cli): direct corrupt post-core handoffs to doctor

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-20 21:42:30 -07:00
Peter Steinberger 0d91b07f5b refactor(update): split update-command into focused modules under the line limit (#110550) 2026-07-18 09:51:00 +01:00
Shakker 006d6556b8 refactor: expose selected plugin payload checks 2026-07-18 07:13:45 +01:00
Peter Steinberger a89f01abf4 perf(sqlite): fast schema gates, background integrity verification, and downgrade protection (#110271)
* perf(sqlite): gate schema version before integrity scans and quarantine terminal open failures

* feat(gateway): refuse incompatible database schemas at boot and verify integrity in the background

* feat(update): refuse installing builds that cannot open the current databases

* docs: add database schema reference with version history and downgrade guidance

* test(update): tolerate optional runner options in git-mutation mocks

* refactor(update): split npm package-target metadata out of update-check

* chore: model verifier internals for knip and regenerate docs map

* chore(i18n): resync stale iOS localization catalog

* chore: allowlist read-only preflight and verifier raw SQLite access
2026-07-18 05:49:39 +01:00
Vito Cappello cd1ab40632 fix: gateway boots when a configured plugin payload is broken (#110239)
* fix: quarantine broken plugins during gateway startup

* fix(plugins): preserve degraded boot on package read errors

* fix(gateway): emit quarantine diagnostic once

* fix(gateway): refresh plugin quarantine every boot

* fix(gateway): harden plugin payload quarantine

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>

* fix(ci): satisfy plugin quarantine checks

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>

---------

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 03:50:50 +01:00
DaigoSoup 025cecf1f9 fix: avoid false macOS gateway restart failures (#109955)
* fix: wait through launchd KeepAlive restart throttling

* ci: retrigger checks

* test: make update restart test platform-independent

---------

Co-authored-by: Josh Lehman <josh@martian.engineering>
2026-07-17 17:19:23 -07:00
Vito Cappello 748fc04419 fix(update): classify unreadable plugin manifests (#110200)
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
2026-07-17 16:33:04 -07:00
Shakker 244f4965dc feat: add external gateway supervision policy 2026-07-16 17:01:39 +01:00
Peter Steinberger 8fe4eeea9e fix(exec): stop isolated state dirs from moving live approvals (#108742)
* fix(exec): isolate approval state directories

* chore: drop release-owned changelog entry

* chore: refresh native i18n inventory

* fix(ci): pin XcodeGen for Periphery scans
2026-07-16 08:57:32 -07:00
ooiuuii 6828bcac53 fix(update): verify Windows restart listener owners (#108023)
* fix(update): verify Windows restart listener owners

* fix(update): harden Windows listener ownership checks

Co-authored-by: luyifan <al3060388206@gmail.com>

* fix(update): test shipped Windows listener policy

* ci: refresh merge ref after main schema fix

* ci: refresh merge ref

* fix(lint): drop redundant String conversion in pwsh lookup

* ci: pick up periphery workflow fix

* ci: pick up pinned xcodegen installer

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 07:59:13 -07:00
Abner Shang 5ad0d4d6c0 fix: avoid false restart failure during startup migrations (#105544)
* fix: wait for startup migrations on restart

* fix: honor restart readiness caller context

* fix: preserve restart service identity

* fix: refresh readiness context after repair

* fix: bound migration restart wait by wall clock

Co-authored-by: Abner Shang <abner.shang@gmail.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 02:04:49 -07:00
Peter Steinberger 9d4652a46c refactor: make update runtime preflight result explicit (#108760) 2026-07-16 01:48:29 -07:00
Peter Steinberger 48b11d1c66 fix(update): repair obsolete managed Gateway Node (#108668)
* fix(update): refresh stale managed service Node

* refactor(update): keep preflight result internal

* docs(changelog): defer update note to release
2026-07-16 00:41:43 -07:00
Peter Steinberger 9497450511 refactor: eliminate dead-export baseline (#108376)
Burn the grandfathered unused-export baseline to zero and enforce a hard-zero Knip gate.
2026-07-15 17:05:07 +01:00
jincheng-xydt b2e42e3645 fix(update): preserve pnpm and Bun global installs (#107802)
* fix(update): preserve pnpm and bun global installs

* fix(update): anchor pnpm updates to invoking install

* fix(update): recover skipped pnpm lifecycle

* fix(update): fail closed on ambiguous pnpm ownership

* fix(update): tolerate pnpm probe warnings

* fix(update): bind pnpm installs to project owners

* fix(update): isolate pnpm mutations from caller pins

* docs(changelog): credit pnpm 11 report

Co-authored-by: jincheng-xydt <xu.jincheng@xydigit.com>

* chore(changelog): defer release note ownership

* fix(update): make package-root fallback explicit

* test(update): split pnpm scenario coverage

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-15 08:03:35 -07:00
Peter Steinberger 0be803ebc0 fix: npm 12 global updates no longer stop at the candidate guard (#108100)
* fix(update): approve candidate lifecycle on npm 12

* test(update): align npm lifecycle argv expectations
2026-07-15 01:10:32 -07:00
Peter Steinberger e323c70ada refactor(cli): trim internal dead exports (#107654)
* refactor(cli): trim internal helper exports

* chore(deadcode): refresh CLI export baseline
2026-07-14 09:28:16 -07:00
Peter Steinberger f81f9d8570 chore: enforce max-lines suppression ratchet (#107315)
* ci: enforce max-lines suppression ratchet

* chore: prune stale max-lines suppression

* fix: close max-lines ratchet enforcement gaps

* fix: harden max-lines ratchet checks

* fix(ci): satisfy max-lines ratchet checks

* style: format max-lines declarations

* fix(ci): match oxlint suppression grammar

* test: isolate max-lines git fixtures

* chore: prune resolved max-lines debt

* test: skip newline path fixture on Windows

* fix: harden max-lines suppression ratchet

* chore: refresh max-lines baseline

* fix: close max-lines ratchet bypasses

* fix: derive ratchet base from PR merge tree

* fix: support older Git in staged ratchet

* fix: align max-lines declarations and baseline

* chore: refresh max-lines baseline for current main

* fix: exclude generated wizard locales from max-lines

* chore: prune resolved max-lines debt
2026-07-14 09:27:02 -07:00
Peter Steinberger fe715a1b88 refactor(daemon): trim internal exports (#107075) 2026-07-13 20:43:08 -07:00
Peter Steinberger db02a96c4c refactor(process): route bounded commands through Execa (#106495)
* refactor(process): centralize bounded command execution

* refactor(process): migrate core one-shot commands

* refactor(plugins): migrate one-shot commands

* fix(process): await Windows tree termination

* chore(plugin-sdk): refresh process runtime surface

* refactor(process): migrate remaining bounded commands

* refactor(process): normalize command result handling

* refactor(process): split execution responsibilities

* chore(plugin-sdk): refresh API baseline

* chore(process): remove release-owned changelog entry

* fix(process): narrow binary command input checks

* fix(process): cap sandbox command output

* fix(qa-lab): preserve exact node probe env

* chore(ci): refresh dead export baseline

* fix(process): preserve force-kill command deadlines

* fix(process): avoid post-exit timeout reclassification

* test(process): update scp staging wrapper mock

* test(process): update remaining wrapper mocks

* refactor(qa-lab): preserve Execa tar execution
2026-07-13 11:07:35 -07:00
Peter Steinberger a965d28e04 refactor(cli): trim internal command exports (#106426) 2026-07-13 06:47:02 -07:00
Peter Steinberger a627a77eab refactor(cli): split update command orchestration (#106322)
* refactor(cli): split update command orchestration

* fix(ci): refresh update command export baseline
2026-07-13 05:11:22 -07:00
Peter Steinberger e2ec8283c4 refactor(deadcode): trim mid-size src exports (#105888)
* refactor(deadcode): trim auto-reply and CLI exports

* refactor(deadcode): trim cron and task exports

* refactor(deadcode): trim fleet and process exports

* test(deadcode): exercise live task and process seams

* test(fleet): cover stream redaction through owner module

* refactor(security): trim dead internal exports

* refactor(secrets): trim dead internal exports

* refactor(deadcode): trim remaining src exports

* refactor(deadcode): remove test-only runtime exports

* refactor(deadcode): trim pairing test exports

* refactor(deadcode): reconcile refreshed baseline

* test(auto-reply): deduplicate queue state imports
2026-07-13 00:42:56 -07:00
Vincent Koc f33ab243cf fix(sqlite): reject runtimes vulnerable to WAL corruption (#106065)
* fix(sqlite): require WAL-reset-safe Node runtime

* docs(sqlite): document safe Node runtime floor

* fix(sqlite): defer runtime library validation until use

* fix(ci): align startup memory with Node 24.15
2026-07-13 13:59:00 +08:00
Vincent Koc 1ac22971f7 fix(update): skip plugins switched through ClawHub 2026-07-12 16:23:35 +02:00
Peter Steinberger 1b313dc4d4 chore(tooling): enforce indexed access in core tests (#105375)
* test(tooling): enforce indexed access in core tests

* test(tui): constrain theme environment overrides

* test(doctor): enforce indexed access in migration fixtures
2026-07-12 14:29:52 +01:00
Peter Steinberger 401f278f11 feat: add Control UI plugin management (#103176)
* feat(ui): add plugin catalog management

* feat(gateway): add plugins.uninstall and richer plugin catalog metadata

Adds a plugins.uninstall gateway method (operator.admin, control-plane write)
backed by a lock-guarded uninstallManagedPlugin that mirrors the CLI flow:
config cleanup, install-record removal, managed file deletion, and registry
refresh. Bundled plugins stay disable-only. Catalog entries now carry a
manifest-derived category and a removable flag; ClawHub search results expose
download counts and verification tiers.

* feat(ui): redesign plugins page with inventory, store shelves, and cover art

Rebuilds /settings/plugins around three tabs: Installed (category-grouped
inventory with overview stats, state filters, uninstall for external plugins,
and inline MCP server management through the shared config seam), Discover
(featured/official shelves plus one-click MCP connectors and curated ClawHub
searches), and ClawHub (search with download counts and verification badges).
Every catalog entry renders bundled cover art or a deterministic gradient
monogram tile - no more empty boxes. Artwork generated with Codex CLI, shipped
as 512px WebP under ui/public/plugin-art.

* chore(ui): regenerate locale bundles for plugins manager strings

* docs: describe plugins manager tabs, uninstall, and MCP connectors

* fix(plugins): human catalog labels and un-pinned hosted fallback ids

listManagedPlugins now prefers manifest names over registry package-name
backfill, falls back to channel catalog labels and blurbs, and stops pinning
expectedPluginId when a hosted feed entry only exposes its package name
(which rejected every legitimate install of that package). Found via live
gateway testing against ClawHub.

* fix(ui): send minimal RFC 7396 merge patches for MCP server edits

config.patch merges rather than replaces, so key removal needs an explicit
null; sending the full config back made MCP server removal a no-op. Found
via live gateway testing.

* fix(ui): write explicit MCP transports for URL servers

The MCP runtime defaults URL-only servers to SSE, so streamable HTTP
endpoints saved by the add form or connector templates would fail at
connect time. Connector templates now declare their transport and the
add form infers streamable-http unless the URL follows the /sse
convention. Flagged by autoreview against the transport resolver.

* test(ui): wait for deferred plugin requests before resolving in e2e

* feat(ui): plugins detail view, action menus, and unified ClawHub search

Reworks the plugins page from PR #103176 feedback: merges the ClawHub tab into
Discover (typing searches ClawHub inline and appends a quiet From ClawHub
section, with Browse ClawHub demoted to a header text link), makes every row and
store card open a plugin detail overlay (hero art, primary enable/install
action, metadata table), and replaces enable/disable switches with a state chip
plus an overflow menu (Enable/Disable, Remove for external plugins, View
details) matching the ChatGPT-store install+menu pattern. MCP rows use the same
menu; refresh is now icon-only.

* chore(ui): regenerate locale bundles for plugins UI iteration

* feat(ui): vetted, grouped connector catalog for the plugins store

Expands Connect your world to 28 connectors organized into use-case shelves
(Work & productivity, Coding & infrastructure, Home & media, Everyday life).
Every entry passed a three-stage subagent review: official-docs verification
plus live endpoint probes for MCP servers, ClawHub result-quality and
malware/typosquat screening for curated searches, and an adversarial pass
that dynamically registered OAuth clients to prove one-click viability.

That review removed Figma (registration allowlisted, 403) and Atlassian
(OAuth issuer-mismatch bug upstream), downgraded GitHub to PAT-based setup
(no dynamic client registration upstream), fixed Linear (/sse retired) and
Home Assistant (/api/mcp, streamable HTTP) endpoints, retargeted poisoned or
dead searches (youtube, finance, hue dropped; calendar -> google calendar;
stocks replaces finance), and added Todoist, Airtable, Canva, Stripe,
Context7, DeepWiki, Hugging Face one-click MCP servers plus Jira, PDF,
transcription, Kubernetes, Reddit, maps, translation, and notes searches.
Keyless servers get a ready-to-use success message; new cover art included.

* chore(ui): regenerate locale bundles for connector groups

* fix(plugins): suppress hosted catalog rows once their package is installed

Hosted feed entries without a declared runtime id fall back to their package
name as catalog id, which never matches the installed runtime id, so the
Discover shelf kept offering an already-installed package. Installed package
names now also suppress official rows. Flagged by autoreview.

* fix(plugins): pin declared runtime ids and surface connector errors in place

The runtime-id pin now keys off explicitly declared catalog ids (plugin,
channel, or provider) instead of string-comparing against the package name,
so declared ids that equal their package name stay enforced while entry-id
fallbacks stay unpinned. Connector add failures on Discover now render on the
triggering card instead of the Installed tab's MCP section. Both flagged by
autoreview; regression tests included.

* feat(ui): full inventory artwork, pulse header, and two-column plugin list

Every bundled plugin now ships distinctive cover art (113 new Codex CLI
illustrations; 172 total, ~2.1MB WebP), so inventory rows and detail views
never fall back to monogram tiles. The four stat cards give way to a compact
inventory pulse: a segmented enabled/disabled/issues meter whose legend and
counts live inside the filter chips. Inventory, MCP, and search rows flow
into two columns when the panel is wide enough.

* chore(ui): regenerate locale bundles for pulse header

* fix(ui): omit stdio args from the MCP server row target

Stdio MCP args routinely carry tokens, and the inventory is visible to
read-only operators; mirror the config page and show only the command.
Flagged by autoreview; regression test included.

* fix(merge): point crestodian setup at relocated plugin commit/refresh modules

* fix(merge): add bootstrapToken to plugins page test gateway harness

* fix(plugins): name catalog install-action branches so Swift emits the union

* fix(ui): satisfy strict lint on plugins page form parsing and mocks

* chore(build): regen docs map, raise plugin-sdk declaration budget for new protocol surface

* fix(ui): type the plugins page patch mock with its real call signature
2026-07-10 11:56:44 +01:00