@skill-map/cli 0.71.0 → 0.73.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -276,8 +276,8 @@ the `__PROVIDER__` token and skip kinds the provider does not claim.
276
276
  `rm -rf .skill-map`.
277
277
  2. Lay the portfolio boot (Express skeleton + handbook):
278
278
  `fixtures.js lay portfolio --only "AGENTS.md,server.js,package.json,public/index.html" --provider <provider> --lang <lang>`.
279
- The harness members (`CLAUDE.md`, `content-editor`, the docs) are
280
- laid by their own chapters.
279
+ The harness members (the entry pointer, `content-editor`, the docs)
280
+ are laid by their own chapters.
281
281
 
282
282
  The tester runs `sm init` in the first chapter. (Later campaign
283
283
  parts use `preflight: seed`; `portfolio-init` is Part 1's flavour,
@@ -19,6 +19,7 @@
19
19
  "portfolio": [
20
20
  "AGENTS.md",
21
21
  "CLAUDE.md",
22
+ "README.md",
22
23
  "server.js",
23
24
  "package.json",
24
25
  "AGENTS.sm",
@@ -269,8 +269,15 @@ A skill-map project reads its files through exactly ONE active lens
269
269
  | `claude` | `.claude/` (agents, commands, skills) | agent, command, skill, markdown| `/` invokes, `@` mentions, refs| `.claude/` | stable | rich |
270
270
  | `codex` | `.codex/agents/*.toml` + `.agents/skills/`| agent (TOML), skill, markdown | `$` invokes, `@` file-refs, refs| `.codex/` | beta | rich |
271
271
  | `antigravity` | `.agents/skills/` + `.agent/workflows/` | skill, workflow, markdown | `/` invokes, `@` file-refs, refs | `.agent/workflows/`| beta | basic |
272
+ | `opencode` | `.agents/skills/` (basic scope) + `.opencode/` | skill, markdown | refs only | `.opencode/` | beta | basic |
272
273
  | `agent-skills` | `.agents/skills/` | skill, markdown | refs only | `.agents/` | stable (default) | basic |
273
274
 
275
+ `opencode` is the one rich-capable lens on the basic track: the OpenCode product
276
+ has `agent` + `command` kinds and `/`-invocation, but its tutorial teaches only
277
+ the shared open-standard `.agents/skills/` skills + markdown references (its
278
+ agents / commands are a deliberate out-of-scope simplification here; the real
279
+ OpenCode lens still classifies them in a live project).
280
+
274
281
  `core/markdown` classifies every orphan `.md` under whatever lens is
275
282
  active; it is the universal base, never a selectable lens.
276
283
 
@@ -282,7 +289,7 @@ active; it is the universal base, never a selectable lens.
282
289
  (skills) and `@`-FILE references (Codex's `@` is a file picker, it cannot
283
290
  mention an agent by name, and `/` is a Codex built-in command, not a skill
284
291
  invocation). Both also use markdown references.
285
- - **basic** (`agent-skills`, `antigravity`): the open-standard family,
292
+ - **basic** (`agent-skills`, `antigravity`, `opencode`): the open-standard family,
286
293
  built on `skill` + `markdown` and wired with **markdown references**
287
294
  (`[text](path)`), the one connection the Agent Skills standard
288
295
  documents. They diverge on what Antigravity bolts on top of the
@@ -311,14 +318,19 @@ built-in command, not a skill invocation).
311
318
  `provider = codex`, `track = rich`.
312
319
  - else a `.agent/workflows/` dir present → `provider = antigravity`,
313
320
  `track = basic`.
321
+ - else a `.opencode/` dir present → `provider = opencode`,
322
+ `<provider_dir> = .agents/skills`, `track = basic` (OpenCode joins the
323
+ open standard for the tutorial; its `.opencode/` marker rides on top of
324
+ the shared `.agents/skills/` skill home, like `.codex/` and
325
+ `.agent/workflows/` do).
314
326
  - else skill under `.claude/skills/sm-tutorial/` → `provider = claude`,
315
327
  `<provider_dir> = .claude`, `track = rich`.
316
328
  - else skill under `.agents/skills/sm-tutorial/` → `provider = agent-skills`,
317
329
  `<provider_dir> = .agents/skills`, `track = basic`.
318
- **Lens precedence for codex / antigravity**: both adopt the open
330
+ **Lens precedence for codex / antigravity / opencode**: each adopts the open
319
331
  `.agents/skills/` layout, so the scaffold leaves the vendor marker
320
- (`.codex/` or `.agent/workflows/`) alongside the `agent-skills` marker
321
- (`.agents/`). The vendor marker WINS: `sm init` resolves `codex` /
332
+ (`.codex/`, `.agent/workflows/`, or `.opencode/`) alongside the
333
+ `agent-skills` marker (`.agents/`). The vendor marker WINS: `sm init` resolves `codex` /
322
334
  `antigravity` outright with no prompt (the `.agents/` open default only
323
335
  competes when no vendor marker is present). So the codex book runs
324
336
  exactly like claude, `sm init` then `sm`, with no lens prompt and no
@@ -289,7 +289,7 @@
289
289
  {
290
290
  "id": "reserved",
291
291
  "title": "A reserved name collides",
292
- "est_min": 2
292
+ "est_min": 4
293
293
  },
294
294
  {
295
295
  "id": "publish",
@@ -209,7 +209,7 @@ parts:
209
209
  - id: setup ; title: "Make it yours and bring it up" ; est_min: 4
210
210
  - id: add-page ; title: "Add a page with your skill" ; est_min: 3
211
211
  - id: broken-ref ; title: "A rename breaks a link" ; est_min: 3
212
- - id: reserved ; title: "A reserved name collides" ; est_min: 2
212
+ - id: reserved ; title: "A reserved name collides" ; est_min: 4
213
213
  - id: publish ; title: "Ship it: run the publish skill for real" ; est_min: 3
214
214
  - id: stability ; title: "Set a node's stability (and the `.sm` sidecar)" ; est_min: 3
215
215
  - id: golive ; title: "Your website, live next to the graph" ; est_min: 3
@@ -12,8 +12,11 @@ model; the per-chapter invocations live in each `part-*.md`.
12
12
  fixtures-data/
13
13
  manifest.json sets, footprints, edits, seeds, providerToken, langs
14
14
  sets/<set>/
15
- shared/ lang-invariant files (code: server.js, package.json, CLAUDE.md)
15
+ shared/ lang-invariant files (code: server.js, package.json)
16
16
  en/ es/ one tree per language (files with translatable prose)
17
+ providers/<provider>/ per-lens overlay (shared/ + en/ es/); e.g. the root
18
+ entry pointer is CLAUDE.md on claude/codex,
19
+ README.md on agent-skills/antigravity
17
20
  edits/<edit-id>/
18
21
  en/ es/ append fragments (one file per fragment)
19
22
  ```
@@ -138,7 +138,7 @@ mv docs/DEPLOY.md docs/DEPLOYMENT.md
138
138
  Wait for confirmation. The harness MUST be clean again before Act C. Mark
139
139
  `broken-ref`: done. Auto-advance to `reserved`.
140
140
 
141
- ## Chapter `reserved` - A reserved name collides (~2 min)
141
+ ## Chapter `reserved` - A reserved name collides (~4 min)
142
142
 
143
143
  **Preparation**: `Write` `<provider_dir>/model/SKILL.md`:
144
144
  ```markdown
@@ -169,7 +169,51 @@ The watcher picks up the new skill. Tell the tester:
169
169
  >
170
170
  > See the `model` node land clean, with no warning?
171
171
 
172
- Wait for confirmation. Mark `reserved`: done. Auto-advance to `publish`.
172
+ Wait for confirmation.
173
+
174
+ **Beat 2, prove the vendor exception by switching the lens (hands-on).** First
175
+ `Write` `<provider_dir>/goal/SKILL.md` (a skill named after the Antigravity
176
+ built-in verb `goal`):
177
+
178
+ ```markdown
179
+ ---
180
+ name: goal
181
+ description: |
182
+ Captures a goal for the site and tracks it to done.
183
+ ---
184
+
185
+ # goal
186
+
187
+ Notes a goal and checks it off when shipped.
188
+ ```
189
+
190
+ The watcher adds it clean (on your open-standard lens `goal` is just a name). The
191
+ agent does NOT touch settings (Inviolable rule #2); the tester drives the
192
+ Settings UI. Tell the tester:
193
+
194
+ > Now let's make that warning real by switching the lens. I added one more skill,
195
+ > `goal`, an Antigravity built-in verb. On your open standard it landed clean,
196
+ > same as `model`.
197
+ >
198
+ > Open **Settings** (the sliders icon, top right) and the **Project** tab. Find
199
+ > **Active provider** and switch it from the open standard to **Google's
200
+ > Antigravity**, then confirm. skill-map clears the old lens's scan, so the Map
201
+ > goes quiet; click the **refresh** button (the sync icon in the topbar) to
202
+ > re-scan under the new lens.
203
+ >
204
+ > Watch the Map: `goal` now wears a **`name-reserved`** warning (under Antigravity
205
+ > `/goal` is a built-in command, so your skill would be shadowed), while `model`
206
+ > stays clean (it is not one of Antigravity's verbs). Same files, different lens:
207
+ > the lens decides what is reserved.
208
+ >
209
+ > Now switch **Active provider** back to the open standard, confirm, and click
210
+ > refresh once more. The warning on `goal` clears, you are back on the neutral
211
+ > standard that reserves nothing.
212
+ >
213
+ > Did the warning appear under Antigravity and clear when you switched back?
214
+
215
+ Wait for confirmation. The lens MUST be back on the open standard before
216
+ continuing. Mark `reserved`: done. Auto-advance to `publish`.
173
217
 
174
218
  ---
175
219
 
@@ -128,8 +128,8 @@ You edit `notes/todo.md` so it becomes the **hub** that points to the other
128
128
  nodes. On this lens there is exactly one connector: the **markdown reference**.
129
129
  A bullet links to another file with `[label](relative/path)`; skill-map reads
130
130
  that as a `references` link and draws an arrow when the target resolves to a
131
- real file. (The rich track also has `/`-invokes and `@`-mentions; the open
132
- standard connects by file links only, and that is all this lens emits.)
131
+ real file. (Wiring everything with file links keeps the harness portable: a
132
+ reference resolves the same way on any runtime that speaks the open standard.)
133
133
 
134
134
  Apply the hub bullets (content lives in `fixtures-data/`). The edit appends
135
135
  three bullets after the `# Pending` heading. Backstage (silent):
@@ -60,13 +60,13 @@ Wait for confirmation. Mark `kickoff`: done.
60
60
  Tell the tester to create the file themselves (their project's file, Inviolable
61
61
  rule #2):
62
62
 
63
- > Create a file called `CLAUDE.md` at the project root with exactly this content:
63
+ > Create a file called `README.md` at the project root with exactly this content:
64
64
  >
65
65
  > ```markdown
66
66
  > See the [handbook](AGENTS.md).
67
67
  > ```
68
68
  >
69
- > Save it. Watch the map: a new `CLAUDE.md` node appears with a `references`
69
+ > Save it. Watch the map: a new `README.md` node appears with a `references`
70
70
  > connector pointing at `AGENTS.md`, solid at 1.00. The markdown link
71
71
  > `[handbook](AGENTS.md)` is a file pointer (the same kind of reference you met
72
72
  > in the prologue), and since the handbook is right there the link resolves with
@@ -117,7 +117,7 @@ Tell the tester:
117
117
  > front of you:
118
118
  >
119
119
  > - **skill**: `content-editor` (does work on your behalf).
120
- > - **markdown**: `AGENTS.md`, `CLAUDE.md`, the two docs (plain notes and
120
+ > - **markdown**: `AGENTS.md`, `README.md`, the two docs (plain notes and
121
121
  > manuals).
122
122
  >
123
123
  > Your lens authors exactly these two; Claude and Codex projects add `agent` and
@@ -188,10 +188,10 @@ Continue the tester message:
188
188
  > - `publish -> content-editor` (the `[content-editor](../content-editor/SKILL.md)` link)
189
189
  > - `publish -> docs/DEPLOY.md` (the `[deploy runbook](../../../docs/DEPLOY.md)` link)
190
190
  >
191
- > One node, three connectors, all references. On a vendor lens (claude/codex) the
192
- > first two would be a `/`-invoke and an `@`-mention; the open standard wires
193
- > everything with file links, and that is all this lens emits. The harness is
194
- > starting to look like a real graph.
191
+ > One node, three connectors, all references. Wiring the whole harness with
192
+ > markdown file links keeps it portable: each reference resolves the same way on
193
+ > any runtime that speaks the open standard. The harness is starting to look
194
+ > like a real graph.
195
195
  >
196
196
  > 💡 Tip: to tidy the layout, click **Re-arrange layout** in the map toolbar.
197
197
  >
@@ -78,7 +78,10 @@ function writeFileEnsuring(abs, content) {
78
78
  * tier, then the per-provider overlay (`providers/<provider>/{shared,<lang>}/`).
79
79
  * The overlay carries the skill-shaped variants of nodes a lens renders
80
80
  * differently (e.g. the `content-editor` agent becomes a skill on
81
- * agent-skills); claude declares no overlay because the base IS its shape.
81
+ * agent-skills). claude is mostly the base shape, but it still carries a tiny
82
+ * overlay for the entry-pointer file: the portfolio root pointer is `CLAUDE.md`
83
+ * (claude/codex overlays) vs `README.md` (agent-skills / antigravity), so it
84
+ * cannot live in the universal base `shared/` tier.
82
85
  */
83
86
  function laySet(manifest, set, o, only = null) {
84
87
  const { kinds } = pdirAndKinds(o);
@@ -297,5 +300,5 @@ function main() {
297
300
  }
298
301
 
299
302
  main();
300
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="9e366749-efd9-5bc5-bba4-41147eabf625")}catch(e){}}();
301
- //# debugId=9e366749-efd9-5bc5-bba4-41147eabf625
303
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="b7c7dad8-e6ce-5918-a25b-41b4e2d13a4c")}catch(e){}}();
304
+ //# debugId=b7c7dad8-e6ce-5918-a25b-41b4e2d13a4c
@@ -7,11 +7,13 @@
7
7
  export const PROVIDER_TOKEN = '__PROVIDER__';
8
8
 
9
9
  export function providerDir(provider) {
10
- // agent-skills, Antigravity and Codex all keep their SKILLS under the
11
- // open `.agents/skills/` layout. (Codex additionally has TOML agents under
12
- // `.codex/agents/`, supplied by the codex overlay's literal paths, not this
13
- // single base dir.)
14
- return provider === 'agent-skills' || provider === 'antigravity' || provider === 'codex'
10
+ // agent-skills, Antigravity, Codex, and OpenCode all keep their SKILLS under
11
+ // the open `.agents/skills/` layout. (Codex additionally has TOML agents
12
+ // under `.codex/agents/`, supplied by the codex overlay's literal paths, not
13
+ // this single base dir. OpenCode is rich-capable but joins the open-standard
14
+ // BASIC track here: the tutorial teaches its shared `.agents/skills/` layer,
15
+ // not its own `.opencode/` agents/commands.)
16
+ return provider === 'agent-skills' || provider === 'antigravity' || provider === 'codex' || provider === 'opencode'
15
17
  ? '.agents/skills'
16
18
  : '.claude';
17
19
  }
@@ -25,6 +27,10 @@ export const PROVIDER_KINDS = {
25
27
  codex: new Set(['skill', 'markdown']),
26
28
  'agent-skills': new Set(['skill', 'markdown']),
27
29
  antigravity: new Set(['skill', 'markdown']),
30
+ // OpenCode is rich-capable (it has agent + command kinds in the product), but
31
+ // its tutorial runs on the BASIC track via the shared open standard, so only
32
+ // skill + markdown are taught here (its agents/commands are out of scope).
33
+ opencode: new Set(['skill', 'markdown']),
28
34
  };
29
35
 
30
36
  export function kindsFor(provider) {
@@ -36,7 +42,8 @@ export function kindsFor(provider) {
36
42
  * kind?" axis (see `_core.md` §Provider detection):
37
43
  * - `rich` (agent + skill + slash + `@`): `claude`, `codex`.
38
44
  * - `basic` (skill + markdown, connected by markdown references): the
39
- * open-standard family `agent-skills`, `antigravity`.
45
+ * open-standard family `agent-skills`, `antigravity`, `opencode`
46
+ * (OpenCode is rich-capable but joins basic via the shared open standard).
40
47
  * The book renders the track's parts; the same lens always resolves to
41
48
  * the same track, so a resumed session never re-derives it.
42
49
  */
@@ -46,13 +53,14 @@ export function trackFor(provider) {
46
53
 
47
54
  /**
48
55
  * The provider whose fixture overlays a given provider reuses. The
49
- * open-standard family (`agent-skills`, `antigravity`) shares one on-disk
50
- * shape (`.agents/skills/`, skill + markdown, connected by markdown
51
- * references), so `antigravity` reuses the canonical `agent-skills`
52
- * overlays rather than duplicating them. Every other provider keys its own.
56
+ * open-standard family (`agent-skills`, `antigravity`, `opencode`) shares one
57
+ * on-disk shape (`.agents/skills/`, skill + markdown, connected by markdown
58
+ * references), so `antigravity` and `opencode` reuse the canonical
59
+ * `agent-skills` overlays rather than duplicating them. Every other provider
60
+ * keys its own.
53
61
  */
54
62
  export function overlayKey(provider) {
55
- return provider === 'antigravity' ? 'agent-skills' : provider;
63
+ return provider === 'antigravity' || provider === 'opencode' ? 'agent-skills' : provider;
56
64
  }
57
65
 
58
66
  /**
@@ -81,6 +89,7 @@ const KIND_DIRS = {
81
89
  codex: { skills: '.agents/skills' },
82
90
  'agent-skills': { skills: '.agents/skills' },
83
91
  antigravity: { skills: '.agents/skills' },
92
+ opencode: { skills: '.agents/skills' },
84
93
  };
85
94
 
86
95
  /**
@@ -135,5 +144,5 @@ export function nodeIdForTokenPath(tokenRelPath) {
135
144
  if (codexAgent) return codexAgent[1];
136
145
  return tokenRelPath;
137
146
  }
138
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="54e1e331-4312-5c77-adc1-287ab9df7502")}catch(e){}}();
139
- //# debugId=54e1e331-4312-5c77-adc1-287ab9df7502
147
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="d231a237-bec6-57bf-a67b-98b9edc47ec9")}catch(e){}}();
148
+ //# debugId=d231a237-bec6-57bf-a67b-98b9edc47ec9