Commit graph

40 commits

Author SHA1 Message Date
lefarcen
df8a0faff6
feat(runtimes): register AMR (vela) as an ACP stdio agent (#2355)
* feat(runtimes): register AMR (vela) as an ACP stdio agent

AMR is the vela CLI's ACP runtime mode. `vela agent run --runtime opencode`
speaks ACP JSON-RPC over stdio (see vela's
`specs/current/runtime/manual-agent-run-openrouter.md`); per
`docs/new-agent-runtime-acp.md` we expose it through the same `streamFormat:
'acp-json-rpc'` transport that already powers Hermes, Devin, Kimi, etc.

The new `defs/amr.ts` is the entire wiring — `buildArgs` returns
`['agent', 'run', '--runtime', 'opencode']`, `fetchModels` reuses
`detectAcpModels`, and the fallback list seeds the OpenRouter ids vela's
e2e baseline uses. `executables.ts`/`app-config.ts`/`metadata.ts` get the
matching `VELA_BIN`/`VELA_LINK_URL`/`VELA_RUNTIME_KEY`/`VELA_OPENCODE_BIN`
allowlist + install/docs URLs, so users can configure the per-agent env in
Settings without leaking into other adapters.

Coverage: `tests/fixtures/fake-vela.mjs` is a minimal ACP stub that returns
the documented `initialize` / `session/new` / `session/set_model` /
`session/prompt` shapes; `tests/amr-acp-integration.test.ts` spawns it via
`child_process.spawn` and drives a full turn through `attachAcpSession` and
`detectAcpModels`, so the ACP transport contract for AMR is end-to-end
verified locally even before a real `vela` binary is installed.

Validated:
- pnpm guard
- pnpm typecheck (all workspace projects)
- pnpm --filter @open-design/daemon test (2881/2881)

Deferred: real OpenRouter-backed turn through a built `vela` binary —
the runtime def needs no changes for that path, only `VELA_RUNTIME_KEY`
and `VELA_LINK_URL` in env (or Settings).

* fix(runtimes/amr): pin a concrete default model and bare openai ids

End-to-end validation against a freshly-built `vela` (nexu-io/vela@main)
+ OpenRouter surfaced two contract details the first AMR runtime def
got wrong:

1. vela rejects `session/prompt` with `session/set_model must be called
   before session/prompt`. attachAcpSession in apps/daemon/src/acp.ts
   skips set_model whenever the picked model is the synthetic 'default'
   id, so AMR's fallback list must NOT include DEFAULT_MODEL_OPTION. The
   def now ships a concrete `gpt-5.4-mini` as both `fetchModels`'
   default option and `fallbackModels[0]`, which makes attachAcpSession
   always send a real `session/set_model` for AMR turns.

2. `vela --runtime opencode` auto-prepends `openai/` to whatever modelId
   it forwards to opencode's openai provider. With OpenRouter-style ids
   like `openai/gpt-5.4-mini`, opencode receives the double-prefixed
   `openai/openai/gpt-5.4-mini` and replies `ProviderModelNotFoundError`.
   The new fallback list ships the bare ids opencode's openai registry
   actually knows about (gpt-5.4, gpt-5.4-mini, gpt-5.4-fast, etc.).

Stub + tests:
- tests/fixtures/fake-vela.mjs now enforces the set_model gate the same
  way real vela does, so a regression that silently goes back to
  model: 'default' would surface as a fatal error in tests instead of a
  hidden production failure.
- tests/amr-acp-integration.test.ts pins both contracts: no 'default' /
  no 'openai/' prefix in fallbackModels, and a negative case that
  asserts session/prompt fails when no model is set.

Adds `apps/daemon/scripts/verify-amr-real-vela.mjs` — a small dev-time
runner that drives `attachAcpSession` against a real `vela` binary and
prints the daemon's chat events, so future protocol drift can be checked
against an actual OpenRouter call.

Verified locally: `vela agent run --runtime opencode` + OpenRouter
returns the prompted string ("AMR-E2E-PASS") through the full daemon
pipeline; daemon test suite stays 2883/2883.

* fix(runtimes/amr): substitute concrete model when chat run sends 'default'

A plugin-driven AMR run from the UI surfaced a real-world hole in the
prior commit:

  json-rpc id 3: session/set_model must be called before session/prompt

The Default-design-router plugin (and any caller that doesn't pin a
real model) sends `model: 'default'` straight through, which the AMR
runtime def cannot accept — vela rejects `session/prompt` without
`session/set_model` and attachAcpSession skips set_model whenever
model === 'default'. Just leaving DEFAULT_MODEL_OPTION out of the
adapter's `fallbackModels` is not enough: the chat-run handler in
server.ts still forwarded 'default' verbatim.

This adds `resolveModelForAgent(def, resolved, env?)` as the
single source of truth for the substitution:

  1. If the caller picked a real id, pass it through.
  2. Else, if `def.defaultModelEnvVar` is set and the daemon process
     env has a non-empty value for it, return that (operator escape
     hatch — see below).
  3. Else, if the def's `fallbackModels` does NOT contain a 'default'
     id, return `fallbackModels[0].id`.
  4. Else, return the original value (the historic shape — defs that
     list 'default' themselves are untouched).

AMR sets `defaultModelEnvVar: 'VELA_DEFAULT_MODEL'`, so when
opencode's openai-provider registry deprecates `gpt-5.4-mini`
upstream, an operator can swap the fallback id without a code change
by exporting `VELA_DEFAULT_MODEL=gpt-5.5` before launching tools-dev
/ od. Worth noting the env var must live in the daemon's `process.env`
(Settings-UI per-agent env values only reach the spawned child, not
the daemon's resolver) — the new field's docblock spells this out.

Coverage:
- `tests/runtimes/resolve-model.test.ts` — 8 unit tests covering all
  four resolver branches plus the env-override happy path / fallback /
  ignore-when-user-picked-a-real-id case.
- `pnpm --filter @open-design/daemon typecheck` clean.

* chore(runtimes/amr): move AMR to the top of the base agent list

So `AMR (vela)` shows up first in the agent picker / status views,
ahead of claude / codex. Pure ordering change; no behavior delta.

* feat(amr): Sign-in / Sign-out button on the AMR Settings card

The first half of the AMR work assumed the operator would set
VELA_RUNTIME_KEY / VELA_LINK_URL on the daemon process and never
surfaced login state to users. This adds the missing UX so a fresh
install can drive the full path from Settings:

  - GET  /api/integrations/vela/status   reads ~/.vela/config.json
    for the active profile and returns { loggedIn, profile, user }
    (without leaking the runtime/control keys themselves).
  - POST /api/integrations/vela/login    spawns `vela login` once
    (409 if one is already in flight). The vela CLI opens the user's
    browser to the device-authorization page itself — Open Design
    only needs to kick the subprocess off.
  - POST /api/integrations/vela/logout   removes ~/.vela/config.json
    so the next status read returns logged-out.

`AmrAgentCard` is a dedicated agent-card component for AMR because
the existing `<button>` row can't host an interactive sub-control
(nested interactive elements). It polls /status after a login click
until the daemon reports loggedIn=true (or 5 minutes elapse), and
exposes a Sign-out action on hover. Other adapters (claude, codex,
hermes, …) keep their existing `<button>` card.

i18n: 8 new keys (settings.amrLogin / Logout / LoggingIn / etc.)
added to en + zh-CN. Other locales spread `en` and inherit the
English copy until translations land.

Coverage:
- `tests/integrations/vela.test.ts` pins the config.json reader
  against a tmp HOME — including the negative case where a profile
  has user info but no runtimeKey (still logged-out), and the
  secret-leak guard ("rt-secret-*" must not appear in the projection
  payload).
- `tests/components/AmrAgentCard.test.tsx` covers all four UI
  states (logged-out, logging-in, logged-in, logging-out) plus the
  click-propagation invariant the divergent card was built to keep.

`pnpm --filter @open-design/daemon test` 2901 / 2901 passing.
`pnpm --filter @open-design/web test` 1719 / 1719 passing.
`pnpm typecheck` + `pnpm guard` clean.

Dev script side-effects: `apps/daemon/scripts/verify-amr-real-vela.mjs`
no longer requires both VELA_RUNTIME_KEY and VELA_LINK_URL — if
VELA_PROFILE is set, the vela CLI is allowed to resolve credentials
from `~/.vela/config.json`. Added the two AMR `.mjs` fixtures to
`scripts/guard.ts` allowlist with the executable-fixture / dev-runner
rationale.

* fix(connection-test): substitute model for AMR before attachAcpSession

The chat-run path in server.ts already routes the requested model through
`resolveModelForAgent` so AMR / vela (whose CLI demands an explicit
`session/set_model` before `session/prompt`) gets the def's first
concrete fallback id when the chat run ships `model: 'default'`.
`connectionTest.ts` was wiring `attachAcpSession({ ..., model: model ?? null })`
directly, which made the Test Connection button on the AMR Settings
card deadlock with the same `session/set_model must be called before
session/prompt` error the chat-run path already handles — surfaced as a
permanent "Testing connection…" spinner in the UI.

Reuse the same helper here so Test Connection mirrors chat-run behavior.

* test(amr): three-layer end-to-end coverage for the AMR login + turn flow

The PR up to this point shipped runtime + UI code with unit-level Vitest
coverage. This commit adds the cross-layer regression net the live demo
relied on:

1. apps/daemon/tests/integrations/vela.routes.test.ts (HTTP, Vitest)
   Spins up the real daemon Express app via `startServer({port:0,...})`,
   persists `agentCliEnv.amr.VELA_BIN = <fake>` into app-config.json,
   and exercises every /api/integrations/vela/* endpoint against the
   extended fake-vela stub:
     - status reads ~/.vela/config.json under various states
     - login spawns the fake, waits for config.json to appear, returns
       pid + startedAt + profile
     - 409 already-running guard with the stub's delay knob
     - logout removes the file (idempotent)
     - secrets (runtimeKey / controlKey) never leak in the projection
     - login → status round-trip flips loggedIn=false → true

2. e2e/tests/amr/turn.test.ts (tools-dev orchestrated, Vitest)
   Boots a namespaced daemon + web pair through `createSmokeSuite`,
   inlines a self-contained fake `vela` binary that handles BOTH
   `vela login` (writes ~/.vela/config.json) and
   `vela agent run --runtime opencode` (ACP stdio with the
   `session/set_model must precede session/prompt` gate the real binary
   enforces), then drives a complete /api/runs lifecycle for
   `agentId: 'amr', model: 'default'` and asserts the assistant message
   captures the fake's streamed text. This is the test that would have
   surfaced today's plugin-default-model regression (the `set_model
   before prompt` error) at PR time instead of demo time.

3. e2e/ui/amr-login-pill.test.ts (Playwright)
   Mocks /api/agents + /api/integrations/vela/{status,login,logout}
   to drive the Settings AMR card through the full Sign in → Signed in
   → Sign out cycle. Pins the AmrLoginPill polling contract and the
   aria-label semantics (the pill's accessible name is "Sign out" once
   logged in, regardless of which label the hover-state text shows).

fake-vela.mjs extensions:
   - Handles `vela login` argv by writing
     ~/.vela/config.json for the active VELA_PROFILE and exiting 0 —
     mirrors real vela's on-disk side-effect without the device-auth
     loop.
   - FAKE_VELA_LOGIN_DELAY_MS knob so route tests can observe the
     in-flight state of the spawn lifecycle.
   - FAKE_VELA_LOGIN_USER_EMAIL / _USER_PLAN to assert the surfaced
     user fields end-to-end.

Validated:
   - `pnpm guard` + `pnpm typecheck` (all workspace projects)
   - `pnpm --filter @open-design/daemon test`: 2998 / 2998 passing,
     including the new 8-test integration suite.
   - `cd e2e && pnpm test tests/amr`: 1 / 1 passing.
   - `cd e2e && pnpm exec playwright test ui/amr-login-pill.test.ts`:
     1 / 1 passing (6.7s).

* feat(amr): package native cli and refine login ui

* feat(amr): wire vela cli beta packaging

* docs(amr): document vela ci packaging review

* docs(amr): refine vela ci integration review

* fix(ci): refresh nix pnpm dependency hashes

* fix(pack): clean up Vela CLI packaging

* fix(pack): bundle Vela CLI support files

* fix(amr): recover login attempts from stale auth state

* test: expand AMR and automations coverage

* fix(amr): address review follow-ups

* test(web): align tasks fixtures with contracts

* fix(daemon): type wildcard route params

* fix(ci): refresh PR merge validation

* fix(amr): clear env credentials on logout

* feat(settings): inline local CLI model configuration

* fix(amr): recognize daemon env credentials

* [codex] Fix Vela companion packaging (#2979)

* Fix Vela companion packaging

* Update Nix pnpm dependency hashes

* [codex] Surface AMR account failures (#2980)

* fix: surface AMR account failures

* fix: cover AMR recovery error guidance

* chore: bump beta base version to 0.8.1 (#2990)

* Fix AMR profile and packaged runtime review issues

* Detect packaged AMR OpenCode companion tree

* feat(web): polish AMR frontend flows

* Polish AMR onboarding card

* fix: read AMR login state from dot-amr config (#3048)

* test: tighten AMR credential and packaging coverage

* test: restore AMR executable test env helper

* [codex] Fix packaged mac Dock identity and AMR label (#3076)

* Fix packaged mac sidecar Dock identity

* Rename AMR assistant label

* Fix AMR live models and dot-amr login state (#3073)

* fix: read AMR login state from dot-amr config

* fix: load live AMR models before runs

* fix: point AMR onboarding link to production wallet

* fix: address AMR model review feedback

* fix: persist live AMR model fallback

* [codex] Fix AMR link catalog model ids (#3088)

* Fix packaged mac sidecar Dock identity

* Rename AMR assistant label

* Fix AMR link catalog model ids

* Fix AMR model normalization typecheck

* Use live AMR model for default runs

* fix: polish AMR runtime settings UI

* Accelerate AMR startup defaults (#3092)

* Surface AMR insufficient balance wallet URL (#3099)

* fix(web): polish onboarding controls (#3112)

* fix(web): show CLI scan loading state

* Avoid duplicate AMR wallet recharge links (#3117)

* Avoid duplicate AMR wallet recharge links

* Use Vela CLI 0.0.3 test package

* chore(nix): refresh pnpm deps hash

* Fix AMR wallet guidance display

---------

Co-authored-by: open-design-bot[bot] <282769551+open-design-bot[bot]@users.noreply.github.com>

* chore(pack): pin Vela CLI 0.0.3-test.1 (#3127)

* chore(nix): refresh pnpm deps hash

* chore(pack): pin Vela CLI 0.0.3

* chore(nix): refresh pnpm deps hash

* fix(web): suppress AMR exit 130 fallback (#3136)

* feat(web): nudge users to hosted AMR on model/auth/quota failures (#3083)

* feat(web): nudge users to hosted AMR on model/auth/quota failures

When a non-AMR agent run fails with an auth / quota / upstream model
error, surface an inline nudge under the error pill linking to Open
Design's hosted AMR gateway (https://open-design.ai/amr). The nudge
fires `surface_view` (element=run_failed_toast) on impression and
`ui_click` (element=go_amr) on the link.

Also teach the daemon to classify CLI-agent auth/quota/upstream failures
(Claude Code, codex, ...) into specific API error codes
(AGENT_AUTH_REQUIRED / RATE_LIMITED / UPSTREAM_UNAVAILABLE) instead of
the generic AGENT_EXECUTION_FAILED, so both the error message and the
nudge key off accurate codes. AMR's own runs are excluded from the
nudge — they keep the dedicated sign-in / recharge affordances.

* feat(web): rework failed-run AMR guidance into per-case error UI

Replace the single inline nudge with a per-case failed-run experience
driven by the run's error code + agent:

- The error card is now neutral gray (was red) and always carries a
  retry button; it is driven by the persisted per-message error event so
  it survives a reload.
- Non-AMR agent hitting a model/auth/quota wall: a theme-color promotion
  card under the error card offers "switch to AMR & retry" — switches the
  run to AMR, opens Settings on the AMR card, and auto-retries once the
  account signs in (ProjectView polls vela login status, independent of
  the Settings pill lifecycle, with success / 5-min-timeout / unmount
  exits).
- AMR agent unauthorized: clearer copy + an "authorize & retry" button.
- AMR agent out of balance: clearer copy + a "top up" button to the AMR
  wallet, with manual retry.
- Settings AMR card: when opened from the nudge, it scrolls into view and
  pulses, and an authorize-button coachmark (a fake hand cursor that
  rises in and dismisses on hover) points at the sign-in control when not
  yet authorized.

analytics: surface_view (run_failed_toast) on the promotion card and
ui_click (go_amr) on its action are retained. i18n adds chat.amrCard.*
and chat.amrError.* (en / zh-CN / zh-TW translated; other locales fall
back to en) and drops the old chat.amrErrorGuidance keys.

* fix(daemon): require status context for numeric service-failure codes

Per review on #3083: the model-service classifier matched bare HTTP
status numbers (`500`, `502`, `429`, `401`), so ordinary CLI output like
`line 500`, `read 502 bytes`, or `exit code 401` could be misclassified
as a provider outage / auth wall and wrongly surface the AMR nudge. Now
a status number only counts when it carries explicit context (`HTTP 500`,
`status 503`, `code: 401`, `502 Bad Gateway`); textual provider phrases
(overloaded, bad gateway, service unavailable, rate limit, …) are
unchanged. Adds fixtures proving unrelated numeric output stays null.

* fix(web): keep error pill for failed runs ChatPane's card doesn't cover

Per review on #3083: the per-message gray error pill was suppressed for
every persisted error status event, but ChatPane only renders the
replacement top-level error card for `retryableAssistantMessage` (the
last failed assistant). So a failed turn that is no longer last (after a
follow-up) or an older failed run in history showed neither the pill nor
the card — its error detail vanished, undercutting reload/history
survival. ChatPane now passes `errorCardOwnerId` (the assistant id whose
error the card represents); AssistantMessage suppresses only that one
pill and keeps rendering StatusPill for all other error events.

* fix(daemon): don't treat a process exit code as an HTTP status

Follow-up to review on #3083: the status-context helper accepted a bare
`code` prefix, so `exit code 401` / `process exited with code 429` still
matched and got classified as AGENT_AUTH_REQUIRED / RATE_LIMITED (the
very `exit code 401` case the comment calls out as noise). `code` now
only counts when qualified (`status code` / `error code` / `response
code`) or punctuation-bound (`code: 401`); bare `exit code N` no longer
matches. Adds fixtures for exit-code lines returning null.

* chore(web): translate AMR card / error keys for 16 remaining locales

PR #3083 added 10 new `chat.amrCard.*` / `chat.amrError.*` keys but only
provided en/zh-CN/zh-TW translations; the other 16 locales fell back to
English. Translate the card title/body, three chips, primary CTA, and
the AMR self-error (auth / balance) messages and buttons for ar, de,
es-ES, fa, fr, hu, id, it, ja, ko, pl, pt-BR, ru, th, tr, uk.

* fix(amr): address review feedback on #2355

Targeted fixes for the unresolved review threads on #2355. Each fix
includes / updates a focused test.

- runtimes/executables.ts: `packagedVelaOpenCodeCompanionTree` now
  verifies the inner `opencode` executable exists + is runnable, not
  just the directory. This closes the false-positive availability path
  that let `detectAgents()` surface AMR as available even when the
  packaged companion was empty / partially copied (mrcfps, 4 threads).

- runtimes/executables.ts: `resolveAmrOpenCodeExecutable` now prefers
  the bundled `<OD_RESOURCE_ROOT>/bin/libexec/opencode/opencode` over a
  stale `opencode` on the user's PATH, so packaged AMR builds can't be
  hijacked by a global installation.

- web/EntryShell.tsx: when the Local CLI scan returns an available
  agent and the previously-selected agent is AMR, switch the selection
  to the first available local agent so the runtime and persisted
  agent agree before Continue.

- server.ts (model-probe branch): for AMR, check `readVelaLoginStatus`
  BEFORE rejecting on an empty live-model catalog — a signed-out user
  was getting `AMR_MODEL_UNAVAILABLE` ("choose a model") instead of
  the correct `AMR_AUTH_REQUIRED` (sign-in affordance).

- server.ts (default model fallback): if the user asked for the AMR
  agent default and the cached id is no longer in the FRESH catalog,
  fall back to `liveModels[0]` from the probe instead of rejecting the
  run as `AMR_MODEL_UNAVAILABLE`.

- integrations/vela.ts: route `vela login` through
  `createCommandInvocation` so an npm/Node-style `vela.cmd` / `.bat`
  shim on Windows gets the correct `cmd.exe /d /s /c …` wrapping with
  verbatim args (matches `execAgentFile` / chat-run spawning).

- tools/pack/src/linux.ts: in containerized Linux builds, bind-mount
  the host directory of `OPEN_DESIGN_VELA_CLI_BIN` and rewrite the env
  to the container-side path. The host path was being passed in as-is
  even though the default container only mounts /project, /tools-pack
  and cache/home — `copyOptionalVelaCliBinary` saw a missing path.

Deferred (out of scope for this PR):
- `od amr status/login/logout/cancel` CLI subcommands (AGENTS.md
  UI/CLI dual-track rule, server.ts:5763) — sizable surface; tracked
  for a separate focused PR.
- Strict `--require-vela-cli` for Windows + mac-x64 beta builds:
  prematurely blocked — `@powerformer/vela-cli` only publishes the
  `darwin-arm64` platform binary today; adding the flag elsewhere
  would fail the builds. Revisit once win/x64/linux binaries ship.

* fix(amr): hoist sendAmrAccountFailure above the AMR catalog preflight (TDZ)

The new signed-out AMR branch in the catalog preflight at server.ts:10875
calls `sendAmrAccountFailure(...)` to emit AMR_AUTH_REQUIRED, but the
const declaration sat ~100 lines below at the outer function scope. Because
`const` is TDZ-aware, that branch would have thrown `ReferenceError:
Cannot access 'sendAmrAccountFailure' before initialization` for the
exact users it tries to help — defeating the original intent.

Hoist the helper to just above the AMR preflight block so it's available
to every AMR code path in this function. Behavior elsewhere is unchanged.

Also rerun the daemon test suite: `launch.test.ts > resolveAgentLaunch
uses packaged built-in Vela for AMR` was creating the
`<resourceRoot>/bin/libexec/opencode/` companion *directory* only, but
this PR's earlier tightening of `packagedVelaOpenCodeCompanionTree`
also requires the inner `opencode` executable. Add it to that fixture
to match the new contract; the test was a sibling of the executables /
env-and-detection fixtures already updated in 13fc4f4.

Addresses #2355 review (mrcfps, 2026-05-28).

* feat(web): add hover cancel for AMR login (#3158)

* feat(web): add hover cancel for AMR login

* fix(web): don't bounce AmrLoginPill back to 'Signing in…' after local cancel

Both codex-connector (P2) and looper (CHANGES_REQUESTED) on this PR
flagged the same race in the new local-cancel path: `handleCancelLogin`
dispatches `notifyAmrLoginStatusChanged('login-canceled')` immediately
after `/login/cancel` returns, but the `AMR_LOGIN_STATUS_EVENT` listener
unconditionally re-enters `refresh()` and then restarts polling
whenever `/api/integrations/vela/status` still reports
`loginInFlight: true`.

That is a real race because the daemon's `cancelVelaLogin()` only sends
SIGTERM (escalating to SIGKILL after `LOGIN_CANCEL_KILL_GRACE_MS` =
2000 ms) and keeps the child in `activeLoginProcs` until it actually
exits — so the first `/status` read after a successful cancel can
legally still come back as in-flight. Under that window the pill flips
back to 'Signing in…' and can later surface the timeout/error path even
though the user already canceled, defeating the behavior promised in
the PR description.

Fix the listener instead of every dispatch site: in the
`login-canceled` branch, after the local reset (stopPolling +
setPending(null) + clear refs), optimistically mark every subscribed
pill instance as not-in-flight (`setStatus((c) => c ? { ...c,
loginInFlight: false } : c)`) and `return` — skip the
refresh-and-reconcile branch below entirely. The next explicit refresh
(component mount, user interaction, or a `status-changed` event) will
pick up the daemon's confirmed state once the child has actually
exited.

Add a focused regression test that holds `/api/integrations/vela/status`
at `loginInFlight: true` even after a successful `/login/cancel`,
asserting that the pill stays at the Canceled → Authorize sequence and
never bounces back to 'Signing in…'. This test fails on the pre-fix
listener and passes on the new behavior; existing
'cancels an in-flight AMR sign-in…' and 'reconciles late AMR browser
completion to Signed in after local cancel' tests continue to pass.

Addresses review feedback on #3158 (chatgpt-codex-connector, nettee).

---------

Co-authored-by: lefarcen <935902669@qq.com>

---------

Co-authored-by: a1chzt <chizblank@gmail.com>
Co-authored-by: Amy <1184569493@qq.com>
Co-authored-by: Mason <jinmeihong0201@gmail.com>
Co-authored-by: Caprika <56862773+alchemistklk@users.noreply.github.com>
Co-authored-by: open-design-bot[bot] <282769551+open-design-bot[bot]@users.noreply.github.com>
2026-05-28 05:09:55 +00:00
PerishCode
4f15c33595 Merge remote-tracking branch 'origin/preview/0.8.0' into preview/v0.8.0 2026-05-14 21:10:03 +08:00
PerishCode
cba8bf151d chore: align namespace lifecycle packaging 2026-05-14 16:35:46 +08:00
pftom
3b167b6921 feat(plugins): add registry protocol and enhance plugin management features
- Introduced the `@open-design/registry-protocol` package, enabling improved interactions with plugin registries.
- Updated the `typecheck` script in the daemon's `package.json` to include the new registry protocol.
- Enhanced the CLI with new flags and commands for better plugin management, including `yank` and additional marketplace functionalities.
- Implemented a plugin lockfile system to manage installed plugins and their versions, improving reliability during upgrades.
- Added new marketplace doctor functionality to validate plugin entries and ensure compliance with registry standards.

This update significantly enhances the plugin ecosystem by providing robust registry interactions and improved management capabilities.
2026-05-14 08:55:36 +08:00
pftom
56c264c9bd feat(plugins): add login and whoami commands for GitHub CLI authentication
- Introduced `login` and `whoami` commands to the plugin CLI, enabling users to authenticate with the Open Design registry via GitHub CLI.
- The `login` command wraps GitHub CLI authentication, allowing users to specify a host, defaulting to GitHub.
- The `whoami` command retrieves and displays the authenticated GitHub account information, with an option for JSON output.
- Updated the CLI help documentation to include usage instructions for the new commands.
- Enhanced error handling for GitHub CLI dependencies and authentication status.

This update improves the user experience by simplifying the authentication process for plugin publishing.
2026-05-14 07:25:05 +08:00
pftom
7c48fbd902 feat(plugins): enhance PluginsView with new marketplace management features
- Updated the PluginsView component to include new tabs for 'Installed', 'Available', and 'Sources', improving the organization of plugin management.
- Introduced functions for adding, refreshing, removing, and setting trust for plugin marketplaces, enhancing the marketplace interaction capabilities.
- Enhanced the UI to reflect the new structure, including updated CSS styles for better visual consistency and usability.
- Added tests to ensure the functionality of the new marketplace features and verify the correct rendering of available plugins.

This update significantly improves the user experience in managing plugins and marketplaces, providing a more intuitive interface for users.
2026-05-13 23:42:41 +08:00
pftom
c9cc3b88c0 feat(web): standardize plugin terminology and enhance UI components
- Updated terminology from "Community" to "Official" across various components to reflect first-party plugin status.
- Enhanced the ChatComposer, HomeHero, and PluginsHomeSection components to improve user experience and clarity in plugin management.
- Improved CSS styles for better visual consistency and layout across plugin-related interfaces.
- Added tests to ensure proper functionality and visibility of official plugins in the UI.

This update reinforces the distinction between official and user-installed plugins, enhancing the overall user experience in plugin interactions.
2026-05-13 12:19:29 +08:00
pftom
1bdf765cf2 feat(daemon): enrich API responses with surface specs and add new flags
- Implemented `--schema` flag for `od ui show` to return only the JSON Schema of the surface.
- Enhanced the response of `GET /api/runs/:runId/genui/:surfaceId` to include the surface spec from the AppliedPluginSnapshot.
- Introduced new flags for daemon and library commands to improve command handling and parsing.
- Added tests for the new functionality, ensuring proper behavior of the enriched responses and flag handling.

This change supports headless interactions by allowing code agents to inspect surface contracts before responding.
2026-05-11 20:27:05 +08:00
Cursor Agent
6001f274c9
docs(plugins): record II-series landing in living plan + CHANGELOG
Plan II2 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the II-series shipped this turn:

  II1. Plugin event ring buffer + SSE tail

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 17:56:49 +00:00
Cursor Agent
11f8a01b90
docs(daemon): record GG-series landing in living plan + CHANGELOG
Plan GG2 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the GG-series shipped this turn:

  GG1. `od daemon db status` SQLite inventory

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 17:40:14 +00:00
Cursor Agent
b9fb14e68b
docs(plugins): record FF-series landing in living plan + CHANGELOG
Plan FF2 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the FF-series shipped this turn:

  FF1. `od plugin verify <id>` CI meta-command

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 17:33:08 +00:00
Cursor Agent
675bfa2a85
docs(plugins): record EE-series landing in living plan + CHANGELOG
Plan EE2 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the EE-series shipped this turn:

  EE1. `od plugin simulate <id>` pipeline dry-run

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 17:26:47 +00:00
Cursor Agent
2da68ba0a6
docs(plugins): record DD-series landing in living plan + CHANGELOG
Plan DD3 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the DD-series shipped this turn:

  DD1. `od plugin stats` inventory health report
  DD2. `od plugin canon --check <expected-file>` byte-equality fixtures

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 17:18:21 +00:00
Cursor Agent
adcffab253
docs(plugins): record BB-series landing in living plan + CHANGELOG
Plan BB3 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the BB-series shipped this turn:

  BB1. `od plugin snapshots show <id>`
  BB2. `od plugin snapshots diff <a> <b>` + diffSnapshots() helper

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 17:04:23 +00:00
Cursor Agent
81412fcf6a
docs(plugins): record AA-series landing in living plan + CHANGELOG
Plan AA3 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the AA-series shipped this turn:

  AA1. `od plugin diff <a> <b>` author tooling
  AA2. `od atoms info <id>` + atom catalog drift fix

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 16:54:00 +00:00
Cursor Agent
9f4e8df498
docs(plugins): record Z-series landing in living plan + CHANGELOG
Plan Z3 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the Z-series shipped this turn:

  Z1. patch-edit atomic file writes (Phase 7 safety patch)
  Z2. `od plugin upgrade <id>` re-install from recorded source

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 16:44:02 +00:00
Cursor Agent
000ea5a734
docs(plugins): record Y-series landing in living plan + CHANGELOG
Plan Y2 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the Y-series shipped this turn:

  Y1. `od plugin search <query>` + filters on `od plugin list`

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 16:34:26 +00:00
Cursor Agent
2d8f556b3b
docs(plugins): record X-series landing in living plan + CHANGELOG
Plan X2 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the X-series shipped this turn:

  X1. `od plugin pack <folder>` distribution archive

The Phase 4 author dev-loop is now closed end-to-end:

  od plugin scaffold --id <id>          # bootstrap a folder
  od plugin validate <folder>           # lint before install
  od plugin pack <folder>               # build a .tgz archive
  od plugin install --source <path>     # install (local OR https)
  od plugin export <projectId>          # build a publish-ready folder
  od plugin publish ...                 # generate catalog PR link

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 16:28:30 +00:00
Cursor Agent
fbddf11f8b
docs(plugins): record W-series landing in living plan + CHANGELOG
Plan W2 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the W-series shipped this turn:

  W1. `od plugin validate <folder>` author-side lint

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 16:22:50 +00:00
Cursor Agent
e026a54fd9
docs(daemon): record V-series landing in living plan + CHANGELOG
Plan V2 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the V-series shipped this turn:

  V1. OD_BUNDLED_ATOM_PROMPTS default flipped to ON

Living plan now reads:
  Phase 4 \u2192 'full incl. OD_BUNDLED_ATOM_PROMPTS default ON'

Remaining backlog: postgres adapter wiring inside the DaemonDb
resolver — the only stubbed item left.

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 16:16:29 +00:00
Cursor Agent
0ddd29aeb6
docs(daemon): record U-series landing in living plan + CHANGELOG
Plan U2 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the U-series shipped this turn:

  U1. S3ProjectStorage live impl via AWS SigV4

Living plan now reads:
  Phase 5 \u2192 'full incl. live S3 impl; postgres adapter still stubbed'

Remaining backlog:
  - Promote OD_BUNDLED_ATOM_PROMPTS=1 to default (audit-blocked)
  - Postgres adapter wiring inside DaemonDb resolver

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 16:11:10 +00:00
Cursor Agent
798ffaec48
docs(plugins): record T-series landing in living plan + CHANGELOG
Plan T3 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the T-series shipped this turn:

  T1. runAndPersistHandoff() + auto-handoff from diff-review bridge
  T2. figma-migration pipeline e2e smoke test

Phase 8 promotion ladder now closes end-to-end without an agent turn:
GenUI Accept \u2192 review/decision.json + handoff/manifest.json with
handoffKind set.

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 16:03:37 +00:00
Cursor Agent
4c3423a500
docs(plugins): record S-series landing in living plan + CHANGELOG
Plan S3 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the S-series shipped this turn:

  S1. runHandoffAtom() pipeline-driven promotion-ladder bridge
  S2. Full code-migration pipeline e2e smoke test

Living plan now records:
  Phase 7 \u2705 + 'full pipeline e2e covered by smoke test'
  Phase 8 \u2705 + 'handoff promotion ladder bridge landed'

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 15:56:54 +00:00
Cursor Agent
c1f6d1f02d
docs(plugins): record R-series landing in living plan + CHANGELOG
Plan R2 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the R-series shipped this turn:

  R1. diff-review GenUI \u2192 review/decision.json bridge

Living plan now reads:
  Phase 8 → \u2705 COMPLETE end-to-end. Patch substrate +
    diff-review atom + auto-surface + native UI mount + GenUI \u2192
    runDiffReview bridge all landed.
  Phase 6 → \u2705 COMPLETE.
  Phase 7 → \u2705 COMPLETE.

Remaining backlog:
  - Promote OD_BUNDLED_ATOM_PROMPTS=1 to default (audit-blocked)
  - AWS SDK wiring inside S3ProjectStorage
  - Postgres adapter wiring inside DaemonDb resolver

Changelog names every shipped surface so a reviewer can audit the
delta without reading the plan.

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 15:49:50 +00:00
Cursor Agent
72ec5fb176
docs(plugins): record Q-series landing in living plan + CHANGELOG
Plan Q3 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the Q-series shipped this turn:

  Q1. Native diff-review UI on GenUISurfaceRenderer  (Phase 8 entry slice)
  Q2. figma-extract asset rasterisation second pass  (Phase 6 entry slice)

Living plan now reads:
  Phase 6 → COMPLETE: figma-extract REST + token-map crosswalk +
    asset rasterisation second pass via GET /v1/images.
  Phase 8 → patch + review + auto-surface + native review UI all
    landed. The remaining slice is wiring the GenUI response back
    through runDiffReview() to auto-update review/decision.json
    (today the daemon stores the response on the run; the
    diff-review runner reads it on next invocation).

Changelog names every shipped surface so a reviewer can audit the
delta without reading the plan.

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 15:41:46 +00:00
Cursor Agent
e135739f99
docs(plugins): record P-series landing in living plan + CHANGELOG
Plan P4 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the P-series shipped this turn:

  P1. token-map atom impl                       (Phase 6/7 entry slice)
  P2. figma-extract atom impl                   (Phase 6 entry slice)
  P3. Auto-derived choice surface for diff-review (Phase 8 entry slice)

Living plan now reads:
  Phase 6 → COMPLETE: figma-extract REST shell-out + token-map
    crosswalk both implemented. Bundled scenario plugin
    od-figma-migration ships the canonical pipeline. Asset
    rasterisation second pass (offlineAssets=false) stays
    scheduled.
  Phase 7 → COMPLETE (continued from O-series): all six atom impls.
  Phase 8 → patch + review + auto-surface substrate landed; native
    UI mount in the web composer stays scheduled.

Changelog names every shipped surface so a reviewer can audit the
delta without reading the plan.

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 15:32:23 +00:00
Cursor Agent
01e94a92be
docs(plugins): record O-series landing in living plan + CHANGELOG
Plan O6 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the O-series shipped this turn:

  O1. Bundled-scenario pipeline fallback resolver (spec §23.3.3)
  O2. design-extract atom impl                    (Phase 6/7 entry slice)
  O3. rewrite-plan atom impl                      (Phase 7 entry slice)
  O4. patch-edit atom impl                        (Phase 7 entry slice)
  O5. diff-review atom impl                       (Phase 7-8 entry slice)

Living plan now reads:
  Phase 7 → ALL SIX atoms IMPLEMENTED (build-test + code-import +
    design-extract + rewrite-plan + patch-edit + diff-review).
    Bundled scenario plugin od-code-migration ships the canonical
    pipeline. Live HTTP wiring for the per-stage runner stays
    scheduled.
  Phase 8 → patch + review substrate landed; native review-and-apply
    UI mounting diff-review through a GenUI choice surface stays
    scheduled.
  Phase 6 → SKILL.md substrate + scenario plugin registered;
    design-extract impl is reused under the figma-migration
    flow as well.

Changelog names every shipped surface so a reviewer can audit the
delta without reading the plan.

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 15:19:04 +00:00
Cursor Agent
1d142b4214
docs(plugins): record N-series landing in living plan + CHANGELOG
Plan §3.N5 — sync docs/plans/plugins-implementation.md and
CHANGELOG.md with the N-series shipped this turn:

  N1. build-test atom shell-out runner (Phase 7 entry slice)
  N2. code-import atom repo walker      (Phase 7 entry slice)
  N3. handoff helper + ArtifactManifest provenance fields
                                        (Phase 7-8 entry slice)
  N4. Bundled scenario plugins          (spec §23.3.3)

Living plan now reads:
  Phase 7 → build-test + code-import IMPLEMENTED; design-extract +
    rewrite-plan + patch-edit + diff-review remain SKILL.md
    substrate.
  Phase 8 → handoff helper + provenance fields IMPLEMENTED; native
    review-and-apply UI remains scheduled.
  Phase 6 → SKILL.md substrate + scenario plugin registered;
    Figma REST + token-map heuristic remain scheduled.

Changelog names every shipped surface so a reviewer can audit the
delta without reading the plan.

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 14:57:23 +00:00
Cursor Agent
4aec507cd3
docs(plugins): record M-series — retention TTL + atom prompt rewiring + Phase 6/7/8 substrate
CHANGELOG.md ## Unreleased gets a new bullet block summarising:
  - OD_SNAPSHOT_RETENTION_DAYS referenced-row TTL (PB2 closed).
  - OD_BUNDLED_ATOM_PROMPTS=1 activates composeDaemonSystemPrompt's
    atom-block branch (default off; byte-equal to today's prompt).
  - Nine new bundled atom SKILL.md fragments under
    plugins/_official/atoms/ for Phases 6, 7, and 8.

docs/plans/plugins-implementation.md §6 Phase 6 / 7 / 8 deliverables
record their substrate-shipped state; the actual implementations
remain scheduled. §9 Status snapshot updated; next-planned-PR cell
moves the AWS SDK / postgres adapter wiring + Phase 6 / 7 / 8
shell-out implementations + the OD_BUNDLED_ATOM_PROMPTS default
flip to the head of the queue.

Final gates: pnpm guard ✓, daemon 1521 tests ✓, web 586 tests ✓,
contracts 12 tests ✓, agui-adapter 9 tests ✓, plugin-runtime 21.

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 14:25:22 +00:00
Cursor Agent
35b4030834
docs(plugins): record L-series — Helm overrides + activeStageBlocks + asset route + storage substrate
CHANGELOG.md ## Unreleased gets a new bullet block summarising:
  - Per-cloud Helm value overrides (AWS / GCP / Azure / Aliyun /
    Tencent / Huawei / self-hosted).
  - composeSystemPrompt accepts activeStageBlocks so a future PR can
    swap inline DISCOVERY_AND_PHILOSOPHY for SKILL.md fragments.
  - Plugin-bundled component surface (sandboxed iframe) +
    GET /api/plugins/:id/asset/* with §9.2 CSP.
  - ProjectStorage + DaemonDb adapter substrate (Local impl wired,
    S3 + postgres stubs interface-locked).

docs/plans/plugins-implementation.md §3 / §6 / §9 flipped:
  - Phase 5 deliverables: chart templates + per-cloud overrides +
    bound-API-token guard + ghcr CI + ProjectStorage + DaemonDb all
    record their landed shipped state.
  - §6 Phase 4 absorbs the activeStageBlocks composer field +
    surface.component sandbox loader as shipped slices.
  - §9 Status snapshot updated; head of the queue is now the live
    composeSystemPrompt rewiring + AWS SDK / postgres adapter
    wiring + OD_SNAPSHOT_RETENTION_DAYS referenced-row TTL +
    Phase 6/7/8 native scenarios.

Final gates: pnpm guard ✓, daemon 1516 tests ✓, web 586 tests ✓,
contracts 12 tests ✓, agui-adapter 9 tests ✓, plugin-runtime 21.

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 14:01:29 +00:00
Cursor Agent
d0dbc7314f
docs(plugins): record K-series — bound-API-token + Helm + surface.component + ghcr CI
CHANGELOG.md ## Unreleased gets a new bullet block summarising:
  - Phase 5 bound-API-token guard (startServer refusal + bearer
    middleware on /api/*).
  - Helm chart templates (Deployment / Service / Secret / ConfigMap /
    PVCs / Ingress / NOTES).
  - od.genui.surfaces[].component manifest field + capability gate.
  - GitHub Actions multi-arch image push to ghcr.io.

docs/plans/plugins-implementation.md §6 / §9 flipped:
  - Phase 5 bound-API-token guard, CI push, Helm templates → shipped.
  - Phase 4 surface.component manifest upgrade → shipped (substrate;
    web sandbox loader stays scheduled).
  - §9 Status snapshot updated; head of the queue is now the
    composeSystemPrompt rewiring + the web custom-component sandbox
    loader + ProjectStorage S3 adapter + DaemonDb Postgres adapter +
    per-cloud values-<cloud>.yaml override files + Phase 6 / 7 / 8.

Final gates: pnpm guard ✓, daemon 1496 tests ✓, web 586 tests ✓,
contracts 12 tests ✓, agui-adapter 9 tests ✓, plugin-runtime 21 tests ✓.

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 13:42:54 +00:00
Cursor Agent
735b7bdffb
docs(plugins): record J-series — AG-UI adapter + atom-block + Phase 5 entry slice
CHANGELOG.md ## Unreleased gets a new bullet block summarising:
  - @open-design/agui-adapter package + GET /api/runs/:runId/agui
    (spec §10.3.5).
  - renderActiveStageBlock + loadAtomBodies (spec §23.3.2 substrate).
  - Phase 5 Dockerfile bundles plugins/_official/, plus
    tools/pack/docker-compose.yml and tools/pack/helm/open-design/
    parameter surface.

docs/plans/plugins-implementation.md §3 / §6 / §9 flipped:
  - Architecture-state table records agui-adapter, atom-bodies,
    atom-block, docker-compose, Helm values.
  - HTTP route table marks /api/runs/:runId/agui shipped.
  - §6 Phase 4 'AG-UI adapter package' deliverable flips. The
    'plugins/_official/atoms/<atom>/SKILL.md extraction' deliverable
    is recorded as substrate-shipped; the composeSystemPrompt
    rewiring stays as the next planned PR.
  - §6 Phase 5 deliverable list flips Dockerfile + docker-compose +
    Helm + snapshot retention worker; the bound-API-token guard +
    pluggable storage / Postgres adapters stay open.
  - §9 Status snapshot updated; head of the queue is now the
    composeSystemPrompt rewiring + od.genui.surfaces[].component
    upgrade + CI pushing :edge / :<version> + bound-API-token guard
    + Postgres / S3 adapters.

Final gates: pnpm guard ✓, daemon 1486 tests ✓, web 586 tests ✓,
contracts 12 tests ✓, agui-adapter 9 tests ✓.

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 13:24:53 +00:00
Cursor Agent
d06c1b4905
docs(plugins): record I-series — pipeline-into-startChatRun + doctor/config + bundled atoms
CHANGELOG.md ## Unreleased gets a new bullet block summarising:
  - Pipeline runner wired into POST /api/runs (e2e-3 full §8 contract).
  - od doctor (repo-wide diagnostics) + od config get/set/list/unset.
  - Phase 4 §23 entry slice — bundled atom plugins + boot walker.

docs/plans/plugins-implementation.md §3 / §6 / §8 / §9 flipped:
  - Architecture-state table records scaffold / export / publish /
    bundled / plugins/_official/atoms as shipped.
  - §6 Phase 4 deliverable list flips bundled atom extraction +
    full CLI parity remainder; the system.ts → SKILL.md prompt
    rewiring stays open as the next planned PR.
  - §8 e2e-3 row flips from entry-slice to full §8 contract:
    plugins-headless-run.test.ts asserts the first SSE event on a
    pipeline-bearing run is pipeline_stage_started.
  - §9 Status snapshot updated; head of the queue is now
    composeSystemPrompt() reading atom fragments from
    plugins/_official/atoms/<atom>/SKILL.md, then the AG-UI adapter,
    then Phase 5 Docker image.

Final gates: pnpm guard ✓, daemon 1481 tests ✓, web 586 tests ✓.

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 13:03:57 +00:00
Cursor Agent
26c5a27cf9
docs(plugins): record Phase 4 publish + CLI parity remainder
CHANGELOG.md ## Unreleased gets a new bullet block summarising:
  - Phase 4 publish CLI (od plugin publish --to <catalog> [--open]).
  - CLI parity remainder (od atoms / skills / design-systems / craft /
    status / version).
  - od marketplace search across configured catalogs.

docs/plans/plugins-implementation.md §3 / §6 / §9 flipped:
  - The CLI table records publish + atoms + skills + design-systems +
    craft + status + version + marketplace search as shipped, with the
    only remaining open verbs being od doctor + od config get/set/list.
  - Phase 4 deliverable list flips publish to shipped.
  - Status snapshot moves marketplace search and library CLI parity
    out of next-planned and into shipped; head of the queue is now the
    pipeline-runner-into-startChatRun integration plus Phase 4 atom
    migration into plugins/_official/ and the AG-UI adapter package.

Final gates: pnpm guard ✓, daemon 1475 tests ✓, web 586 tests ✓.

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 12:44:16 +00:00
Cursor Agent
a1798ba47d
docs(plugins): record Phase 4 author tooling + Phase 2B marketplace UI
CHANGELOG.md ## Unreleased gets a new bullet block summarising:
  - Phase 4 author tooling: od plugin scaffold + od plugin export with
    provenance README + claude-plugin / agent-skill targets.
  - Phase 2B marketplace deep UI: /marketplace + /marketplace/:id
    routes, MarketplaceView grid + filters + configured catalogs panel,
    PluginDetailView with capability + connector + GenUI surface
    summaries plus a 'Use this plugin' button.
  - Phase 2B ChatComposer mount of PluginsSection.
  - docs/atoms.md as the canonical first-party atom catalog reference.

docs/plans/plugins-implementation.md §3 / §6 / §9 flipped:
  - The web component table now records MarketplaceView + PluginDetailView
    as shipped (with the routes attached) and the ChatComposer rail mount
    flipped from absent → shipped.
  - The CLI table records od plugin scaffold + od plugin export as
    shipped Phase 4 deliverables; od plugin publish stays absent.
  - The Phase 4 deliverable list flips: docs/atoms.md, scaffold, export,
    and run shorthand are all checked. Atom migration into
    plugins/_official/, AG-UI adapter, plugin manifest .component
    capability, and CLI parity remainder stay open.
  - §9 Status snapshot updated; next-planned-PR cell moves the
    pipeline-runner-into-startChatRun integration to the head of the
    queue and points at the remaining Phase 4 / 5 backlog.

Final gates: pnpm guard ✓, daemon 1465 tests ✓, web 586 tests ✓.

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 12:33:38 +00:00
Cursor Agent
0e92952ac7
docs(plugins): record Phase 1 follow-up + 1.5 + 2B mount + 3 install resolution
CHANGELOG.md gets a new bullet block summarising:
  - Phase 1 follow-up CLI (od project / run / files / conversation).
  - Phase 1.5 headless lifecycle (od daemon start --headless / --serve-web /
    status / stop) with backing /api/daemon/status + /api/daemon/shutdown.
  - Phase 3 'od plugin install <name>' resolution through configured
    marketplaces.
  - Web composer mount: PluginsSection + NewProjectPanel integration.

docs/plans/plugins-implementation.md §3 / §6 / §8 / §9 flipped:
  - The Phase 1.5 deliverable list moves from open boxes to shipped
    rows.
  - The CLI table moves od project / run / files / conversation /
    daemon to shipped, with the lone remaining deferrals (od files
    diff, od project import, od conversation new, od marketplace
    search) called out explicitly.
  - The web component table records PluginsSection + the
    NewProjectPanel mount as shipped, with the deeper ChatComposer
    mount + MarketplaceView + PluginDetailView still scheduled for
    Phase 2B.
  - Phase 3 marks 'od plugin install <name>' as shipped; the Phase 3
    items still open are: trust UI, bundle-plugin installer, full
    doctor expansion.
  - §8 e2e-3 flips to entry-slice complete (HTTP-layer walkthrough);
    the live-agent-loop integration moves to the next-planned-PR cell.
  - §9 Status snapshot updated.

Final gates green: pnpm guard ✓, daemon 1455 tests ✓, web 579 tests ✓.

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 12:16:15 +00:00
Cursor Agent
20285c9959
docs(plugins): flip Phase 2A boxes + record Phase 3/5 entry slices
Plan §3 architecture state, §6 phase deliverables, §8 definition of done,
§9 status snapshot all updated to reflect the work that landed in this
branch.

CHANGELOG.md gets a new ## Unreleased bullet summarising the daemon /
CLI / web slice, with explicit pointers to the e2e test paths that
anchor each §8 row.

Phases / slices that flipped to shipped:

  - All Phase 2A daemon deliverables (pipeline, pipeline-runner,
    connector-gate, GenUI registry/store/events, snapshot resolver,
    SQLite migrations, HTTP routes, SSE / ND-JSON event emission, PB1
    renderer in contracts).
  - Phase 2A CLI: trust mutation, --grant-caps, --input k=v, recoverable
    exit codes 64–73, ui list/show/respond/revoke/prefill, plugin
    replay, plugin run shorthand, plugin snapshots prune.
  - Phase 2A web: applyPlugin() helper, InlinePluginsRail,
    ContextChipStrip, PluginInputsForm, GenUISurfaceRenderer
    (confirmation + oauth-prompt first-class), GenUIInbox.
  - Phase 3 entry slice: marketplace registry + od marketplace add /
    list / info / refresh / remove / trust + matching HTTP routes.
    Plugin-name resolution + trust UI stay scheduled.
  - Phase 5 (early): snapshot GC worker + applied-plugins audit
    routes + od plugin snapshots prune.

§8 Definition of Done: e2e-1, e2e-2, e2e-4, e2e-5, e2e-6, e2e-7, e2e-8
all anchored to specific daemon test paths. e2e-3 (headless run) stays
TBD pending Phase 1.5.

Status snapshot: Phase 2A finished + entry slices of Phase 2B/2C/3 +
early Phase 5; next planned PRs: Phase 1.5 headless flag (e2e-3
unblock), Phase 2B marketplace deep UI, Phase 3 `od plugin install
<name>` resolution + trust UI.

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 11:54:29 +00:00
pftom
4c7cd5d9f2 feat(plugins): introduce plugin system with installation and management capabilities
- Added support for a new plugin system, allowing users to install, uninstall, and manage plugins through the daemon.
- Implemented API endpoints for listing installed plugins, retrieving plugin details, and applying plugins with input validation.
- Introduced a plugin doctor feature to validate plugin manifests and check for issues before application.
- Established a plugin persistence layer with SQLite migrations for managing installed plugins and their metadata.
- Enhanced the CLI with commands for plugin operations, improving user interaction with the plugin ecosystem.
2026-05-09 18:24:44 +08:00
pftom
8d7f914b55 docs(plugins): enhance plugin specification and introduce implementation roadmap
- Added a new section detailing the implementation plan for the Open Design Plugin & Marketplace, serving as a living roadmap for future development.
- Updated the plugin specification to include the `expires_at` column in the `applied_plugin_snapshots` table, clarifying its role in snapshot retention and garbage collection.
- Revised the structure of the plugin block renderer, lifting it into the contracts layer to eliminate byte-equality drift and streamline plugin support across different consumption modes.
- Documented the phased approach to plugin functionality, ensuring clarity on the current capabilities and future enhancements within the plugin ecosystem.
2026-05-09 17:28:31 +08:00
Caprika
8eb9b1b506
Implement manual edit mode (#620) 2026-05-06 16:13:52 +08:00