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"]./server→dist/server.js./tui→dist/tui.jspi.extensions: ["./dist/pi.js"]./pi→dist/pi.js- no generated runtime skill directory is published; the plugin stays fetch-only at runtime
- native OpenCode
skills.urlsis 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-runPublished 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@latestPi 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_status→opencode_wizard_statuswizard_catalog_fetch→opencode_wizard_catalog_fetchwizard_artifact_fetch→opencode_wizard_artifact_fetchwizard_artifact_preference_set→opencode_wizard_artifact_preference_setwizard_published_skills_fetch→opencode_wizard_published_skills_fetchwizard_published_skill_preference_set→opencode_wizard_published_skill_preference_setwizard_report_issue→opencode_wizard_report_issue
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; only opencode_wizard_editor_create_or_update_skill, opencode_wizard_editor_publish_skill, and opencode_wizard_artifact_import 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:
- Draft the complete
SKILL.mdmarkdown content in chat or another editor. - Call
opencode_wizard_editor_create_or_update_skillwithmarkdownContentand optionaldirectory. - Use
opencode_wizard_artifact_fetchwithartifactKind: "SKILL"or compatibilityopencode_wizard_published_skills_fetchto 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.
Release flow
- Bump
versioninplugins/opencode-wizard/package.json. - Run
npm run plugin:release:checkfrom the repo root. - If you are following the repo release-tag convention, create Git tag
plugin-opencode-wizard-v<version>. - 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.