Skip to content

C2: Port the plugin runtime to the v2 Effect-first plugin API - #33

Merged
diegohb merged 4 commits into
mainfrom
v2/issue-25-effect-ts
Oct 6, 2026
Merged

diegohb merged 4 commits into
mainfrom
v2/issue-25-effect-ts

Conversation

@diegohb

@diegohb diegohb commented Oct 6, 2026

Copy link
Copy Markdown
Member

Closes #25 (C2, child of spec #23)

What

Ports the plugin runtime from the v1 @opencode-ai/plugin factory to the opencode v2 Effect-first plugin API, per the C1 verified-facts record (docs/reference/opencode-v2-facts.md, pinned to anomalyco/opencode v2.0.23).

  • Definition: default export is now a v2 plugin definition { id: "opencode-architect", effect } built with Plugin.define from @opencode/plugin/effect (facts §1–2). The v1 factory, its types, and the config hook are gone.
  • Agents: registered through ctx.agent.transform + editor.update upserts (system, description, mode, permissions), mirroring the pinned first-party exemplar core/src/config/plugin/agent.ts.
  • Permissions: the external-directory allow migrates to v2 semantics — a ctx.permission.hook("evaluate") decision that upgrades a pending ask to allow only for external_directory resources inside the bundled assets directory. Explicit config denies are final under v2 and never reach the hook, preserving the old deny-wins behavior.
  • Frontmatter translation: prompt → system; the tools boolean map and permission keyed record become a v2 permission ruleset using the pinned normalizeAction renames (write/patch → edit, task → subagent, bash → shell) (facts §4–6).
  • Preserved invariants: prompt path rewriting untouched; at-most-once advisories with separate guards; startup non-interference — a failed load degrades to the single stale-cache advisory and skips the not-installed advisory, matching v1 ordering; successful activations advise once and stay suppressed.
  • Dependencies: @opencode/plugin@2.0.23 + effect@4.0.0-rc.112 pinned (C1 adjudication; 2.0.24 was latest at execution — flagged, not adopted per spec). @opencode-ai/plugin and @opencode-ai/sdk removed. Consumer-facing templates declare @opencode/plugin and effect at @latest so generated packages resolve current versions at time of use — policy recorded in facts §15 for C5–C7.

Acceptance criteria (all verified at 8670c4b)

  • Plugin loads under a v2 host and registers all ten agents — activation harness registers exactly 10 agents with non-empty system and valid mode; host-level load smoke lands with C4's harness per the spec's ticket split
  • Permission registration works under v2 semantics — nine decision-table tests on the evaluate hook
  • Prompt path rewriting and advisories behave as before
  • No v1 plugin API usage remains in the runtime — zero @opencode-ai/* in src/
  • Typecheck and migrated test suite green — tsc --noEmit clean; migrated tests 23/23; full suite 143 pass with only the 5 failures that pre-exist on the base commit (Windows-only environment artifacts in tarball/cache tests; CI runs ubuntu)

Evidence: issue comment

Test plan

  • bun run check (tsc --noEmit)
  • bun test — baseline diff vs fbbaed8 shows no new failures
  • CI on ubuntu (this PR)

Out of scope (owned by sibling tickets)

diegohb added 4 commits October 6, 2026 00:54
…@4.0.0-rc.112

v1 packages stay until the runtime port commit removes them, so this
commit typechecks and tests at baseline. Versions pinned to the C1
adjudication (opencode-v2-facts #24); @opencode/plugin 2.0.24 is out but
the spec forbids silently upgrading the 2.0.23 pin.
The default export is now a v2 plugin definition { id, effect } built
with Plugin.define from @opencode/plugin/effect, carrying the stable id
'opencode-architect'. Agents register through ctx.agent.transform via
editor.update upserts (system, description, mode, permissions) — the
v1 config hook is gone.

The external-directory allow migrates to v2 permission semantics: the
plugin registers a permission evaluate hook that upgrades a pending ask
to allow only for external_directory resources inside the bundled
assets directory. Explicit config denies are final under v2 and never
reach the hook, preserving the old deny-wins behavior.

Frontmatter translation follows the verified-facts record (opencode-v2-facts
sections 4-6): prompt becomes system, the tools boolean map and the
permission keyed record become a v2 permission ruleset using the pinned
normalizeAction renames (write/patch to edit, task to subagent, bash to
shell).

Startup non-interference is preserved: a failed load degrades to the
at-most-once stale-cache advisory and skips the not-installed advisory,
matching v1 ordering; successful activations advise once and stay
suppressed. Prompt path rewriting is untouched.

Dependencies move to the C1-adjudicated v2 packages (@opencode/plugin
2.0.23, effect 4.0.0-rc.112); @opencode-ai/plugin and @opencode-ai/sdk
are removed. Tests migrate to a v2 activation harness with spy agent
and permission domains.
…elpers into AgentLoader

AgentFrontmatter now uses nullable fields per the coding standard, with
absent YAML keys normalized to null at the parse boundary. The
frontmatter translation helpers move into AgentLoader as private
methods per classes-over-helpers, and the adviseIfNotInstalled wrapper
is inlined.
…eeps the 2.0.23 pin

The full-package manifest template names @opencode/plugin and effect at
latest so generated packages pick up current versions at time of use;
the opencode-architect runtime stays pinned to the C1 adjudication
(2.0.23 / 4.0.0-rc.112; 2.0.24 was latest at execution — flagged, not
adopted). The policy is recorded in opencode-v2-facts section 15 so the
guidance-rewrite tickets (C5-C7) enforce it.
@diegohb
diegohb merged commit c8c7e3a into main Oct 6, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

C2: Port the plugin runtime to the v2 Effect-first plugin API

1 participant