JSPM

  • Created
  • Published
  • Downloads 786
  • Score
    100M100P100Q114529F
  • License ISC

OpenCode plugin for opencode-wizard published skills

Package Exports

  • @aexol/opencode-wizard/server
  • @aexol/opencode-wizard/tui

Readme

@aexol/opencode-wizard

@aexol/opencode-wizard is a separately releasable OpenCode and Pi plugin package for fetching published skills from the opencode-wizard backend runtime and surfacing plugin status in OpenCode/Pi hosts.

Package target

  • oc-plugin: ["server", "tui"]
  • ./serverdist/server.js
  • ./tuidist/tui.js
  • pi.extensions: ["./dist/pi.js"]
  • ./pidist/pi.js
  • no generated runtime skill directory is published; the plugin stays fetch-only at runtime
  • native OpenCode skills.urls is treated as a public/static registry complement, not as the private wizard delivery authority
  • the TUI is a compact status panel: it shows backend URL, signed-in identity, role, and catalog counts while mutations still run through guarded tools

Local development

This monorepo still path-loads the same package from ./plugins/opencode-wizard during local OpenCode development.

Backend origin resolution defaults to the deployed backend at https://opencode-wizard.aexol.work for both local path-loaded and packaged plugin usage. Set OPENCODE_WIZARD_BACKEND_ORIGIN explicitly to target a local/backend URL. Generic host APP_URL and PORT are ignored so released plugin usage does not accidentally target placeholder app URLs or the OpenCode host port.

Useful commands:

npm run typecheck
npm run test
npm run build
npm run release:check
npm pack --dry-run

Published package usage

OpenCode server/plugin host can install the published package by package name instead of a repo-local path:

{
  "plugin": ["@aexol/opencode-wizard@latest"]
}

For repo-local development, continue using the local path-based config already documented in this repository.

Pi package usage

The same npm package can be loaded by Pi as a native Pi package/plugin; it does not use MCP and does not duplicate degraded static catalog stubs.

pi install -l ./plugins/opencode-wizard
# or use the published package when available:
pi install @aexol/opencode-wizard@latest

Pi loads the pi.extensions entrypoint at ./dist/pi.js, registers Pi-native tools, and bridges them to the same real backend/client/runtime handlers used by the OpenCode server plugin:

  • wizard_statusopencode_wizard_status
  • wizard_catalog_fetchopencode_wizard_catalog_fetch
  • wizard_artifact_fetchopencode_wizard_artifact_fetch
  • wizard_artifact_preference_setopencode_wizard_artifact_preference_set
  • wizard_published_skills_fetchopencode_wizard_published_skills_fetch
  • wizard_published_skill_preference_setopencode_wizard_published_skill_preference_set
  • wizard_report_issueopencode_wizard_report_issue
  • editor-only tools include wizard_initopencode_wizard_init and wizard_updateopencode_wizard_update

The Pi before_agent_start hook calls the same runtime system-note path as OpenCode, so dynamic prompt context comes from real backend catalog/status resolution when auth and catalog fetches succeed. Missing auth, forbidden role, backend, or catalog failures are returned as explicit operational states by the existing wizard runtime; no tokens are exposed.

Pi usage has the same backend configuration and auth prerequisites as OpenCode usage: the backend origin defaults to https://opencode-wizard.aexol.work, OPENCODE_WIZARD_BACKEND_ORIGIN can override it, and plugin session auth is stored in ~/.config/opencode/opencode-wizard.json.

Native skills.urls compatibility

OpenCode's native skills.urls support downloads public/static skill registries from base URLs that expose an index.json and file paths under that base URL. Current support has no plugin session/header integration, so it must not be pointed at private opencode-wizard skill delivery.

Use skills.urls only for public registries that are intentionally cacheable by OpenCode. Private workspace-scoped wizard artifacts remain authenticated and directory-scoped through opencode_wizard_artifact_fetch or compatibility opencode_wizard_published_skills_fetch; same-named native/local seed skill bodies are not authoritative for wizard-listed skills.

Catalog discovery and auth bootstrap

Catalog discovery uses the backend-issued plugin session token stored at ~/.config/opencode/opencode-wizard.json (auth field); the plugin does not persist or send Microsoft/Entra tokens to GraphQL. If no valid plugin session exists, no-arg opencode_wizard_catalog_fetch, compatibility no-arg opencode_wizard_published_skills_fetch, explicit opencode_wizard_status, and chat/system-context startup may start the browser Entra PKCE flow and exchange the callback for a fresh backend-issued plugin session. The TUI panel displays the resulting backend URL, auth identity, role, and catalog counts from that status payload.

The shared plugin tools opencode_wizard_catalog_fetch, opencode_wizard_artifact_fetch, opencode_wizard_artifact_preference_set, compatibility published-skill tools, opencode_wizard_status, and opencode_wizard_report_issue are always exposed by the plugin. Missing auth, forbidden role, backend, or catalog/report problems are reported by tool output/status metadata instead of hiding these shared tools; opencode_wizard_editor_create_or_update_skill, opencode_wizard_editor_publish_skill, opencode_wizard_artifact_import, opencode_wizard_init, and opencode_wizard_update stay editor-only.

Use opencode_wizard_report_issue for authenticated Wizard BUG/FEATURE reports. Required args are reportType (BUG or FEATURE), title, and description; optional safe fields include severity/priority, reproduction steps, expected/actual behavior, impact, labels, related tool, directory override, and a repo-relative path. The tool sends source: OPENCODE, safe workspace/repository/directory context, and bounded metadata only; it does not capture transcripts, prompts, env, secrets, tokens, raw logs, or unbounded local absolute paths.

Call opencode_wizard_catalog_fetch with artifactKind: SKILL or compatibility opencode_wizard_published_skills_fetch without skill or skills to manually bootstrap plugin login if needed and return catalog-only discovery output for the current directory scope.

No-arg discovery returns published skill summaries, assignment counts split into global, project, user, and other, policy metadata, and no markdown bodies. Canonical opencode_wizard_artifact_fetch with artifactKind: SKILL and compatibility skill/skills calls fetch one or more full skill body/detail payloads by slug, artifact name, or skill name. DESIGN_DOC uses generic wizard artifact persistence and returns metadata-only catalogs plus explicit DESIGN.md body/files detail fetches for effective assignments. Use the fetched markdownDocument/markdownBody as the authoritative wizard skill body before applying a wizard-listed skill.

Workspace delivery still follows the backend contract: the plugin sends workspaceSlug when it has one, otherwise falls back to repositoryUrl. The plugin now prefers configured or learned workspace slug mappings over a repo-basename fallback, and learns durable slug-to-repo mappings from successful backend catalog responses so worktrees and nontrivial repo roots stay aligned.

Published skill fetches still support refresh: true, but normal cache entries now self-expire after 30 seconds and fetch/status payloads surface source, workspaceSlug, and workspaceSlugSource so stale-vs-refreshed behavior is visible without relying on manual cache deletion. Try refresh: true and report the tool-output auth/catalog/source/cache/workspace-resolution state before deleting ~/.cache/opencode/*.

Use opencode_wizard_artifact_preference_set or compatibility opencode_wizard_published_skill_preference_set for preference actions (install, uninstall, ignore, unignore); the TUI panel stays read-only and does not run preference mutations directly.

EDITOR skill creation flow

For new or updated skills, the canonical plugin path is direct markdown creation:

  1. Draft the complete SKILL.md markdown content in chat or another editor.
  2. Call opencode_wizard_editor_create_or_update_skill with markdownContent and optional directory.
  3. Use opencode_wizard_artifact_fetch with artifactKind: "SKILL" or compatibility opencode_wizard_published_skills_fetch to verify the backend-published body that became runtime authority.

Keep opencode_wizard_editor_publish_skill for the legacy seed-file flow when .opencode/skills/<slug>/SKILL.md already exists locally. Keep opencode_wizard_artifact_import for external SKILL/DESIGN_DOC sources such as GitHub skill repos or npx getdesign@latest add ... inputs. EDITOR role is checked both when exposing these tools and again at execution time.

Editors can import external artifacts without writing project files via opencode_wizard_artifact_import: use source: "npx getdesign@latest add bmw-m" for a DESIGN_DOC, or source: "https://github.com/vercel-labs/agent-skills --skill react-best-practices" for a SKILL. The plugin import path is a command/raw-source bridge into generic backend artifact persistence: it fetches markdown or a zip-backed SKILL.md/README.md, sends it to the backend import mutation, records the importing editor in existing created/published actor fields plus source metadata, and imports as a production runtime artifact. By default it also requests a workspace/path assignment for the current directory; pass assignmentScope: "user" or "none" to skip assignment and use preference/assignment tools later. The admin Skills Catalog UI can browse Vercel, Skillta, and Design Docs sources and unzip archives in the browser; the plugin keeps generic artifact tool naming because the same backend artifact flow supports both SKILL and DESIGN_DOC.

GLOBAL_CONTEXT skills are active context skills and are not meant to be installed per project. PROJECT_INSTALLABLE skills are gallery/installable skills that may be attached globally or to a workspace/path through assignment records; those assignments remain the source of truth for what is active in a catalog response.

EDITOR workspace init flow

Use opencode_wizard_init to bootstrap a repository workspace without reading project instruction files:

  1. Call without confirm to get a non-mutating preview with detected git root/remote/directory, suggested workspace name/slug, ACTIVE PROJECT_INSTALLABLE skills, selected/missing skills, questionBlock, and a suggested follow-up call.
  2. Choose skillSlugs or set assignAllSkills: true; if no skills are selected, even confirm: true returns needs_input and does not mutate.
  3. Rerun with confirm: true to create or resolve the workspace, persist the repo-to-workspace slug mapping, and bulk assign selected skills as ACTIVE PATH assignments using scopePath (default current directory path) and includeChildren (default true).

Pi exposes the same flow as wizard_init.

EDITOR workspace update flow

Use opencode_wizard_update after init to reconcile an existing workspace without destructive changes:

  1. Call without confirm to resolve the existing workspace by slug/learned mapping/repository URL and preview current matching skills, missing assignable skills, unavailable assignments, different-scope assignments, questionBlock, and a suggested follow-up call.
  2. Choose missing additions with skillSlugs or set assignAllSkills: true; if nothing new is selected, even confirm: true returns no_changes/needs_input and does not mutate.
  3. Rerun with confirm: true to add only selected missing ACTIVE PROJECT_INSTALLABLE skills as ACTIVE PATH assignments for scopePath and includeChildren; existing assignments are never removed or deactivated.

If no existing workspace resolves, the tool returns needs_init and points the caller to opencode_wizard_init. Pi exposes the same flow as wizard_update.

Release flow

  1. Bump version in plugins/opencode-wizard/package.json.
  2. Run npm run plugin:release:check from the repo root.
  3. If you are following the repo release-tag convention, create Git tag plugin-opencode-wizard-v<version>.
  4. Push the release commit/tag so GitLab can run the shared npm public publish job.

The CI publish job comes from ci/templates/node/npm-publish-public.yml, stays manual on the repo deploy stage, runs from plugins/opencode-wizard via APP_ROOT, runs npm run release:check including npm pack --dry-run, deletes the inherited @aexol GitLab registry override, packs the exact release tarball with npm pack, and publishes that tarball with npm publish --provenance --access public --registry https://registry.npmjs.org/ ./*.tgz.

GitLab provides a SIGSTORE_ID_TOKEN (aud: sigstore) for npm provenance, and the packed *.tgz is retained as a 30-day job artifact. The current flow still requires the existing NPM_AUTH_TOKEN; npm trusted publishing for GitLab would be the stronger future option once configured because it can remove the long-lived npm token. After release, npm audit signatures from a throwaway install is an optional registry verification check.