JSPM

  • Created
  • Published
  • Downloads 834
  • Score
    100M100P100Q114587F
  • 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

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, and opencode_wizard_status are always exposed by the plugin. Missing auth, forbidden role, backend, or catalog problems are reported by tool output/status metadata instead of hiding these shared tools; only opencode_wizard_editor_create_or_update_skill, opencode_wizard_editor_publish_skill, and opencode_wizard_artifact_import stay editor-only.

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 the imported backend artifact becomes the runtime authority. 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.

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.