Procházet zdrojové kódy

docs: document OpenCode v2 migration

Alvin Unreal před 3 týdny
rodič
revize
5930d2f570
5 změnil soubory, kde provedl 208 přidání a 187 odebrání
  1. 5 5
      .slim/clonedeps.json
  2. 1 1
      AGENTS.md
  3. 1 0
      README.md
  4. 27 2
      docs/clonedeps.md
  5. 174 179
      docs/opencode-v2-compatibility.md

+ 5 - 5
.slim/clonedeps.json

@@ -1,6 +1,6 @@
 {
 {
   "version": "1.0.0",
   "version": "1.0.0",
-  "updatedAt": "2026-08-04T19:15:39.000Z",
+  "updatedAt": "2026-08-25T00:00:00.000Z",
   "dependencies": [
   "dependencies": [
     {
     {
       "name": "@opencode-ai/plugin",
       "name": "@opencode-ai/plugin",
@@ -31,12 +31,12 @@
     },
     },
     {
     {
       "name": "anomalyco/opencode",
       "name": "anomalyco/opencode",
-      "resolvedVersion": "dev",
+      "resolvedVersion": "beta",
       "repoUrl": "https://github.com/anomalyco/opencode.git",
       "repoUrl": "https://github.com/anomalyco/opencode.git",
-      "ref": "dev@f0afb6750e63ee0a60b052914531bde0afb9bc2b",
+      "ref": "beta@d6deb62379c54dc60468b80c498bd6a5899797cf",
       "path": ".slim/clonedeps/repos/opencode",
       "path": ".slim/clonedeps/repos/opencode",
-      "packagePath": "packages/opencode",
-      "reason": "Latest OpenCode TypeScript runtime source with experimental background subagent support."
+      "packagePath": "packages/plugin",
+      "reason": "OpenCode v2 plugin SDK and runtime source for the v2 migration."
     },
     },
     {
     {
       "name": "agentclientprotocol/agent-client-protocol",
       "name": "agentclientprotocol/agent-client-protocol",

+ 1 - 1
AGENTS.md

@@ -180,7 +180,7 @@ Read-only dependency source repositories are available under
 `.slim/clonedeps/repos/` for inspection. Do not edit these clones.
 `.slim/clonedeps/repos/` for inspection. Do not edit these clones.
 
 
 - `.slim/clonedeps/repos/anomalyco__opencode-v1.18.13/` - `https://github.com/anomalyco/opencode.git` at `v1.18.13@a105350812f05f914c768e468559dbd6bd508d8e`; inspect `packages/plugin` and `packages/sdk/js` for OpenCode plugin and SDK internals.
 - `.slim/clonedeps/repos/anomalyco__opencode-v1.18.13/` - `https://github.com/anomalyco/opencode.git` at `v1.18.13@a105350812f05f914c768e468559dbd6bd508d8e`; inspect `packages/plugin` and `packages/sdk/js` for OpenCode plugin and SDK internals.
-- `.slim/clonedeps/repos/opencode/` - `https://github.com/anomalyco/opencode.git` at `dev@f0afb6750e63ee0a60b052914531bde0afb9bc2b`; inspect `packages/opencode` for latest TypeScript runtime internals and experimental background subagent support.
+- `.slim/clonedeps/repos/opencode/` - `https://github.com/anomalyco/opencode.git` at `beta@d6deb62379c54dc60468b80c498bd6a5899797cf`; inspect `packages/plugin`, `packages/sdk`, `packages/core`, and `packages/cli` for the OpenCode v2 migration.
 - `.slim/clonedeps/repos/modelcontextprotocol__typescript-sdk/` - `https://github.com/modelcontextprotocol/typescript-sdk.git` at `1.30.0@2d889f2b329e46680ec9bdd565de4616c497825a`; inspect it for MCP protocol and server integration internals.
 - `.slim/clonedeps/repos/modelcontextprotocol__typescript-sdk/` - `https://github.com/modelcontextprotocol/typescript-sdk.git` at `1.30.0@2d889f2b329e46680ec9bdd565de4616c497825a`; inspect it for MCP protocol and server integration internals.
 - `.slim/clonedeps/repos/agentclientprotocol__agent-client-protocol/` - `https://github.com/agentclientprotocol/agent-client-protocol.git` at `main@541daf8fa488c6b93aad4a874ac050b3daf9b282`; inspect it for ACP protocol specification and schema details.
 - `.slim/clonedeps/repos/agentclientprotocol__agent-client-protocol/` - `https://github.com/agentclientprotocol/agent-client-protocol.git` at `main@541daf8fa488c6b93aad4a874ac050b3daf9b282`; inspect it for ACP protocol specification and schema details.
 
 

+ 1 - 0
README.md

@@ -664,6 +664,7 @@ Use this section as a map: start with installation, then jump to features, confi
 | **[Configuration](docs/configuration.md)** | Config file locations, JSONC support, prompt overrides, and full option reference |
 | **[Configuration](docs/configuration.md)** | Config file locations, JSONC support, prompt overrides, and full option reference |
 | **[Project Customization](docs/project-local-customization.md)** | Repository-specific custom agents, prompt overrides, per-agent skills, and precedence |
 | **[Project Customization](docs/project-local-customization.md)** | Repository-specific custom agents, prompt overrides, per-agent skills, and precedence |
 | **[Background Orchestration](docs/background-orchestration.md)** | Scheduler-first orchestrator model built around native background subagents |
 | **[Background Orchestration](docs/background-orchestration.md)** | Scheduler-first orchestrator model built around native background subagents |
+| **[OpenCode v2 Compatibility](docs/opencode-v2-compatibility.md)** | Supported v1/v2 hosts, adapter behavior, feature coverage, and v2 limitations |
 | **[Maintainer Guide](docs/maintainers.md)** | Issue triage rules, label meanings, support routing, and repo maintenance workflow |
 | **[Maintainer Guide](docs/maintainers.md)** | Issue triage rules, label meanings, support routing, and repo maintenance workflow |
 | **[Skills](docs/skills.md)** | Bundled skills such as `simplify`, `codemap`, `clonedeps`, `deepwork`, `verification-planning`, `reflect`, `worktrees`, and `oh-my-opencode-slim` |
 | **[Skills](docs/skills.md)** | Bundled skills such as `simplify`, `codemap`, `clonedeps`, `deepwork`, `verification-planning`, `reflect`, `worktrees`, and `oh-my-opencode-slim` |
 | **[MCPs](docs/mcps.md)** | `context7`, `gh_grep`, and how MCP permissions work per agent |
 | **[MCPs](docs/mcps.md)** | `context7`, `gh_grep`, and how MCP permissions work per agent |

+ 27 - 2
docs/clonedeps.md

@@ -66,7 +66,10 @@ name, and may include a pinned-release suffix when multiple revisions need to
 coexist. For example, the TypeScript OpenCode repository
 coexist. For example, the TypeScript OpenCode repository
 `https://github.com/anomalyco/opencode.git` becomes
 `https://github.com/anomalyco/opencode.git` becomes
 `.slim/clonedeps/repos/anomalyco__opencode-v1.18.13/` when pinned to that
 `.slim/clonedeps/repos/anomalyco__opencode-v1.18.13/` when pinned to that
-release.
+release. This project also keeps a separate
+`.slim/clonedeps/repos/opencode/` checkout of the OpenCode `beta` source for
+intentional v2 migration work. That checkout is tracked as source by its branch
+and commit, not as an npm-pinned dependency.
 
 
 If multiple packages come from the same monorepo, they share one cloned repo path
 If multiple packages come from the same monorepo, they share one cloned repo path
 and use different `packagePath` values in the manifest.
 and use different `packagePath` values in the manifest.
@@ -75,7 +78,9 @@ These repositories are read-only reference source. Do not edit them.
 
 
 ### `.slim/clonedeps.json`
 ### `.slim/clonedeps.json`
 
 
-This is the structured manifest. It is intentionally small and committable:
+This is the structured manifest. It is intentionally small and committable. The
+following abbreviated example shows the OpenCode entries; other manifest entries
+are omitted:
 
 
 ```json
 ```json
 {
 {
@@ -99,11 +104,27 @@ This is the structured manifest. It is intentionally small and committable:
       "path": ".slim/clonedeps/repos/anomalyco__opencode-v1.18.13",
       "path": ".slim/clonedeps/repos/anomalyco__opencode-v1.18.13",
       "packagePath": "packages/sdk/js",
       "packagePath": "packages/sdk/js",
       "reason": "Core SDK source used to inspect runtime behavior"
       "reason": "Core SDK source used to inspect runtime behavior"
+    },
+    {
+      "name": "anomalyco/opencode",
+      "resolvedVersion": "beta",
+      "repoUrl": "https://github.com/anomalyco/opencode.git",
+      "ref": "beta@d6deb62379c54dc60468b80c498bd6a5899797cf",
+      "path": ".slim/clonedeps/repos/opencode",
+      "packagePath": "packages/plugin",
+      "reason": "OpenCode v2 plugin SDK and runtime source for the v2 migration"
     }
     }
   ]
   ]
 }
 }
 ```
 ```
 
 
+The actual manifest may contain additional dependency entries beyond this
+abbreviated example.
+
+The beta entry is a checked-out source reference: `resolvedVersion` identifies
+the beta channel, while `ref` records the branch and commit. It does not pin an
+npm package version.
+
 Future clonedeps runs read this file first instead of starting from a fresh scan.
 Future clonedeps runs read this file first instead of starting from a fresh scan.
 
 
 ### `AGENTS.md`
 ### `AGENTS.md`
@@ -124,6 +145,10 @@ Read-only dependency source repositories are available under
   `anomalyco/opencode` at
   `anomalyco/opencode` at
   `v1.18.13@a105350812f05f914c768e468559dbd6bd508d8e`; inspect `packages/plugin` and
   `v1.18.13@a105350812f05f914c768e468559dbd6bd508d8e`; inspect `packages/plugin` and
   `packages/sdk/js` for OpenCode plugin and SDK internals.
   `packages/sdk/js` for OpenCode plugin and SDK internals.
+- `.slim/clonedeps/repos/opencode/` - `anomalyco/opencode` at
+  `beta@d6deb62379c54dc60468b80c498bd6a5899797cf`; inspect the checked-out beta
+  source as an intentional OpenCode v2 migration reference. This is not an
+  npm-pinned dependency.
 ```
 ```
 
 
 ---
 ---

+ 174 - 179
docs/opencode-v2-compatibility.md

@@ -1,201 +1,196 @@
-# OpenCode v2 (`opencode2`) Compatibility
+# OpenCode v2 compatibility and native migration
 
 
-oh-my-opencode-slim installs and runs on **both** OpenCode v1 (`opencode`) and
-OpenCode v2 (`opencode2`) from a single published package. This document
-explains how the dual-compatibility works and what is supported on each host.
+## Current status
 
 
-## How it works
+OpenCode v2 compatibility is currently provided by a **v1-to-v2 adapter**. It
+is not a native v2 implementation, and native v2 support has not shipped.
 
 
-The package's default export is an object:
+The current path is `src/v2/setup.ts`:
 
 
-```ts
-export default {
-  id: 'oh-my-opencode-slim',
-  server: OhMyOpenCodeLite, // v1 plugin function (PluginInput) => Promise<Hooks>
-  setup: createV2Setup(),   // v2 promise-plugin setup (ctx) => Promise<cleanup>
-};
-```
+1. v2 calls the package's `default.setup(ctx)` entry point.
+2. The adapter builds a v1-shaped `PluginInput`, including a client shim and
+   `process.cwd()` as the project directory.
+3. It invokes the existing `OhMyOpenCodeLite` v1 factory and receives v1
+   `Hooks`.
+4. It translates those hooks into v2 agent, tool, command, session-context,
+   tool-lifecycle, and event registrations.
+5. It returns cleanup functions for the v2 registrations and the v1 factory.
+
+This preserves useful behavior while both hosts are supported, but it is a
+best-effort compatibility layer. Registration failures are independently
+isolated, so a plugin can load with only part of its behavior registered.
+
+The beta checkout used for the migration target is OpenCode `v2` at
+`d6deb62379c54dc60468b80c498bd6a5899797cf`.
+
+## Installing the current adapter on v2
 
 
-- **v1 loader** (`readV1Plugin` in `packages/opencode/src/plugin/shared.ts`)
-  detects an object with a `server` field and calls `plugin.server(input)`.
-  This is the original, unchanged v1 code path — v1 behavior is identical to
-  previous releases.
-- **v2 loader** (`PluginModule` schema in
-  `packages/core/src/plugin/supervisor.ts`) decodes `default` as
-  `{ id, setup }` (Effect Schema 4 rejects function defaults) and calls
-  `setup(ctx)` via the promise-plugin bridge.
-
-Two builds are produced:
-
-| Export | File | Build | Externals |
-|---|---|---|---|
-| `.` (main) | `dist/index.js` | `build:plugin` | zod, jsdom, @ast-grep/napi, @opencode-ai/* (shared with v1 host) |
-| `./server` | `dist/server.js` | `build:v2` | @ast-grep/napi, jsdom only (self-contained for v2) |
-
-v2's plugin resolver tries the `server` subpath first
-(`subpaths: ["server", ""]`), so a v2 package install loads the self-contained
-`dist/server.js`. v1 uses the main entry.
-
-## The v2 adapter (`src/v2/setup.ts`)
-
-`setup(ctx)` wraps the existing v1 factory rather than reimplementing it:
-
-1. Builds a v1-shaped `PluginInput` from the v2 context (`process.cwd()` for
-   `directory`; a shim `client` that delegates `session.abort/prompt/messages`,
-   `app.log`, and `tui.showToast` to the v2 context or graceful no-ops).
-2. Invokes `OhMyOpenCodeLite(pluginInput)` to reuse **all** existing build
-   logic (config, agents, tools, hooks, job board, multiplexer, companion).
-3. Runs the v1 `config()` hook against a synthesized config to resolve agent
-   models and the slash commands.
-4. Bridges the returned v1 `Hooks` into v2 registrations:
-   - `agent` → `ctx.agent.transform` (model/prompt/permission adaptation +
-     `subagent`/`execute` permission mapping + prompt rewrite `task`→`subagent`)
-   - `tool` → `ctx.tool.transform` (zod shape → JSON schema; execute shimmed)
-   - `command` → `ctx.command.transform` (deepwork/reflect/loop)
-   - `experimental.chat.system.transform` +
-     `experimental.chat.messages.transform` → `ctx.session.hook("context")`
-     (SystemPart[]/Message.content shape conversion)
-   - `tool.execute.before/after` → `ctx.tool.hook`
-   - `event` → `ctx.event.subscribe()` loop
-   - `dispose` → returned cleanup
-
-Each bridge is independently try/catch-guarded so one failure cannot disable
-the rest.
-
-## Feature matrix
-
-| Capability | v1 (`opencode`) | v2 (`opencode2`) | Notes |
-|---|---|---|---|
-| Orchestrator + specialist agents | ✅ | ✅ | |
-| Agent prompts / system injection | ✅ | ✅ | via `session.hook("context")` |
-| Delegation to subagents | ✅ `task` | ✅ `subagent` | prompts rewritten for v2 |
-| Tools (ast-grep, webfetch, task_message, task_cancel, task_revive, wait_for_user, acp_run) | ✅ | ✅* | `*` ast-grep/webfetch need `@ast-grep/napi`/`jsdom` resolvable |
-| Slash commands `/deepwork` `/reflect` `/loop` | ✅ | ✅ | |
-| Message transforms (phase reminder, skills filter, image routing, display-name rewrite) | ✅ | ✅ | |
-| Event handling (session tracking, lifecycle) | ✅ | ✅ | |
-| Tool execute hooks (apply-patch recovery, task-session, json-recovery) | ✅ | ✅ | |
-| Built-in MCPs (context7, grep.app) | ✅ | ⚠️ config-only | v2 has no programmatic MCP hook; add 2 lines to `opencode.json` — see [below](#restoring-built-in-mcps-on-v2) |
-| `/preset` (interactive switcher) | ✅ | ❌ at load only | the switcher is a v1-TUI 3-level UI; on v2 set `"preset"` in the config file (applies at load) |
-| Foreground model fallback (rate-limit failover) | ✅ | ❌ | v2 locks the model at session creation; the plugin API has no per-prompt model override, session model-setter, or `/model` command, so mid-flight switching is impossible |
-| Orchestrator wake scheduler (`backgroundJobs.orchestratorWake`) | ✅ | ❌ | Requires host `session.get` / `todo` / `children` / `status` / `promptAsync`; the v2 shim lacks these APIs so the capability-gated feature stays inactive |
-| Multiplexer (tmux/zellij/herdr/cmux panes) | ✅ | ❌ | v1-TUI-pane integration; v2 renders subagents natively instead |
-| Companion app | ✅ | ⚠️ unverified | independent desktop app; test separately against v2 |
-| Default agent on new session | ✅ orchestrator | ⚠️ TUI shows `build` | v1 sets `default_agent`; v2's TUI ignores that field and defaults to the first agent in its list (`build`). `run`/API still default to orchestrator. See [limitations](#limitations) |
-
-## Installing on v2
-
-Add to `~/.config/opencode2/opencode.json`:
+The existing package install remains. In the beta checkout, the executable is
+`opencode2` but the global configuration root is still named `opencode`:
+
+Add to `~/.config/opencode/opencode.json`:
 
 
 ```json
 ```json
 {
 {
-  "plugin": ["oh-my-opencode-slim@latest"]
+  "plugins": ["oh-my-opencode-slim@latest"]
 }
 }
 ```
 ```
 
 
-For local development, point at the built `dist/server.js` directly:
+For local development, use the v2 bundle directly:
 
 
 ```json
 ```json
 {
 {
-  "plugin": ["/path/to/oh-my-opencode-slim/dist/server.js"]
+  "plugins": ["/path/to/oh-my-opencode-slim/dist/server.js"]
 }
 }
 ```
 ```
 
 
-Then build:
+Build the two host bundles with:
 
 
 ```bash
 ```bash
 bun install
 bun install
-bun run build   # produces dist/index.js (v1) AND dist/server.js (v2)
-```
-
-Verify with `opencode2 run "list your specialist agents" --standalone` — the
-orchestrator should name explorer, librarian, oracle, designer, fixer.
-
-## Configuring models on v2
-
-Agent models are resolved the same way as v1 (per-agent `model` in
-`oh-my-opencode-slim.json`, or inherited from the session/host default). On v2,
-set a working provider+model in your v2 config or the plugin's config file so
-delegated subagents can run.
-
-> **Rate-limit fallback is not available on v2.** v2 locks a session's model at
-> creation; the plugin context exposes no per-prompt model override, no
-> session-level model setter, and no `/model` command. If you hit a 429/rate
-> limit, switch the model manually (start a new session or change the configured
-> model) — the plugin cannot do this automatically on v2.
-
-## Restoring built-in MCPs on v2
-
-v2 has no programmatic MCP-registration hook, so the plugin's two built-in
-remote MCPs are not auto-registered. They are plain remote URLs — copy this into
-your `~/.config/opencode2/opencode.json` to restore them:
-
-```json
-{
-  "mcp": {
-    "context7": {
-      "type": "remote",
-      "url": "https://mcp.context7.com/mcp",
-      "headers": { "CONTEXT7_API_KEY": "$CONTEXT7_API_KEY" }
-    },
-    "gh_grep": { "type": "remote", "url": "https://mcp.grep.app" }
-  }
-}
+bun run build
 ```
 ```
 
 
-(`context7` needs `CONTEXT7_API_KEY`; `gh_grep` needs nothing. Drop either key
-if unused.) The librarian agent uses these for library-docs lookup and
-GitHub-wide code search; without them it still works via `webfetch`.
-
-## Limitations
-
-### Interview
-
-`/interview` is supported on v2 through a marker command and a trailing-message
-context bridge. The bridge keeps an in-memory transcript projection from v2
-context and streamed text events, and uses the v2 session methods for prompts,
-notifications, and renames. The markdown document remains the durable source
-of truth; completion responses without `<interview_state>` rewrite the current
-spec while retaining frontmatter and Q&A history.
-
-These are **v2 API constraints**, not adapter gaps — they cannot be fixed in the
-plugin without v2 adding the corresponding capability:
-
-- **Foreground model fallback impossible.** v2's `SessionPromptInput` has no
-  `model` field, the plugin `SessionDomain` exposes only
-  `create/get/prompt/generate/command/synthetic/interrupt` (no model setter),
-  and there is no `/model` command. A session's model is fixed at creation, so
-  the plugin cannot switch models on a rate-limited foreground session.
-  v1-only.
-- **Interactive `/preset` switcher impossible.** The switcher is a three-level
-  v1-TUI UI (`@opentui/solid`). v2 slash commands are template-only (no
-  interactive UI, no execute handler). **Workaround:** set `"preset"` in
-  `oh-my-opencode-slim.json` — it applies at plugin load and resolves all agent
-  models correctly.
-- **No programmatic MCP registration.** v2's plugin context has no MCP domain.
-  Declare MCPs in `opencode.json` (snippet above).
-- **Multiplexer panes.** tmux/zellij/herdr integration is a v1-TUI feature; v2
-  renders subagents natively, so this is intentionally not ported.
-- **TUI default agent is `build`, not `orchestrator`.** v1 sets
-  `default_agent = "orchestrator"` in its config hook and the v1 TUI honors it.
-  The v2 adapter does call `ctx.agent.transform(draft => draft.default("orchestrator"))`,
-  which makes `run`/API default to the orchestrator — but the v2 TUI ignores the
-  `default_agent` config field entirely and instead defaults to the **first agent
-  in its list** (`list()[0]`, insertion order), which is v2's built-in `build`.
-  The plugin API offers no list-reorder, and `AgentDraft` has no "move to front".
-  Effect: `opencode2 run` and programmatic sessions use the orchestrator; opening
-  the v2 TUI / starting a new session there defaults to `build` (switch once; the
-  choice is persisted per-session via `saved.session[id].agent`, but each brand-new
-  session resets to `build`). Requires an upstream v2 change (TUI honoring
-  `default_agent`, or a list-order/default API for plugins) to fix.
-
-These are adapter/environment caveats that can be worked around:
-
-- **Path-based dev loading.** When v2 loads the plugin by absolute file path it
-  appends a `?mtime=` cache-busting query, which can break resolution of
-  externalized bare imports (`@ast-grep/napi`, `jsdom`) from the plugin's
-  `node_modules`. The plugin still loads (these are lazy-imported only by the
-  ast-grep and webfetch tools); install as a package or ensure the externals are
-  resolvable to enable those tools locally.
-- **directory source.** v2's plugin context does not expose the project
-  directory, so the adapter uses `process.cwd()`. Run `opencode2` from your
-  project root (or use `--standalone`, which sets cwd to the project).
+The build currently produces `dist/index.js` for v1 and `dist/server.js` for
+the v2 adapter. Run OpenCode v2 from the project directory, or use
+`--standalone`, because the adapter has no project-directory field and uses
+`process.cwd()`.
+
+## Adapter limitations
+
+These are limitations of the transitional implementation, not proof that the
+official v2 API lacks the capability:
+
+- The adapter must construct fake v1 input and translate v1 hook shapes. It
+  cannot provide the type or lifecycle guarantees of a native v2 plugin.
+- It uses a client shim with only selected operations and graceful no-ops.
+  Legacy code that expects v1 client state, task/session helpers, headers, or
+  UI behavior cannot be made equivalent by the shim.
+- The v1 factory and synthesized `config()` hook remain the source of agent,
+  tool, command, and runtime wiring. Failed bridges are logged and skipped
+  rather than failing setup as a native plugin should.
+- The adapter currently does not register built-in MCP definitions through the
+  v2 MCP domain. OpenCode v2 does provide that domain; native migration must
+  use it rather than treating MCP support as config-only.
+- The adapter's interview bridge reconstructs only an in-memory projection
+  from v2 context and events. It is not a durable, reload-safe v2 history
+  implementation.
+- Absolute-path development loading can expose externalized `jsdom` and
+  `@ast-grep/napi` resolution problems. Installing the package or making those
+  dependencies resolvable avoids this adapter/build issue.
+
+## Supported native v2 surface
+
+The beta Promise plugin API uses `define({ id, setup(context) })`; setup returns
+cleanup and registrations are disposed with plugin scope. Its domains include:
+
+- `agent`: inspect/update/remove agents, set the default, and transform the
+  agent catalog;
+- `tool`: add tools and hook `execute.before`/`execute.after`;
+- `command`: add executable command definitions and reload commands;
+- `session`: create/get/switch agent/switch model, prompt, generate, command,
+  synthetic, interrupt, rename, wait, and hook `context`, `model.request`,
+  `http.request`, or `http.response`;
+- `event`: subscribe to the server event stream;
+- `mcp`: transform, add, update, remove, and reload MCP configurations;
+- `shell`, `skill`, `storage`, and `websearch`: supported domain APIs for the
+  corresponding native integrations.
+
+Session `context` is the supported native replacement for v1 raw message
+transforms. Native code should mutate the v2 `system`, `messages`, and `tools`
+context directly, without converting through v1 `{ info, parts }` objects.
+
+## Native target architecture
+
+The target is a separate native Promise-plugin composition, not a more capable
+adapter:
+
+1. Keep host-neutral configuration, agent definitions, prompt construction, and
+   tool definitions in shared modules.
+2. Move the existing v1 composition behind an explicit `src/v1` boundary.
+3. Implement a native `define({ id, setup })` composition that registers agents,
+   tools, executable commands, MCPs, session context/model hooks, tool hooks,
+   and event handling through the official domains.
+4. Replace the client shim, local v2 type mirror, and interview bridge with
+   native context and lifecycle modules.
+5. Make required registration failures fail setup; do not silently continue
+   with a partial native installation.
+
+The native implementation must not invoke the v1 factory, convert v2 values to
+v1 hook payloads, or retain legacy lifecycle ownership merely to preserve
+parity.
+
+## Behaviors to deliberately retire
+
+Exact v1 parity is not possible through the supported v2 Promise API. The
+following behaviors must be explicitly retired from the native v2 target,
+rather than emulated with shims:
+
+- legacy background-job ownership and orchestrator wake scheduling;
+- child-pane multiplexer integration (tmux, zellij, herdr, and cmux);
+- runtime foreground-model failover;
+- tool permission prompt/cancellation interception;
+- initiator-header injection;
+- interview-history reconstruction after a plugin reload.
+
+The beta API also has no exact plugin hooks for compaction prompt replacement,
+permission-prompt interception, or synthetic text completion. Those behaviors
+need a product-level replacement or explicit retirement; they must not be
+presented as native parity.
+
+TUI toasts and the interactive `/preset` switcher are **not** required
+retirements. The beta plugin package exposes TUI participation through
+`tui: true` and the TUI context surface, so native migration should evaluate
+those controls as API opportunities. The current adapter does not bridge them;
+that is an adapter gap, not a claim that the native API cannot support them.
+
+Small-model selection is an inventory decision, not a predeclared retirement.
+The current implementation uses `runtime.smallModel()` for SmartFetch's
+secondary-model selection. The native migration must determine the supported
+v2 equivalent and its parity requirements during inventory.
+
+The official API does provide MCP registration, session model switching, and
+executable command registration. Those are migration opportunities, not
+retirements. In particular, the old documentation claim that v2 has no model
+setter or programmatic MCP surface is outdated for the beta checkout.
+
+The current adapter does not preserve the v1 `/preset` TUI experience. Native
+migration should decide whether the v2 TUI context can provide an equivalent
+interactive control or whether a documented noninteractive config/command
+workflow is preferable; it must not claim v1 UI parity before that work is
+verified.
+
+## Verification gates
+
+Validation is required at each migration boundary:
+
+1. **Architecture gate:** approve the host-neutral boundary, native domain
+   mapping, parity definition, and deliberate retirements.
+2. **Static/runtime gate:** compile, lint, and run unit tests for shared code,
+   the v1 host, and native registrations. Required registration failures must
+   be observable failures.
+3. **v2 host smoke gate:** using the beta checkout's embedded-host patterns and
+   `bun run dev:live`, prove plugin loading, agent/tool/command/MCP registration,
+   a session-context transform, tool lifecycle hooks, event handling, and
+   cleanup.
+4. **v1 compatibility gate:** retain the existing v1 load/smoke path until the
+   cutover is complete; verify that the v1 factory remains unchanged during
+   the transition.
+5. **Release-readiness gate:** verify the published package entry points,
+   install path, native v2 smoke artifact, documented retirements, and absence
+   of adapter-only claims before removing the transitional path.
+
+## Migration roadmap
+
+1. **Inventory:** map each v1 behavior to an official v2 domain, classify it as
+   native, adapter-only, or retired, and obtain approval for the retirements.
+2. **Separate composition:** introduce shared host-neutral config/prompt/tool
+   logic, move v1 composition to `src/v1`, and implement native Promise setup
+   with strict registration and cleanup.
+3. **Prove both hosts:** run the v2 host smoke and v1 compatibility gates in
+   parallel; compare supported behavior without expanding the shim.
+4. **Cut over v2:** make the native composition the v2 entry point, remove the
+   v1 adapter, client shim, local v2 type mirror, and interview bridge, then
+   retain v1 only for the verified cutover period.
+5. **Complete migration:** after release-readiness review, decide whether the
+   v1 host can be retired and remove remaining compatibility-only code.