Repository navigation
Releases: Expert-Vision-Software/opencode-architect
Release list
v1.1.0
Added
-
statusnow resolves the effective version a session would load, per scope, instead of echoing the manifest version. For each scope it reports the config file holding the registration, the raw entry as written (name@latest, a pinned spec, a{ package }object, or a path/file://form), and the resolved source on disk — an npm spec to OpenCode's package cache ($XDG_CACHE_HOME/opencode/npm, falling back to~/.cache/opencode/npm) with the version read from that copy'spackage.jsonand the copy's age as a staleness hint, a path entry to the package checkout viaPluginEntryResolver.packageRoot— and closes with an effective verdict that annotates a double-scope registration (should load: 1.0.0 (cache copy, local + global; both scopes register — double-load)) plus warnings for that double-load, a manifest/resolved version mismatch, a missing or incomplete cached copy, and an unparseable config. The verdict answers from the strongest source available: a resolved copy on disk, else the registration spec (a pinned exact version answers directly;@latestanswers with the published version under--online; ranges stayunresolved), else the manifest version. A manifest without a live registration reports unregistered: the report answers what would load, not what was once installed. New--onlinequeries the npm registry for every registered package — the name comes from the entry, or from the checkout'spackage.jsonfor path-form registrations — and prints the published latest per scope (npm-latest=<version>, also, latest <version>on the verdict), flagging staleness with warn-and-continue on network failure. New--path <dir>resolves against another project directory; both flags are status-only and rejected elsewhere.statusremains read-only. Resolution lives in the newStatusReporter(src/status-reporter.ts) oversrc/loaded-version.ts,src/config-entries.ts, andsrc/registry-version-checker.ts, with entry classification unified insrc/entry-spec.ts;Installeris install/uninstall/cache only and exposesmanifestAt()in place of the retiredstatus()/StatusOutcome. The generated-package templates (registration,plugin-entry,installer,cli) gain the same resolution so packaged extensions inherit it. -
Path-form plugin-entry recognition (the
aurelia-expert@db0736elesson, issue #3): the newsrc/plugin-entry.tsandtemplates/plugin-entry.template.txtresolve afile://URL or filesystem config entry to a package bypackage.jsonname. Registration-scope detection (templates/registration.template.txt) and the surgical config editor (src/plugin-config.ts,templates/plugin-config.template.txt) now count a live path-form entry as registered, so installation never adds a duplicatename@latestentry beside it. The packager and publisher template maps gainedsrc/plugin-entry.ts, and conformance-checklist items B2 and C1 gained the rule.
Changed
- Path-form resolution refinements from the code review: relative path entries resolve against the config file's directory (facts §7) instead of the process working directory;
package.jsonname matching is case-insensitive on Windows in code, as the docs already claimed; resolution memoization is an unbounded map keyed by resolved path;src/plugin-entry.tsis byte-identical to its template again, and the suite gainssrc/plugin-name.ts(byte-identical totemplates/plugin-name.template.txt), both enforced by a new byte-sync test. The registration/config-editor "name match, then path resolve" shape is deduplicated into one shared predicate per file, and the four array fields collapse into keyed records.
Fixed
agents/opencode-plugin-engineer.mdreferenced a nonexistentfilterOurEntries; it now names the real de-dup path (PluginConfigEditor.ensurePluginEntry's zero-write no-op). Historical note: commit6308389was labeleddocs:but also flipped test expectations (the v2 fixture dropped itspluginskey).
v1.0.0
Changed
- Breaking: The package targets the OpenCode v2 line only (ADR-0012). v2 replaced the extension SDK — a v1 plugin implementation does not run under a v2 host — and a dual-target package would keep a dead code path alive while forcing the teaching surface (our actual product) to serve two vocabularies at once. No dual entrypoint and no v1 host support; consumers on v1 hosts must stay on a pre-1.0 release. Superseding notes land on ADR-0010 and ADR-0011 — their structural rules survive under the v2 contract.
- Breaking: The plugin runtime is ported to the v2 Effect-first plugin API (issue #25). The entry default-exports a plugin definition (
Plugin.define({ id, effect })) built against@opencode/plugin/effect; agents register through the agent-domain transform, skills and commands through their own domain transforms, and the external-directory allow is re-derived as a permissionevaluatehook (the v1permission-registraris gone). Prompt-path rewriting, at-most-once advisories, and the startup non-interference invariant are preserved. - Breaking: The entire guidance suite is rewritten in place to v2 facts (issue #28): references, worked one-shots, and the conformance checklist now teach the v2
pluginsregistration key, Effect-first plugin definitions, the hook-family map, ruleset permissions, plugin-registered tools with JSON-Schema arguments, and v2 config/agent/command/skill/MCP shapes. No v1 archive ships — git history is the archive — and v1 names appear only inside explicit v1→v2 migration mappings. - Breaking: All ten agent definitions are updated to v2 (issue #30): the packager and publisher emit v2-native
plugins-key registration snippets and consumer instructions; the tool-builder pivots to plugin-registered tools with a v1 tool-file port path; the plugin-engineer teaches Effect-first authoring and the hook-family map; the extension-auditor inventories and judges v2 targets. - Breaking: Generated packages are v2-native and Effect-first (issue #29): the plugin-entry template renders
Plugin.definewith a never-throw effect, package manifests declareexports["./server"], the registration/manifest templates read and write thepluginskey, and the installer follows the v2 npm cache location. - Installer and config machinery write v2-native registrations and tolerate legacy v1
pluginentries read-only with an upgrade advisory — never migrated silently, never written back (issue #26). Manifest gating, registration-scope detection, the zero-write no-op, partial-cache-artifact detection, and the copy-mode refusal for code-backed packages are preserved. - Repo content is v2-consistent: README, CONTRIBUTING, and AGENTS.md; the domain glossary gains the v2 vocabulary (plugin registration key, plugin definition shape, tool registration).
Added
- One-shot consumer v1→v2 upgrade (issue #31): the bundled
opencode-v2-upgradeskill and the/upgrade-opencode-v2slash command, both registered at load. Say "upgrade my plugin/extensions package to opencode v2" and the suite inventories the extensions, ports v1 plugin code to the Effect-first v2 API, ports v1 file-based tools to plugin-registered tools, rewrites consumer configs to v2-native keys, and closes with a report recommending v2 capabilities worth adopting (richer session hooks, plugin RPC, TUI plugins, MCP Code Mode, saved approvals). It no-ops byte-for-byte on already-v2 projects, skips consumer-modified files by hash, and never touches the OpenCode application installation. docs/reference/opencode-v2-facts.md(issue #24): the verified-facts record for opencode v2.0.23 — every API fact the suite teaches traced to a pinned source snapshot, with doc-vs-source contradictions adjudicated.- V2 verification harness (issue #27):
tests/v2-host.test.tsloads the built package entry the way a v2 host does — real@opencode/pluginEffect activation, registrations audited against@opencode/schemaAgent.Info(all ten agents, permissionevaluatehook) — andtests/fixture-config-schema.test.tsvalidates every produced fixture config against the pinnedConfig.Info; a dedicatedV2 verification harnessCI job gates both. - Docs-fact gate (issue #28):
tests/docs-fact-gate.test.tsfails the build when a known-false v1 claim re-entersreferences/or a changed fact is not cited to the verified-facts record. CONTRIBUTING.md: the v2 fact policy, the gates, and the Effect-first house style.
Fixed
- Registration loss under v2:
package.jsondeclaresexports["./server"]pointing at the package entry. Without it, server-kind resolution depended on the root-index fallback, which is dead on Bun 1.3.x (ResolveMessageis not anError, so the fallback's catch never fires) and the plugin was disabled at the entry stage; with the export declared, resolution is deterministic on every observed runtime. - Windows test suite (issue #36): cache-removal and tarball tests pass on Windows — deterministic removal-failure injection through an
rmseam and win32-safe tarball root resolution.
v0.9.2
Added
- Conformance checklist E4, root holds only the entry (ADR-0011):
index.tsis the only TypeScript file at the package root, every other module lives undersrc/; a legacy root-levelplugin.tsis recognized during merge and migration but is non-conformant for built or audited packages; the packager self-audit gate verifies the root surface docs/agents/release.md: the release flow is tag push only —npm run releasetags the head commitv<version>(version read frompackage.json) and pushes; CI validates the changelog section and publishes with provenance
Changed
- Breaking:
plugin.tsmoved tosrc/plugin.ts— in this package and in generated packages (hook template lands atsrc/plugin.ts,index.tsre-exports./src/plugin.ts, templatefileswhitelists dropplugin.ts); templates resolve package-root resources via../fromsrc/; packager, publisher, architect, and auditor instructions updated releasenpm script no longer bumps the version or publishes locally
v0.9.1
Added
- Conformance checklist E4, root holds only the entry (ADR-0011):
index.tsis the only TypeScript file at the package root, every other module lives undersrc/; a legacy root-levelplugin.tsis recognized during merge and migration but is non-conformant for built or audited packages; the packager self-audit gate verifies the root surface docs/agents/release.md: the release flow is tag push only —npm run releasetags the head commitv<version>(version read frompackage.json) and pushes; CI validates the changelog section and publishes with provenance
Changed
- Breaking:
plugin.tsmoved tosrc/plugin.ts— in this package and in generated packages (hook template lands atsrc/plugin.ts,index.tsre-exports./src/plugin.ts, templatefileswhitelists dropplugin.ts); templates resolve package-root resources via../fromsrc/; packager, publisher, architect, and auditor instructions updated releasenpm script no longer bumps the version or publishes locally
v0.9.0
Added
- Conformance checklist E4, root holds only the entry (ADR-0011):
index.tsis the only TypeScript file at the package root, every other module lives undersrc/; a legacy root-levelplugin.tsis recognized during merge and migration but is non-conformant for built or audited packages; the packager self-audit gate verifies the root surface docs/agents/release.md: the release flow is tag push only —npm run releasetags the head commitv<version>(version read frompackage.json) and pushes; CI validates the changelog section and publishes with provenance
Changed
- Breaking:
plugin.tsmoved tosrc/plugin.ts— in this package and in generated packages (hook template lands atsrc/plugin.ts,index.tsre-exports./src/plugin.ts, templatefileswhitelists dropplugin.ts); templates resolve package-root resources via../fromsrc/; packager, publisher, architect, and auditor instructions updated releasenpm script no longer bumps the version or publishes locally
v0.8.1
Fixed
- v0.8.0 failed to load in every consumer session: the package entry module re-exported the named
OpencodeArchitectPluginclass, and OpenCode's loader invokes every function-valued entry export as a plain plugin factory — calling a class withoutnewaborts the whole plugin (Cannot call a class constructor OpencodeArchitectPlugin without |new|in the session log) and no agents register.index.tsnow exports onlydefault; the class stays importable fromplugin.tsfor tests (ADR-0010)
Added
- Entry-module regression test:
tests/entry-exports.test.tsimports the real entry and asserts the opencode contract — nothing besidesdefaultis exported anddefaultis callable withoutnew - Conformance checklist E3, entry module default-only: generated packages are audited against the same rule (their templates already emit default-only entries); E3 joins the hard non-conformance set
v0.8.0
Added
- Packager deployment-target choice: the packager first establishes the repo root (
git rev-parse --show-toplevel, never the.opencode/directory) and resolves every source and target path from it; a generated package lays down in the current workspace root by default (files merged with consent, structural conflicts routed toopencode-plugin-engineer, sibling../opencode-<name>/recommended only on explicit request or extensive merges) or in a sibling directory on request - Mandatory frontmatter double-quoting (checklist D6): every frontmatter property value in every generated asset —
SKILL.md, commands, agent definitions — is enclosed in double quotation marks (bare values non-conformant; native booleans/numbers excepted); rule carried in the skills/commands/agents references, the skill-structure template, and the three creator agents - Generated packages ship a working CLI surface at packager time:
binentry (<package> → src/cli.ts),check/testscripts,src/installer.ts+src/cli.tscreated from templates,runCli(argv)export, and anindex.tsdispatch shim — so everybunx <package> ...advisory resolves before any publishing step - Promoted-source retirement (checklist D9): after packaging
.opencode/extensions, the packager establishes a live config reference to the package (surgicalplugin/skills.pathswrite with consent), triggers and verifies the scope payload, then — with a printed list and explicit user confirmation — removes the promoted originals per item; the end state leaves.opencode/holding only the config file plus hook-managed payload and manifests (sourcepackage.json, lockfile, andnode_modules/always removed, unrelated extensions untouched), and it never deletes with no reference in place or the whole.opencode/directory - Packager self-audit gate: before reporting done, the packager verifies the actual tree — exact file inventory (
src/module split),plugin.tsas the thin hook only (monolith pattern is a structural failure), package.jsonbin/files/content/scripts, single-line byte-for-byte badge row, D6 frontmatter quoting,bun test+bunx tsc --noEmitgreen, and the retirement end state — and fixes misses by rebuilding from templates; checklist D7 now fails multi-line or hand-rolled badge rows - Generated packages inherit the suite's cache hygiene, self-scoped (checklist A6): the installer template prunes its own
@latest,@<version>, and untagged cache copies on every install (best-effort warn-and-continue, including no-ops); the generated CLI template gains a self-onlyclear-cachesubcommand (no--package/--all); the generated load-time failure advisory suggestsbunx <pkg> clear-cacheinstead of manual removal; the conformance checklist, packager, and publisher instructions require generated output to carry it; regression coverage asserts each template behavior clear-cacheCLI subcommand (manual-only, never invoked at load): with no flags it removesopencode-architectand everyopencode-architect@*copy from OpenCode's package cache ($XDG_CACHE_HOME/opencode/packages, falling back to~/.cache/opencode/packages).--package <name>removes<name>and every<name>@*;--allremoves the whole OpenCode cache directory; both broad modes require--yes, are mutually exclusive, and unsafe package names (path separators,..) are rejected.--dry-runlists what any mode would remove without deleting. Idempotent — nothing cached is a success — and removal failures warn without failing the commandinstallprunes this package's stale copies from OpenCode's package cache ($XDG_CACHE_HOME/opencode/packages, falling back to~/.cache/opencode/packages):opencode-architect,opencode-architect@latest, andopencode-architect@<installed version>are removed on every install invocation, including no-ops, so OpenCode re-fetches the just-installed version on next start. Pinned versions and other packages' cache dirs are preserved; removal failures warn without failing the install, and cleared paths are reported- Conformance checklist items for the content-based deployment plan (ADR-0008): surgical config writes (B5), zero-write registration no-op (B6), content declaration present and consistent (E1), and binary mode enforcement (E2); E1–E2 and B5–B6 join the hard non-conformance set and the auditor's conformance review covers section E
- Plugins and config references document the allowed config patterns (including global
config.json), the repo-rootopencode.jsonccreate-default, and the surgical-writer rule
Fixed
plugin-local.template.txtread the package version from the parent of the package dir (${import.meta.dirname}/../package.json); corrected to the package root, matching plugin.ts's actual location
Changed
- Packager README badge row is now byte-for-byte the publisher 4b markup: substituting custom badges ("Bun tested", "TypeScript", hand-rolled variants) is explicitly D7 non-conformant
- Breaking: generated packages use package-root content directories —
skills/<name>/,commands/,agents/sit at the package root with noassets/intermediary (ASSET_LAYOUT_DIR = "."), aligning generated repos with skills.sh-style root-skills/scanners; legacyassets/-wrapper packages remain recognized by the installer, checklist, auditor, and publisher - Generated
package.jsonfileslists the shipped content directories (skills,commands, plusagents/plugins/tools/srcas present) instead ofassets - Breaking:
installis now a registration manager (plugin install is the only mode for this code-backed package, per ADR-0008, superseding ADR-0004): the CLI ensures thepluginentry in the target scope's config file via the surgical editor — comments and formatting preserved, unparseable configs abort untouched — and writes a generalized manifest (version, mode, plugin entry, target config file) at the scope base. A matching manifest with the entry present is a zero-write no-op.--mode copyis refused with an explanatory error;--forcenow re-registers and rewrites the manifest instead of removing the entry - Legacy copy installs migrate automatically on install: the old manifest's file list is removed exactly, with a printed notice, before the plugin entry is added
uninstallsurgically removes the plugin entry (config formatting preserved) plus the manifest and any residual copy payload — manifest-gated, or a known-filenames sweep ofagents/andopencode-architect/when no manifest exists;statusreports mode, version, and the config file holding the registration- Generalized manifest schema covers copy mode too, with a single
content-hashproperty (folder-hash) for copy-installed payloads - Nothing changes at runtime: the plugin already registers the agents from the package and resolves reference paths at load
v0.7.1
Fixed
permission-registrar.tsmissing from the published tarball (package.jsonfiles):index.tsimports it at load, so npm-installed copies of 0.7.0 failed at startup
Added
- Tarball contents regression test:
npm pack --dry-runoutput must cover everyfileswhitelist entry and nothing else — the same guard the conformance checklist's D4 mandates for published packages prepublishOnlyscript running typecheck and tests beforenpm publish
Changed
- Conformance-drift instruction gap closure: checklist amendments (C1 directory-identity and unparseable-candidate clauses, B4 advisory contract, new A5 loud asset absence, D8 consumer snippet
plugin-key validity),.jsonc-lenient registration/installer templates with loud asset-absence handling, auditor execution and criteria-version requirements,plugin(singular) key across packager/publisher consumer snippets
v0.7.0
Fixed
- Repeated
external_directorypermission prompts when agents read bundled references in plugin install mode: the load-timeconfighook now registers an in-memory allow scoped to the package's ownassets/*directory, preserving existing rules and respecting an explicit global deny (#11)
v0.6.0
Added
- Startup non-interference rules, recorded in ADR-0007: load-time hooks never throw — failures degrade to a warning plus one advisory so OpenCode always launches; hard errors stay CLI-only
- npm plugin loading mechanics section in the plugins reference: cache-dir resolution,
import.meta.dirnamesemantics, error-handling and timeout behavior, config-format and precedence rules (verified against the OpenCode source) - Conformance checklist items: B4 hooks-never-throw, D4 cache-rot advisory naming the exact cache directory and
npm pack --dry-runtarball verification
Changed
- Plugin-engineer agent: startup non-interference section — wrap load-time installation in try/catch, detect registration in both
opencode.jsonandopencode.jsonc, treat absent assets as a partial npm cache artifact with a removal advisory plugin-local.template.txt: config-hook installation wrapped in try/catch (load-bearing); load-bearing note covers format-tolerant scope detection- Conformance checklist: C1 requires both config extensions, D3 adds
.jsonc-registration and hook-degradation regression tests, verdict scale includes B4 - Glossary: Startup non-interference, Partial cache artifact