clone

a hermes agent plugin for openspec: tools for spec workflows and a dashboard tab for browsing changes and specs

main
hermes-openspec / docs / layers.md
layers.md 7.2K rendered
1# Layer Architecture23The OpenSpec plugin has four layers that coexist by design. They serve4different audiences and return different data shapes. Understanding the5boundaries prevents "fixing" the duplication by rewriting one layer to6use another.78## Layers910```11┌─────────────────────────────────────────────────────────────┐12│ Skills (11 upstream workflow prompts) │13│ openspec-propose, openspec-apply-change, etc. │14│ Agent auto-loads when user intent matches description. │15│ Skills instruct agent to run openspec CLI commands. │16└─────────────┬───────────────────────────────────────────────┘17 │18 ▼19┌─────────────────────────────────────────────────────────────┐20│ CLI interface (two paths, same binary) │21│ │22│ openspec_cli tool terminal tool │23│ ├─ Gated by check_fn ├─ Always available │24│ ├─ JSON output parsed ├─ Raw stdout │25│ └─ Discoverable in tool └─ Skills use this by default │26│ list │27└─────────────┬───────────────────────────────────────────────┘28 │29 ▼30┌─────────────────────────────────────────────────────────────┐31│ openspec CLI binary │32│ (installed separately via npm, not part of plugin) │33└─────────────────────────────────────────────────────────────┘3435┌─────────────────────────────────────────────────────────────┐36│ Plugin tools (19 existing + openspec_cli = 20) │37│ openspec_context, openspec_show, openspec_spec_diff, etc. │38│ Different JSON shapes than CLI. │39│ Used for: ad-hoc agent queries, dashboard backend. │40│ NOT used by: upstream skills (they call CLI directly). │41└─────────────────────────────────────────────────────────────┘4243┌─────────────────────────────────────────────────────────────┐44│ Dashboard │45│ Board, spec browser, change detail │46│ Reads from filesystem + git, not from CLI or plugin tools. │47└─────────────────────────────────────────────────────────────┘48```4950## Why skills don't use plugin tools5152The upstream OpenSpec skills are structured prompts that instruct the agent53to run `openspec` CLI commands directly:5455```bash56openspec new change "<name>"57openspec status --change "<name>" --json58openspec instructions apply --change "<name>" --json59```6061The CLI returns JSON with fields like `applyRequires`, `artifacts`,62`contextFiles`, `actionContext`, and `planningHome`. The skill prompts63parse these fields to drive the workflow.6465Our plugin tools wrap a subset of the CLI but return **different JSON66shapes**. For example:6768| CLI output | Plugin tool output |69|---|---|70| `openspec status --json` → `{changeName, schemaName, artifacts, applyRequires, planningHome, actionContext}` | `openspec_status` → `{ok, change, status, counts}` |71| `openspec instructions apply --json` → `{contextFiles, state, progress, tasks, instruction}` | `openspec_instructions` → `{ok, artifact, instructions}` |7273Rewriting skills to use plugin tools would require modifying every prompt74to match our shapes — a permanent sync burden with no value gained. The75upstream prompts are the product.7677## When to use what7879| You want to… | Use |80|---|---|81| Follow a workflow (propose, apply, verify, archive) | **Skills** — the agent loads them automatically when intent matches |82| Run a CLI command with raw JSON output | **`openspec_cli`** tool — gated, discoverable, parses JSON |83| Run a CLI command via shell pipeline | **`terminal`** tool — always available, raw stdout |84| Query a change/spec without the CLI | **Plugin tools** (`openspec_context`, `openspec_show`, `openspec_spec_diff`, etc.) — filesystem-backed, work without the CLI binary |85| Browse changes and specs visually | **Dashboard** at `/openspec` |8687## Skill list888911 skills bundled from upstream OpenSpec CLI v1.4.1:9091| Skill | Workflow | Profile |92|---|---|---|93| `openspec-propose` | propose | core |94| `openspec-explore` | explore | core |95| `openspec-apply-change` | apply | core |96| `openspec-archive-change` | archive | core |97| `openspec-new-change` | new | expanded |98| `openspec-continue-change` | continue | expanded |99| `openspec-ff-change` | ff | expanded |100| `openspec-verify-change` | verify | expanded |101| `openspec-sync-specs` | sync | expanded |102| `openspec-bulk-archive-change` | bulk-archive | expanded |103| `openspec-onboard` | onboard | expanded |104105Skills are generated by `openspec init --tools claude` and bundled106unmodified. The `generatedBy` version in each skill's frontmatter shows107which OpenSpec version produced the content.108109## Regenerating skills110111When upstream OpenSpec updates the workflow prompts:112113```bash114# 1. Set all workflows in openspec config115python3 -c "116import json117c = json.load(open('~/.config/openspec/config.json'.replace('~', __import__('os').path.expanduser('~'))))118c['profile'] = 'custom'119c['workflows'] = ['propose','explore','new','continue','apply','ff','sync','archive','bulk-archive','verify','onboard']120json.dump(c, open(c_path := __import__('os').path.expanduser('~/.config/openspec/config.json'), 'w'), indent=2)121"122123# 2. Generate into a temp dir124mkdir -p /tmp/opsx-regen && cd /tmp/opsx-regen125openspec init . --tools claude126127# 3. Copy into the plugin128cp -r .claude/skills/openspec-* /path/to/hermes-openspec/skills/129130# 4. Restore core profile131openspec config profile core132```133134## Long-term: Hermes adapter upstream135136The ideal solution is contributing a Hermes adapter to the OpenSpec CLI's137command-generation system (in `dist/core/command-generation/adapters/`).138This would let `openspec init --tools hermes` generate skills directly into139the plugin structure. Until then, the manual regeneration above is140mechanical and infrequent.