@skill-map/cli 0.67.0 → 0.68.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.
- package/dist/cli/tutorial/sm-tutorial/SKILL.md +16 -8
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/edits/agents-hub/providers/agent-skills/en/agents-hub.md +2 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/edits/agents-hub/providers/agent-skills/es/agents-hub.md +2 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/edits/content-editor-style/providers/agent-skills/en/content-editor-style.md +1 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/edits/content-editor-style/providers/agent-skills/es/content-editor-style.md +1 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/edits/todo-connectors/providers/agent-skills/en/todo-bullet-guideline.md +1 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/edits/todo-connectors/providers/agent-skills/en/todo-bullet-guideline2.md +1 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/edits/todo-connectors/providers/agent-skills/en/todo-bullet-skill.md +1 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/edits/todo-connectors/providers/agent-skills/es/todo-bullet-guideline.md +1 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/edits/todo-connectors/providers/agent-skills/es/todo-bullet-guideline2.md +1 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/edits/todo-connectors/providers/agent-skills/es/todo-bullet-skill.md +1 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/manifest.json +9 -1
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/sets/harness/providers/agent-skills/en/__PROVIDER__/skills/publish/SKILL.md +15 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/sets/harness/providers/agent-skills/es/__PROVIDER__/skills/publish/SKILL.md +16 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/sets/harness/providers/codex/en/__PROVIDER__/skills/publish/SKILL.md +15 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/sets/harness/providers/codex/es/__PROVIDER__/skills/publish/SKILL.md +16 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/sets/master/providers/agent-skills/en/__PROVIDER__/skills/master-agent/SKILL.md +13 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/sets/master/providers/agent-skills/es/__PROVIDER__/skills/master-agent/SKILL.md +14 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/sets/master/providers/codex/en/.codex/agents/master-agent.toml +10 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/sets/master/providers/codex/es/.codex/agents/master-agent.toml +10 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/sets/portfolio/providers/agent-skills/en/AGENTS.md +7 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/sets/portfolio/providers/agent-skills/en/__PROVIDER__/skills/content-editor/SKILL.md +20 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/sets/portfolio/providers/agent-skills/es/AGENTS.md +7 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/sets/portfolio/providers/agent-skills/es/__PROVIDER__/skills/content-editor/SKILL.md +20 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/sets/portfolio/providers/agent-skills/shared/CLAUDE.md +1 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/sets/portfolio/providers/codex/en/.codex/agents/content-editor.toml +19 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/sets/portfolio/providers/codex/es/.codex/agents/content-editor.toml +19 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/sets/prologue/providers/codex/en/.codex/agents/demo-agent.toml +13 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/sets/prologue/providers/codex/en/__PROVIDER__/skills/demo-command/SKILL.md +11 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/sets/prologue/providers/codex/es/.codex/agents/demo-agent.toml +13 -0
- package/dist/cli/tutorial/sm-tutorial/fixtures-data/sets/prologue/providers/codex/es/__PROVIDER__/skills/demo-command/SKILL.md +12 -0
- package/dist/cli/tutorial/sm-tutorial/references/_core.md +101 -48
- package/dist/cli/tutorial/sm-tutorial/references/_manifest.json +174 -0
- package/dist/cli/tutorial/sm-tutorial/references/_manifest.yml +90 -0
- package/dist/cli/tutorial/sm-tutorial/references/part-basic-connect.md +166 -0
- package/dist/cli/tutorial/sm-tutorial/references/part-basic-daily.md +267 -0
- package/dist/cli/tutorial/sm-tutorial/references/part-basic-fundamentals.md +350 -0
- package/dist/cli/tutorial/sm-tutorial/references/part-basic-kickoff.md +140 -0
- package/dist/cli/tutorial/sm-tutorial/references/part-connect-harness.md +6 -4
- package/dist/cli/tutorial/sm-tutorial/references/part-daily-loop.md +21 -26
- package/dist/cli/tutorial/sm-tutorial/references/part-fundamentals.md +10 -5
- package/dist/cli/tutorial/sm-tutorial/references/part-mcp.md +3 -6
- package/dist/cli/tutorial/sm-tutorial/references/part-project-kickoff.md +29 -14
- package/dist/cli/tutorial/sm-tutorial/references/part-settings.md +17 -13
- package/dist/cli/tutorial/sm-tutorial/scripts/fixtures.js +85 -22
- package/dist/cli/tutorial/sm-tutorial/scripts/lib/paths.js +74 -4
- package/dist/cli/tutorial/sm-tutorial/scripts/state.js +22 -6
- package/dist/cli.js +400 -160
- package/dist/conformance/index.js +42 -2
- package/dist/index.js +43 -30
- package/dist/kernel/index.d.ts +28 -5
- package/dist/kernel/index.js +43 -30
- package/dist/ui/chunk-3ANNEMV4.js +499 -0
- package/dist/ui/chunk-3GDWM5VM.js +2 -0
- package/dist/ui/{chunk-5BJGO7GH.js → chunk-3U4QZKU2.js} +4 -4
- package/dist/ui/chunk-3ZAHOYQ7.js +1 -0
- package/dist/ui/chunk-4F53HBGG.js +1845 -0
- package/dist/ui/{chunk-56CBK7LB.js → chunk-6FGV5O5J.js} +1 -1
- package/dist/ui/chunk-7WMT2LX4.js +1 -0
- package/dist/ui/chunk-BJUBDHJR.js +3 -0
- package/dist/ui/{chunk-276RLZR4.js → chunk-BSIR3ADF.js} +14 -14
- package/dist/ui/{chunk-FC22ZJQZ.js → chunk-CG25RHMO.js} +1 -1
- package/dist/ui/chunk-EFSC6SOL.js +3 -0
- package/dist/ui/chunk-EJVWTBMV.js +4 -0
- package/dist/ui/chunk-EZI3BXQN.js +1 -0
- package/dist/ui/{chunk-JZ2YF7EL.js → chunk-GUPPOK7U.js} +8 -8
- package/dist/ui/{chunk-CJURGJTN.js → chunk-HLALESGR.js} +1 -1
- package/dist/ui/chunk-I3I4KHR5.js +2 -0
- package/dist/ui/{chunk-BOVJVOLH.js → chunk-I6ED2OW7.js} +1 -1
- package/dist/ui/chunk-JKPG5PO7.js +375 -0
- package/dist/ui/chunk-KHDWXSGR.js +1 -0
- package/dist/ui/{chunk-HEK4PH5A.js → chunk-KMHXNOFZ.js} +1 -1
- package/dist/ui/chunk-KWT7E2RJ.js +16 -0
- package/dist/ui/{chunk-WHZVGOS3.js → chunk-MQSU6EFZ.js} +1 -1
- package/dist/ui/{chunk-43S72FTV.js → chunk-OGEE252A.js} +1 -1
- package/dist/ui/{chunk-J4J42HJ4.js → chunk-PU5OP5RN.js} +1 -1
- package/dist/ui/{chunk-UTRZTB6V.js → chunk-QVG7J2MP.js} +1 -1
- package/dist/ui/chunk-TQBXK5JN.js +1 -0
- package/dist/ui/chunk-Z7SOKILO.js +2 -0
- package/dist/ui/{chunk-WCABR6TI.js → chunk-ZRJ5ZCFR.js} +1 -1
- package/dist/ui/index.html +2 -2
- package/dist/ui/main-ZYRIR6DB.js +4 -0
- package/dist/ui/styles-VEGETYWD.css +1 -0
- package/package.json +17 -18
- package/dist/ui/chunk-34ZZDYNQ.js +0 -1
- package/dist/ui/chunk-444BFYGR.js +0 -3
- package/dist/ui/chunk-44VNNUSQ.js +0 -2
- package/dist/ui/chunk-4SG4352Z.js +0 -7
- package/dist/ui/chunk-5ITZXW3A.js +0 -1
- package/dist/ui/chunk-7ANZW2OI.js +0 -499
- package/dist/ui/chunk-BJ6X6WBO.js +0 -4
- package/dist/ui/chunk-CZSLV6YD.js +0 -1
- package/dist/ui/chunk-DLYJHLJX.js +0 -2
- package/dist/ui/chunk-LGFABCIA.js +0 -16
- package/dist/ui/chunk-LPDD2DHE.js +0 -369
- package/dist/ui/chunk-P3SNMV4X.js +0 -2
- package/dist/ui/chunk-S4S5ZMXJ.js +0 -3
- package/dist/ui/chunk-VHEFRMK3.js +0 -1
- package/dist/ui/chunk-X6TRIDBI.js +0 -1845
- package/dist/ui/main-V77F2KZX.js +0 -4
- package/dist/ui/styles-I4ULXD3V.css +0 -1
- /package/dist/ui/{chunk-Y2Z26SRI.js → chunk-5RNLC6V4.js} +0 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Part 1 (basic track): The project from zero (step library, `kickoff-*` ids)
|
|
2
|
+
|
|
3
|
+
The campaign turns real here for the **basic track** (the open-standard family:
|
|
4
|
+
`agent-skills`, `antigravity`). After the abstract prologue, the tester starts an
|
|
5
|
+
actual project: a tiny personal **portfolio website**, fully static, served by a
|
|
6
|
+
~15-line Express server, plus the `.agents/skills/` **harness** that maintains
|
|
7
|
+
it. skill-map maps the harness (the `.md` assets and how they reference each
|
|
8
|
+
other); the site itself is plain HTML the harness produces (the daily loop, Part
|
|
9
|
+
3, runs and ships it). This lens authors only **skills** and **markdown notes**,
|
|
10
|
+
and they connect by **markdown references** (`[text](path)`). `pace: per-step`,
|
|
11
|
+
`preflight: portfolio-init`. Shared conventions live in `_core.md`. Narrate with
|
|
12
|
+
`<provider_dir>` = `.agents/skills`.
|
|
13
|
+
|
|
14
|
+
The orchestrator's `portfolio-init` pre-flight (backstage, silent) has already
|
|
15
|
+
laid the bare skeleton before the tester runs `sm init`: `server.js`,
|
|
16
|
+
`package.json`, `public/index.html` (none `.md`, so the scan ignores them), the
|
|
17
|
+
portfolio `.skillmapignore`, and the handbook `AGENTS.md` (the one boot node).
|
|
18
|
+
The chapters grow the harness from there.
|
|
19
|
+
|
|
20
|
+
## Chapter `kickoff` - Start the portfolio (~2 min)
|
|
21
|
+
|
|
22
|
+
**Context**: same `sm init` from the prologue, now on a real project. The map
|
|
23
|
+
shows the project's harness, not throwaway demo nodes.
|
|
24
|
+
|
|
25
|
+
If the prologue (`basic-fundamentals`) ran first here, `portfolio-init` already
|
|
26
|
+
cleared the demo fixture during pre-flight, so the tester sees only the
|
|
27
|
+
portfolio. If anything demo lingers, mention it once and move on.
|
|
28
|
+
|
|
29
|
+
The project carries a `.agents/` marker (the open-standard skill home where the
|
|
30
|
+
tutorial itself lives), so `sm init` auto-detects the `<provider>` lens with no
|
|
31
|
+
prompt. The root `AGENTS.md` is the vendor-neutral handbook, NOT a lens marker.
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
sm init
|
|
35
|
+
sm
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Tell the tester:
|
|
39
|
+
|
|
40
|
+
> This is a real project now: a small **portfolio website**. It's static HTML
|
|
41
|
+
> served by a tiny Express server (`server.js`), and the `.agents/skills/` folder
|
|
42
|
+
> is the **harness** (the helpers that maintain the site). skill-map maps that
|
|
43
|
+
> harness.
|
|
44
|
+
>
|
|
45
|
+
> Run `sm init`, it auto-detects your `<provider>` lens from the `.agents/`
|
|
46
|
+
> folder. Then run `sm` to boot the live UI.
|
|
47
|
+
>
|
|
48
|
+
> Open the URL `sm` printed. You'll see **one node**: `AGENTS.md`, the project's
|
|
49
|
+
> handbook (the operating manual for the site). `server.js`, `package.json` and
|
|
50
|
+
> the HTML under `public/` are not `.md`, so skill-map leaves them out, it maps
|
|
51
|
+
> the harness, not the served files.
|
|
52
|
+
>
|
|
53
|
+
> See the handbook node? Then we start building.
|
|
54
|
+
|
|
55
|
+
Wait for confirmation. Mark `kickoff`: done.
|
|
56
|
+
|
|
57
|
+
## Chapter `manual` - The handbook and an entry pointer (~2 min)
|
|
58
|
+
|
|
59
|
+
**Context**: the first connector on the real project. A project often keeps a
|
|
60
|
+
short entry file that points readers (and tools) at the handbook. On this lens
|
|
61
|
+
that pointer is a plain **markdown link**, the only connector the open standard
|
|
62
|
+
defines, and it is the tester's first real reference here.
|
|
63
|
+
|
|
64
|
+
Tell the tester to create the file themselves (their project's file, Inviolable
|
|
65
|
+
rule #2):
|
|
66
|
+
|
|
67
|
+
> Create a file called `CLAUDE.md` at the project root with exactly this content:
|
|
68
|
+
>
|
|
69
|
+
> ```markdown
|
|
70
|
+
> See the [handbook](AGENTS.md).
|
|
71
|
+
> ```
|
|
72
|
+
>
|
|
73
|
+
> Save it. Watch the map: a new `CLAUDE.md` node appears with a `references`
|
|
74
|
+
> connector pointing at `AGENTS.md`, solid at 1.00. The markdown link
|
|
75
|
+
> `[handbook](AGENTS.md)` is a file pointer (the same kind of reference you met
|
|
76
|
+
> in the prologue), and since the handbook is right there the link resolves with
|
|
77
|
+
> full confidence. It tells anyone (and skill-map) that this file defers to the
|
|
78
|
+
> handbook.
|
|
79
|
+
>
|
|
80
|
+
> Did the connector light up?
|
|
81
|
+
|
|
82
|
+
Wait for confirmation. Mark `manual`: done.
|
|
83
|
+
|
|
84
|
+
## Chapter `first-skill` - The first harness skill (~2 min)
|
|
85
|
+
|
|
86
|
+
Lay the first harness skill (content lives in `fixtures-data/`; the `skill` kind
|
|
87
|
+
exists on every lens, so no skip). Backstage (silent):
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
node .claude/skills/sm-tutorial/scripts/fixtures.js lay portfolio --only "__PROVIDER__/skills/content-editor/SKILL.md" --provider <provider> --lang <lang>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Tell the tester:
|
|
94
|
+
|
|
95
|
+
> I added the first real member of your harness: a skill called `content-editor`
|
|
96
|
+
> (its job is to write the site's pages). A new `skill` node appeared on the map.
|
|
97
|
+
> Right now it stands alone; in the next part we wire it to the handbook and the
|
|
98
|
+
> style guide.
|
|
99
|
+
>
|
|
100
|
+
> 💡 Tip: I create these harness files for you. If you'd like to see what's
|
|
101
|
+
> inside, open `<provider_dir>/content-editor/SKILL.md` in your editor, and feel
|
|
102
|
+
> free to peek at the files I add in the coming chapters too.
|
|
103
|
+
>
|
|
104
|
+
> See the new skill node?
|
|
105
|
+
|
|
106
|
+
Wait for confirmation. Mark `first-skill`: done.
|
|
107
|
+
|
|
108
|
+
## Chapter `real-kinds` - The kinds in context (~2 min)
|
|
109
|
+
|
|
110
|
+
**Context**: the prologue showed this lens's two kinds on abstract demo nodes.
|
|
111
|
+
Now name them on the real project, and add the two markdown docs the harness
|
|
112
|
+
references later (the style guide and the deploy runbook), so the daily loop's
|
|
113
|
+
maintenance beats have something to point at.
|
|
114
|
+
|
|
115
|
+
Lay the two docs (content lives in `fixtures-data/`). Backstage (silent):
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
node .claude/skills/sm-tutorial/scripts/fixtures.js lay portfolio --only "docs/STYLE.md,docs/DEPLOY.md" --provider <provider> --lang <lang>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Tell the tester:
|
|
122
|
+
|
|
123
|
+
> Two more nodes joined the map, both `markdown` (the catch-all kind for `.md`
|
|
124
|
+
> files that are not a skill): `docs/STYLE.md` (the style guide) and
|
|
125
|
+
> `docs/DEPLOY.md` (the deploy runbook). So now you have your lens's two kinds in
|
|
126
|
+
> front of you:
|
|
127
|
+
>
|
|
128
|
+
> - **skill**: `content-editor` (does work on your behalf).
|
|
129
|
+
> - **markdown**: `AGENTS.md`, `CLAUDE.md`, the two docs (plain notes and
|
|
130
|
+
> manuals).
|
|
131
|
+
>
|
|
132
|
+
> Your lens authors exactly these two; Claude and Codex projects add `agent` and
|
|
133
|
+
> `command` kinds on top. Your handbook now has a real harness around it: a
|
|
134
|
+
> `content-editor` skill plus its docs, all on the map.
|
|
135
|
+
>
|
|
136
|
+
> See the skill and the docs in the map?
|
|
137
|
+
|
|
138
|
+
Wait for confirmation. Mark `real-kinds`: done. Last chapter of the part: apply
|
|
139
|
+
§Closing a part (name the part by its title, route back to the menu; do NOT lead
|
|
140
|
+
into the next part from here).
|
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
This is the wiring part. Part 1 grew a small set of standalone nodes around the handbook (the portfolio harness); here the tester turns that scatter of dots into a connected graph: a link checker, a publish command that pulls three pieces together, the handbook becoming a real hub, and a close-up on how sure skill-map is of each connection. `pace: auto-advance` (walk straight into the next chapter once one is marked done), `preflight: seed` (it builds on the portfolio harness from Part 1, reusing the accumulated state when its predecessors are done, no fresh fixture of its own). Shared conventions (tone, provider detection / substitution, the `> ` rendering rule, the per-step cycle) live in `_core.md`; do not restate them here.
|
|
4
4
|
|
|
5
|
+
**Codex deltas (rich track).** When `tutorial.provider == codex`, the bodies below are written in the claude shape; apply per chapter (the `/` invocation and `@` mention both resolve on Codex, so the lessons and the graph are identical, only the kind / path of the `publish` node changes):
|
|
6
|
+
|
|
7
|
+
- `publish`: Codex has no `command` kind, so the tester creates a **skill** at `.agents/skills/publish/SKILL.md` instead of `.claude/commands/publish.md`. The body is the Codex one (same `/check-links` + `@content-editor` + deploy reference); fetch it with `fixtures.js cat harness --file "__PROVIDER__/skills/publish/SKILL.md" --provider codex --lang <lang>`. Tell the tester they are creating a `skill` (one node, three connectors, same as the claude command). The fixture lays no `publish` for codex in this chapter (the tester authors it), so the `cat` is the source.
|
|
8
|
+
- `links`: the `content-editor-style` reference is baked into the Codex content-editor's TOML (`developer_instructions`) at lay time, so the `edit content-editor-style` step is a no-op on Codex, the `content-editor -> docs/STYLE.md` arrow is already drawn from Part 1. Run only `edit agents-hub` and narrate the two `AGENTS.md` arrows; mention the style-guide arrow as already present.
|
|
9
|
+
|
|
5
10
|
## Chapter `check-links` - The link checker (~3 min)
|
|
6
11
|
|
|
7
12
|
**Context**: the harness needs a guard that runs before publishing: a skill that walks every page and checks the internal links resolve. We only create it here (its first standalone `skill` node); the `publish` command in the next chapter is what invokes it.
|
|
@@ -30,8 +35,6 @@ Wait for confirmation. Mark `check-links`: done.
|
|
|
30
35
|
|
|
31
36
|
**Context**: this is the chapter where the graph comes alive. The `/publish` command ties three pieces together in one body: it invokes the link checker, mentions the content editor, and references the deploy runbook. Three connectors light up from a single new node, one per link syntax.
|
|
32
37
|
|
|
33
|
-
On `agent-skills` / Antigravity there is no `command` kind, so skip this whole chapter and fold its purpose into the prose of the next one.
|
|
34
|
-
|
|
35
38
|
Tell the tester to create the file themselves (it is their project's file, Inviolable rule #2). Substitute `<provider_dir>` per `_core.md` in the path you give them. Backstage, get the content: `node .claude/skills/sm-tutorial/scripts/fixtures.js cat harness --file "__PROVIDER__/commands/publish.md" --provider <provider> --lang <lang>`, then render it as a **top-level fenced code block**: at column 0, NOT inside the `> ` blockquote and with NO leading indentation, so the tester's copy keeps every line flush left. The frontmatter fences (`---`) MUST land on column 0. If the block is rendered (or pasted) indented, the opening and closing `---` shift off column 0, the YAML never parses, and the `publish` node loads body-only without its `name` / `description` (`sm check` then warns `frontmatter-malformed`). Present the block below exactly as written.
|
|
36
39
|
|
|
37
40
|
> Create `.claude/commands/publish.md` with exactly this content (the first line is `---`, nothing before it):
|
|
@@ -86,8 +89,7 @@ Wait for confirmation. You MAY use `Read` on the file afterwards to verify it la
|
|
|
86
89
|
|
|
87
90
|
Apply both edits (their content + translation live in `fixtures-data/`).
|
|
88
91
|
The first appends the two hub bullets to `AGENTS.md`; the second adds
|
|
89
|
-
the style-guide reference line to the content-editor (
|
|
90
|
-
so it folds away on `agent-skills`). Backstage (silent):
|
|
92
|
+
the style-guide reference line to the content-editor. Backstage (silent):
|
|
91
93
|
|
|
92
94
|
```
|
|
93
95
|
node .claude/skills/sm-tutorial/scripts/fixtures.js edit agents-hub --provider <provider> --lang <lang>
|
|
@@ -18,11 +18,25 @@ what the tester names their portfolio. Persist the answer with
|
|
|
18
18
|
`state.js set-identity --name "<name>" --tagline "<tagline>"` (it records
|
|
19
19
|
`tester.site_identity` in `tutorial-state.json`).
|
|
20
20
|
|
|
21
|
-
**Provider note (read once).**
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
**Provider note (read once).** This is the rich track; the bodies below are the
|
|
22
|
+
`claude` layout (`.claude/`). The open-standard family (agent-skills /
|
|
23
|
+
antigravity) walks its own `basic-daily` part. **Codex deltas** (when
|
|
24
|
+
`tutorial.provider == codex`): the `content-editor` is a TOML agent at
|
|
25
|
+
`.codex/agents/content-editor.toml`, and Codex has no `command` kind, so
|
|
26
|
+
`publish` is a **skill** at `.agents/skills/publish/SKILL.md`. The `@`/`/`
|
|
27
|
+
connectors all resolve on Codex, so every beat lands the same; only the path /
|
|
28
|
+
kind of those two nodes changes. Per chapter:
|
|
29
|
+
|
|
30
|
+
- `add-page`: invoke the `content-editor` TOML agent via the Task tool (same flow).
|
|
31
|
+
- `broken-ref`: the deploy link that breaks lives in the `publish` SKILL; fix it
|
|
32
|
+
in `.agents/skills/publish/SKILL.md` (not a `.claude/commands/` file).
|
|
33
|
+
- `reserved`: Codex has no command, so create a SKILL with a reserved name
|
|
34
|
+
instead, `Write` `.agents/skills/config/SKILL.md` named `config` (it shadows
|
|
35
|
+
the open-standard `COMMONS_RESERVED_NAMES`); clear it by renaming the folder +
|
|
36
|
+
`frontmatter.name` to `new-page`, exactly like the basic track's `reserved`
|
|
37
|
+
chapter, on a skill.
|
|
38
|
+
- `publish`: run the `publish` SKILL's steps for real (same `/check-links` +
|
|
39
|
+
`@content-editor` + deploy runbook).
|
|
26
40
|
|
|
27
41
|
**Real-execution contract (read once).** When invoking the `content-editor` via
|
|
28
42
|
the Task tool, instruct it explicitly to write ONLY `.html` files under
|
|
@@ -225,8 +239,8 @@ Tell the tester:
|
|
|
225
239
|
> page.
|
|
226
240
|
|
|
227
241
|
When the tester answers, invoke the project's `content-editor` (the
|
|
228
|
-
|
|
229
|
-
|
|
242
|
+
`.claude/agents/content-editor.md` agent) via the Task tool, honouring the
|
|
243
|
+
real-execution contract above: write ONE new
|
|
230
244
|
`.html` page under `public/` named after the topic (default `public/projects.html`),
|
|
231
245
|
following the agent's own steps and `docs/STYLE.md` (the shared shell, link
|
|
232
246
|
`/style.css`, one `<h1>`, a nav link back to Home), and add the new page to the
|
|
@@ -259,10 +273,6 @@ Wait for confirmation. Mark `add-page`: done. Auto-advance to `broken-ref`.
|
|
|
259
273
|
its keep. You rename a doc, and a link that pointed at the old name goes stale.
|
|
260
274
|
skill-map catches it the moment you re-scan.
|
|
261
275
|
|
|
262
|
-
On `agent-skills` / Antigravity there is no `/publish` command holding the deploy
|
|
263
|
-
link; use the variant in the note at the end of this chapter (rename
|
|
264
|
-
`docs/STYLE.md` to break the `content-editor`'s style-guide reference instead).
|
|
265
|
-
|
|
266
276
|
**Preparation**: none (the tester drives). Everything here is watched live on
|
|
267
277
|
the Map; no `sm` commands.
|
|
268
278
|
|
|
@@ -293,23 +303,12 @@ Wait for confirmation. The harness MUST be clean again (the red marker gone)
|
|
|
293
303
|
before Act C (the real `/publish` later follows this runbook). Mark `broken-ref`:
|
|
294
304
|
done. Auto-advance to `reserved`.
|
|
295
305
|
|
|
296
|
-
On `agent-skills` / Antigravity (no `command` kind), run the same beat on a link
|
|
297
|
-
that exists there: `mv docs/STYLE.md docs/STYLE-GUIDE.md`, which breaks the
|
|
298
|
-
`content-editor` skill's `[style guide]` reference; the Map flags the broken
|
|
299
|
-
reference on the `content-editor`; fix the link in the skill body and watch it
|
|
300
|
-
clear.
|
|
301
|
-
|
|
302
306
|
## Chapter `reserved` - A reserved name collides (~2 min)
|
|
303
307
|
|
|
304
308
|
**Context**: you add a quick command to scaffold new pages and, without
|
|
305
309
|
thinking, name it `init`, a name Claude Code already owns for its own slash
|
|
306
310
|
command. skill-map warns you before the runtime silently ignores your file.
|
|
307
311
|
|
|
308
|
-
On `agent-skills` / Antigravity there is no `command` kind: **skip this chapter**
|
|
309
|
-
and fold a one-line mention ("skill-map also warns when a file's name collides
|
|
310
|
-
with a runtime built-in") into the close of the previous chapter. Adjust the
|
|
311
|
-
section's chapter count accordingly.
|
|
312
|
-
|
|
313
312
|
**Preparation**: `Write` `.claude/commands/init.md`:
|
|
314
313
|
```markdown
|
|
315
314
|
---
|
|
@@ -359,10 +358,6 @@ checker over your pages, briefs the `content-editor` if anything needs a fix,
|
|
|
359
358
|
then follows the deploy runbook. This is the same Layer 1 / Layer 2 split, the
|
|
360
359
|
pages are output, so the Map stays put while the pipeline runs.
|
|
361
360
|
|
|
362
|
-
On `agent-skills` / Antigravity there is no `/publish` command: run the
|
|
363
|
-
`check-links` skill directly over `public/`, then follow `docs/DEPLOYMENT.md` by
|
|
364
|
-
hand. Everything else in this chapter is identical.
|
|
365
|
-
|
|
366
361
|
**Preparation**: make sure the pages exist (`index`, `about`, `projects` from the
|
|
367
362
|
earlier chapters; lay any that are missing from the templates in `setup`). When the tester asks to publish, **execute the publish flow for real**
|
|
368
363
|
by following `.claude/commands/publish.md`: run the `check-links` logic over
|
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
The live-UI prologue: the tester runs `sm init`, opens the browser, and watches the map update in real time as files are written and edited. `pace: per-step` (one chapter per exchange; the chapter's own confirmation advances to the next, NO separate "¿seguimos?"), `preflight: taught-init` (the tester runs `sm init` as the first taught step, not pre-flight), and the chapters lay the basics fixture progressively, one node at a time. Shared conventions (tone, provider detection / substitution, the `> ` rendering rule, the per-step cycle) live in `_core.md`; do not restate them here.
|
|
4
4
|
|
|
5
|
+
**Codex deltas (rich track).** When `tutorial.provider == codex` the lay commands are unchanged (the `--only` ids match the Codex overlay), but the on-disk shapes differ; substitute in the tester-facing prose:
|
|
6
|
+
|
|
7
|
+
- `init`: the boot node `demo-agent` is a **TOML agent** at `.codex/agents/demo-agent.toml`.
|
|
8
|
+
- `kinds`: the node list reads `.codex/agents/demo-agent.toml` (agent), `.agents/skills/demo-command/SKILL.md` (Codex has no `command`, so this node is a **skill**), `.agents/skills/demo-skill/SKILL.md` (skill), and the `notes/*.md`. Name the kinds as agent + skill + markdown.
|
|
9
|
+
- `first-edit`: the description to edit lives in `.codex/agents/demo-agent.toml` (the `description = "…"` TOML field, not YAML frontmatter).
|
|
10
|
+
- `connectors` onward: identical, the `@`/`/` bullets resolve the same on Codex; only the `ignore` chapter's directory tree shows `.codex/agents/` + `.agents/skills/` instead of `.claude/`.
|
|
11
|
+
|
|
5
12
|
## Chapter `init` - Your first node (~2 min)
|
|
6
13
|
|
|
7
14
|
Agent background (do NOT render this as a separate context paragraph; the tester-facing version is folded into the message below): `sm init` creates a hidden `.skill-map/` folder in the cwd holding the database where skill-map stores what it learns about the project, and runs an initial scan (mandatory first step). Typing `sm` alone (no arguments) in an initialised dir then starts the UI server with the watcher built in (it is just an alias of `sm serve` with all defaults; the moment you need any flag you write `sm serve --flag ...` explicitly). One process, one terminal: it boots the server, scans the `.md` files, detects changes, and pushes events over WebSocket to the live UI. The next chapters all run against this same `sm` session, you boot it here and keep it alive through the `ignore` chapter.
|
|
@@ -38,7 +45,7 @@ Wait for confirmation. Mark `init`: done.
|
|
|
38
45
|
|
|
39
46
|
Leave the browser open and the terminal with `sm` running. You create five more nodes **without any cross-fixture links** yet, pure standalone nodes, so the tester sees five new nodes pop in. Three new **kinds** show up in this step (skill, command, markdown); the last two files are sibling `markdown` notes (`demo-guideline`, `demo-guideline2`) the hub in the `connectors` chapter reaches two ways, a bare mention that resolves to nothing (which lands as a broken reference, no arrow drawn) and the same handle plus `.md` that resolves to a real file (a solid arrow).
|
|
40
47
|
|
|
41
|
-
Lay these five files in one go (their content + translation live in `fixtures-data/`). The script resolves `__PROVIDER__`
|
|
48
|
+
Lay these five files in one go (their content + translation live in `fixtures-data/`). The script resolves `__PROVIDER__` to the claude layout (this is the rich track). Backstage (silent):
|
|
42
49
|
|
|
43
50
|
```
|
|
44
51
|
node .claude/skills/sm-tutorial/scripts/fixtures.js lay prologue --only "__PROVIDER__/skills/demo-skill/SKILL.md,__PROVIDER__/commands/demo-command.md,notes/todo.md,notes/demo-guideline.md,notes/demo-guideline2.md" --provider <provider> --lang <lang>
|
|
@@ -109,7 +116,7 @@ You edit `notes/todo.md` so it becomes the **hub** that points to each of the ot
|
|
|
109
116
|
|
|
110
117
|
Five bullets, three kinds: `invokes` and `mentions` each appear twice, `references` once. The last two bullets are the resolution lesson: a bare `@demo-guideline` mention (which resolves to no agent, so it lands as a broken reference and draws no arrow) next to `@demo-guideline2.md`, the same handle shape plus a `.md` extension that points at a real sibling file (so it resolves and draws a solid arrow). Two separate nodes, one broken and one resolved. Five bullets but only four arrows on the canvas.
|
|
111
118
|
|
|
112
|
-
Apply the hub bullets (their content + translation live in `fixtures-data/`). The edit appends after the `# Pending` heading
|
|
119
|
+
Apply the hub bullets (their content + translation live in `fixtures-data/`). The edit appends after the `# Pending` heading. Backstage (silent):
|
|
113
120
|
|
|
114
121
|
```
|
|
115
122
|
node .claude/skills/sm-tutorial/scripts/fixtures.js edit todo-connectors --provider <provider> --lang <lang>
|
|
@@ -223,14 +230,12 @@ Once they confirm, the second edit fixes the broken reference. Tell the tester:
|
|
|
223
230
|
>
|
|
224
231
|
> Confirm when the new arrow is in and the red marker is gone.
|
|
225
232
|
|
|
226
|
-
You verify by reading `notes/todo.md` to confirm both edits landed (the `@demo-agent` bullet gone, `@demo-guideline` now `@demo-guideline.md`); the prologue's broken reference is now resolved.
|
|
233
|
+
You verify by reading `notes/todo.md` to confirm both edits landed (the `@demo-agent` bullet gone, `@demo-guideline` now `@demo-guideline.md`); the prologue's broken reference is now resolved. Once they confirm, leave the server running, the next chapter reuses it. Mark `edit-link`: done.
|
|
227
234
|
|
|
228
235
|
## Chapter `workspace` - Navigate the workspace (files, search, isolate) (~2 min)
|
|
229
236
|
|
|
230
237
|
**Context**: you've built the graph and understood it; this beat is about *moving around* it. The workspace has two halves: the **Map** you've been working in, and a **Files** panel, a folder tree of every node. You'll open that tree and filter it with the search box. The same `sm` session you booted back in the `init` chapter is still running.
|
|
231
238
|
|
|
232
|
-
Per §Provider detection, on `agent-skills` / Antigravity the fixture has fewer nodes (`demo-skill` plus the two `notes/` files), so swap the node names below for ones that exist in that set; the gestures are identical.
|
|
233
|
-
|
|
234
239
|
Walk the three tester actions below one at a time (open the Files
|
|
235
240
|
panel, then search, then isolate); each ends with its own
|
|
236
241
|
confirmation, so present one and wait for the tester before the next.
|
|
@@ -27,12 +27,9 @@ an external service, not a file on disk). If several harness members
|
|
|
27
27
|
named the same server, skill-map would draw a single shared
|
|
28
28
|
`mcp://images` node, not one per caller.
|
|
29
29
|
|
|
30
|
-
**Preparation**: `Edit`
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
frontmatter the same way). Do NOT rewrite the file. Change only the
|
|
34
|
-
`tools:` line in the frontmatter so the MCP tool joins the existing
|
|
35
|
-
two:
|
|
30
|
+
**Preparation**: `Edit` `.claude/agents/content-editor.md`. Do NOT
|
|
31
|
+
rewrite the file. Change only the `tools:` line in the frontmatter so
|
|
32
|
+
the MCP tool joins the existing two:
|
|
36
33
|
|
|
37
34
|
```yaml
|
|
38
35
|
tools: [Read, Write, mcp__images__search]
|
|
@@ -16,6 +16,25 @@ which are `.md`, so the scan ignores them), the portfolio
|
|
|
16
16
|
`.skillmapignore`, and the handbook `AGENTS.md` (the one boot node).
|
|
17
17
|
The chapters grow the harness from there.
|
|
18
18
|
|
|
19
|
+
**Codex deltas (rich track).** When `tutorial.provider == codex`:
|
|
20
|
+
|
|
21
|
+
- `kickoff` / `manual`: identical. A `.codex/` project resolves the `codex`
|
|
22
|
+
lens; `CLAUDE.md`'s `@AGENTS.md` reference resolves the same (Codex has the
|
|
23
|
+
`@`-directive). `AGENTS.md` is still the one boot node.
|
|
24
|
+
- `first-agent`: the `content-editor` is a **TOML agent** at
|
|
25
|
+
`.codex/agents/content-editor.toml`, not a `.claude/agents/*.md` file; point
|
|
26
|
+
the tester at the `.toml` if they want to peek. Its body references the style
|
|
27
|
+
guide from the start (baked into `developer_instructions`), so lay
|
|
28
|
+
`docs/STYLE.md` together with it (`fixtures.js lay portfolio --only
|
|
29
|
+
"__PROVIDER__/agents/content-editor.md,docs/STYLE.md" --provider codex …`,
|
|
30
|
+
the `--only` matches the TOML overlay by node id) so the
|
|
31
|
+
`content-editor -> docs/STYLE.md` arrow resolves immediately instead of
|
|
32
|
+
showing a transient broken-reference.
|
|
33
|
+
- `real-kinds`: Codex's kinds are `agent` (TOML) + `skill` + `markdown`, there is
|
|
34
|
+
no `command`. Lay only `docs/DEPLOY.md` here (STYLE landed in `first-agent`),
|
|
35
|
+
and name the kinds as agent + skill + markdown (the skill + the publish piece
|
|
36
|
+
arrive in Part 2 as skills).
|
|
37
|
+
|
|
19
38
|
## Chapter `kickoff` - Start the portfolio (~2 min)
|
|
20
39
|
|
|
21
40
|
**Context**: same `sm init` the tester learned in the prologue, but
|
|
@@ -28,14 +47,13 @@ disk. The orchestrator's `portfolio-init` already cleared it during
|
|
|
28
47
|
pre-flight, so the tester sees only the portfolio. If anything demo
|
|
29
48
|
lingers, mention it once and move on.
|
|
30
49
|
|
|
31
|
-
**Context (agent, do not narrate the plumbing): the lens.**
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
lens prompt here.
|
|
50
|
+
**Context (agent, do not narrate the plumbing): the lens.** The skill
|
|
51
|
+
was scaffolded under `.claude/` (the `claude` marker, where the tutorial
|
|
52
|
+
skill itself lives), so `sm init` auto-detects the `claude` lens with no
|
|
53
|
+
prompt. The root `AGENTS.md` is the vendor-neutral handbook, NOT a lens
|
|
54
|
+
marker, so it never forces an ambiguous prompt. (This is the rich track;
|
|
55
|
+
a Codex project resolves the `codex` lens the same way from its
|
|
56
|
+
`.codex/` marker.) Do not promise the tester a lens prompt here.
|
|
39
57
|
|
|
40
58
|
```bash
|
|
41
59
|
sm init
|
|
@@ -49,9 +67,8 @@ Tell the tester:
|
|
|
49
67
|
> `.claude/` folder is the **harness** (the helpers that maintain the
|
|
50
68
|
> site). skill-map maps that harness.
|
|
51
69
|
>
|
|
52
|
-
> Run `sm init`, it auto-detects the `claude` lens
|
|
53
|
-
>
|
|
54
|
-
> live UI.
|
|
70
|
+
> Run `sm init`, it auto-detects the `claude` lens from the `.claude/`
|
|
71
|
+
> folder. Then run `sm` to boot the live UI.
|
|
55
72
|
>
|
|
56
73
|
> Open the URL `sm` printed. You'll see **one node**: `AGENTS.md`,
|
|
57
74
|
> the project's handbook (the operating manual for the site).
|
|
@@ -99,9 +116,7 @@ Wait for confirmation. Mark `manual`: done.
|
|
|
99
116
|
## Chapter `first-agent` - The first harness agent (~2 min)
|
|
100
117
|
|
|
101
118
|
Lay the first harness agent (its content + translation live in
|
|
102
|
-
`fixtures-data/`).
|
|
103
|
-
`agent-skills` / Antigravity, which has no `agent` kind, adjust the
|
|
104
|
-
prose to the skill the set lays there. Backstage (silent):
|
|
119
|
+
`fixtures-data/`). Backstage (silent):
|
|
105
120
|
|
|
106
121
|
```
|
|
107
122
|
node .claude/skills/sm-tutorial/scripts/fixtures.js lay portfolio --only "__PROVIDER__/agents/content-editor.md" --provider <provider> --lang <lang>
|
|
@@ -125,16 +125,19 @@ Mark `settings-2-resolve: done`.
|
|
|
125
125
|
|
|
126
126
|
**Context**: the single most consequential setting, the lens that
|
|
127
127
|
decides which provider types the project's files. It auto-detects and
|
|
128
|
-
never touches your `.md` files.
|
|
128
|
+
never touches your `.md` files. (Agent: substitute `<provider>` with
|
|
129
|
+
`tutorial.provider`, the lens this run was scaffolded for.)
|
|
129
130
|
|
|
130
131
|
> One setting earns its own step: the **active provider lens**. A
|
|
131
132
|
> skill-map project reads its files through exactly **one** provider
|
|
132
133
|
> at a time, and that lens decides how each file is interpreted, so
|
|
133
134
|
> the same files can read differently depending on which lens is active.
|
|
134
135
|
|
|
135
|
-
> The lens auto-detects on the first scan from
|
|
136
|
-
>
|
|
137
|
-
>
|
|
136
|
+
> The lens auto-detects on the first scan from the project's layout. A
|
|
137
|
+
> marker folder selects its lens: `.claude/` → `claude`, `.codex/` →
|
|
138
|
+
> `codex`, `.agent/workflows/` → `antigravity`; a project with only
|
|
139
|
+
> `.agents/skills/` and no vendor marker falls back to the open-standard
|
|
140
|
+
> `agent-skills` lens. Scan once and check where it landed:
|
|
138
141
|
|
|
139
142
|
```bash
|
|
140
143
|
sm scan
|
|
@@ -142,17 +145,18 @@ sm config get activeProvider
|
|
|
142
145
|
```
|
|
143
146
|
|
|
144
147
|
Expected: the scan prints a line like `Auto-detected activeProvider
|
|
145
|
-
=
|
|
146
|
-
.skill-map/settings.json`, and `get` then reports
|
|
148
|
+
= <provider> from filesystem markers; persisted to
|
|
149
|
+
.skill-map/settings.json`, and `get` then reports `<provider>`. The lens
|
|
147
150
|
is just a key in `settings.json`, persisted like any other setting.
|
|
148
151
|
|
|
149
|
-
>
|
|
150
|
-
> `agent-skills
|
|
151
|
-
>
|
|
152
|
-
>
|
|
153
|
-
>
|
|
154
|
-
>
|
|
155
|
-
>
|
|
152
|
+
> The other lenses are just as real: `claude` and the open-standard
|
|
153
|
+
> `agent-skills` are stable; `codex` (OpenAI) and `antigravity` (Google)
|
|
154
|
+
> are beta but ship enabled and auto-detect their own marker. The open
|
|
155
|
+
> `agent-skills` lens is the default a project falls back to when no
|
|
156
|
+
> vendor marker is present. The idea to keep: one project reads through
|
|
157
|
+
> exactly one lens at a time, chosen by `activeProvider`, and it is cheap
|
|
158
|
+
> to change later because the graph is always rebuilt from your files,
|
|
159
|
+
> never the other way around.
|
|
156
160
|
|
|
157
161
|
Mark `settings-3-lens: done`.
|
|
158
162
|
|
|
@@ -34,7 +34,8 @@ import { parseArgs } from './lib/args.js';
|
|
|
34
34
|
import { emit, succeed, die } from './lib/io.js';
|
|
35
35
|
import { loadFixturesManifest, fixturesDir, resolveFootprint } from './lib/fixtures-manifest.js';
|
|
36
36
|
import {
|
|
37
|
-
providerDir, kindsFor, resolveTargetPath, kindForPath,
|
|
37
|
+
providerDir, kindsFor, resolveTargetPath, kindForPath, nodeIdForTokenPath, overlayKey,
|
|
38
|
+
fragmentKindsFor, PROVIDER_TOKEN,
|
|
38
39
|
} from './lib/paths.js';
|
|
39
40
|
|
|
40
41
|
function opts(args) {
|
|
@@ -68,38 +69,76 @@ function writeFileEnsuring(abs, content) {
|
|
|
68
69
|
|
|
69
70
|
/**
|
|
70
71
|
* Lay one set's files for the given lang + provider. `only` (a Set of
|
|
71
|
-
* token-form relpaths) restricts to those
|
|
72
|
-
* progressive reveal where each chapter lands its
|
|
72
|
+
* token-form relpaths, claude-shaped and lens-agnostic) restricts to those
|
|
73
|
+
* nodes, for the prologue's progressive reveal where each chapter lands its
|
|
74
|
+
* own nodes; matching is by logical node id so a claude-shaped `--only`
|
|
75
|
+
* entry still selects the agent-skills skill overlay of the same node.
|
|
76
|
+
*
|
|
77
|
+
* Tiers, in lay order (later wins): lang-invariant `shared/`, the language
|
|
78
|
+
* tier, then the per-provider overlay (`providers/<provider>/{shared,<lang>}/`).
|
|
79
|
+
* The overlay carries the skill-shaped variants of nodes a lens renders
|
|
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.
|
|
73
82
|
*/
|
|
74
83
|
function laySet(manifest, set, o, only = null) {
|
|
75
84
|
const { kinds } = pdirAndKinds(o);
|
|
76
85
|
if (!manifest.sets.includes(set)) die('unknown-set', `set '${set}' is not in the manifest.`);
|
|
77
86
|
const base = join(fixturesDir(), 'sets', set);
|
|
78
87
|
const langDir = existsSync(join(base, o.lang)) ? o.lang : (manifest.defaultLang ?? 'en');
|
|
88
|
+
const onlyIds = only ? new Set([...only].map(nodeIdForTokenPath)) : null;
|
|
89
|
+
const oKey = overlayKey(o.provider);
|
|
79
90
|
const laid = [];
|
|
91
|
+
const laidIds = new Set();
|
|
80
92
|
const skipped = [];
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
93
|
+
const tiers = [
|
|
94
|
+
join(base, 'shared'),
|
|
95
|
+
join(base, langDir),
|
|
96
|
+
join(base, 'providers', oKey, 'shared'),
|
|
97
|
+
join(base, 'providers', oKey, langDir),
|
|
98
|
+
];
|
|
99
|
+
for (const tierRoot of tiers) {
|
|
84
100
|
for (const rel of walk(tierRoot)) {
|
|
85
101
|
// `rel` is the token-form target path (e.g. __PROVIDER__/agents/x.md).
|
|
86
|
-
if (
|
|
102
|
+
if (onlyIds && !onlyIds.has(nodeIdForTokenPath(rel))) continue;
|
|
87
103
|
const kind = kindForPath(rel);
|
|
88
104
|
if (!kinds.has(kind)) { skipped.push({ path: rel, kind }); continue; }
|
|
89
105
|
const target = resolveTargetPath(rel, o.provider);
|
|
90
106
|
writeFileEnsuring(join(process.cwd(), target), readFileSync(join(tierRoot, rel)));
|
|
91
107
|
laid.push(target);
|
|
108
|
+
laidIds.add(nodeIdForTokenPath(rel));
|
|
92
109
|
}
|
|
93
110
|
}
|
|
94
|
-
|
|
111
|
+
// Drop from `skipped` any node that the overlay laid under another kind
|
|
112
|
+
// (the claude-shaped agent file is skipped, but its skill overlay landed),
|
|
113
|
+
// so the report only flags nodes genuinely absent on this lens.
|
|
114
|
+
const netSkipped = skipped.filter((s) => !laidIds.has(nodeIdForTokenPath(s.path)));
|
|
115
|
+
return { laid, skipped: netSkipped };
|
|
95
116
|
}
|
|
96
117
|
|
|
97
|
-
|
|
118
|
+
// Count UNIQUE `.md` targets: a per-provider overlay can overwrite a base
|
|
119
|
+
// file (e.g. the open-standard `AGENTS.md` handbook), so `laid` may list the
|
|
120
|
+
// same target twice; the node count is the on-disk reality, not the write count.
|
|
121
|
+
const nodeCount = (paths) => new Set(paths.filter((p) => p.endsWith('.md'))).size;
|
|
98
122
|
|
|
99
|
-
/**
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
123
|
+
/**
|
|
124
|
+
* Resolve a fragment file path. A per-provider overlay
|
|
125
|
+
* (`edits/<id>/providers/<provider>/<lang>/`) wins when present, mirroring
|
|
126
|
+
* the set overlay, a fragment with a relative link to a provider-dir file
|
|
127
|
+
* is depth-sensitive (the content-editor lives one level deeper as a skill
|
|
128
|
+
* under agent-skills), so its link text differs per lens. Falls back to the
|
|
129
|
+
* shared fragment, then to the default language for either tier.
|
|
130
|
+
*/
|
|
131
|
+
function fragmentPath(manifest, id, o, file) {
|
|
132
|
+
const def = manifest.defaultLang ?? 'en';
|
|
133
|
+
const dir = join(fixturesDir(), 'edits', id);
|
|
134
|
+
const oKey = overlayKey(o.provider);
|
|
135
|
+
const candidates = [
|
|
136
|
+
join(dir, 'providers', oKey, o.lang, file),
|
|
137
|
+
join(dir, 'providers', oKey, def, file),
|
|
138
|
+
join(dir, o.lang, file),
|
|
139
|
+
join(dir, def, file),
|
|
140
|
+
];
|
|
141
|
+
return candidates.find((c) => existsSync(c)) ?? candidates[candidates.length - 1];
|
|
103
142
|
}
|
|
104
143
|
|
|
105
144
|
/** Apply one manifest edit (append fragments) honoring requiresKind. */
|
|
@@ -107,14 +146,30 @@ function applyEdit(manifest, id, o) {
|
|
|
107
146
|
const { kinds } = pdirAndKinds(o);
|
|
108
147
|
const def = manifest.edits?.[id];
|
|
109
148
|
if (!def) die('unknown-edit', `edit '${id}' is not in the manifest.`);
|
|
110
|
-
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
|
|
149
|
+
// Resolve the target to the shape this provider actually laid. When the
|
|
150
|
+
// declared (claude-shaped) target's kind is unclaimed, fall back to the
|
|
151
|
+
// skill-overlay path for the same node id, agent-skills renders the
|
|
152
|
+
// content-editor agent as a skill, so the style fragment must append to
|
|
153
|
+
// that skill body. Only genuinely-absent nodes skip the edit.
|
|
154
|
+
let targetTok = def.target;
|
|
155
|
+
if (!kinds.has(kindForPath(targetTok))) {
|
|
156
|
+
const skillTok = `${PROVIDER_TOKEN}/skills/${nodeIdForTokenPath(def.target)}/SKILL.md`;
|
|
157
|
+
const skillAbs = join(process.cwd(), resolveTargetPath(skillTok, o.provider));
|
|
158
|
+
if (kinds.has('skill') && existsSync(skillAbs)) {
|
|
159
|
+
targetTok = skillTok;
|
|
160
|
+
} else {
|
|
161
|
+
return { target: resolveTargetPath(def.target, o.provider), appended: [], skipped: true };
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
const target = resolveTargetPath(targetTok, o.provider);
|
|
114
165
|
const targetAbs = join(process.cwd(), target);
|
|
115
166
|
if (!existsSync(targetAbs)) die('edit-target-missing', `edit '${id}' target not found: ${target}`);
|
|
116
167
|
|
|
117
|
-
|
|
168
|
+
// Fragment gating is by TRACK, not the base-tier `kinds`: a rich provider
|
|
169
|
+
// (codex) links to agent / command roles it renders via overlay (TOML agent,
|
|
170
|
+
// command-as-skill), so those bullets apply even though its base kinds omit them.
|
|
171
|
+
const fragKinds = fragmentKindsFor(o.provider);
|
|
172
|
+
const fragments = (def.fragments ?? []).filter((f) => !f.requiresKind || fragKinds.has(f.requiresKind));
|
|
118
173
|
if (fragments.length === 0) return { target, appended: [] };
|
|
119
174
|
|
|
120
175
|
let content = readFileSync(targetAbs, 'utf8');
|
|
@@ -122,7 +177,7 @@ function applyEdit(manifest, id, o) {
|
|
|
122
177
|
if (def.prefix) content += def.prefix;
|
|
123
178
|
const appended = [];
|
|
124
179
|
for (const frag of fragments) {
|
|
125
|
-
content += readFileSync(fragmentPath(manifest, id, o
|
|
180
|
+
content += readFileSync(fragmentPath(manifest, id, o, frag.file), 'utf8');
|
|
126
181
|
appended.push(frag.file);
|
|
127
182
|
}
|
|
128
183
|
writeFileSync(targetAbs, content);
|
|
@@ -207,7 +262,15 @@ const VERBS = {
|
|
|
207
262
|
const langDir = existsSync(join(base, o.lang)) ? o.lang : (manifest.defaultLang ?? 'en');
|
|
208
263
|
// Accept a resolved path (`.claude/...`) or token form; normalise to token.
|
|
209
264
|
const tokenForm = file.startsWith(`${pdir}/`) ? PROVIDER_TOKEN + file.slice(pdir.length) : file;
|
|
210
|
-
|
|
265
|
+
// Prefer the per-provider overlay (so codex / agent-skills get their own
|
|
266
|
+
// shape, e.g. the publish skill or the TOML agent) before the base.
|
|
267
|
+
const oKey = overlayKey(o.provider);
|
|
268
|
+
const found = [
|
|
269
|
+
join(base, 'providers', oKey, langDir, tokenForm),
|
|
270
|
+
join(base, 'providers', oKey, 'shared', tokenForm),
|
|
271
|
+
join(base, langDir, tokenForm),
|
|
272
|
+
join(base, 'shared', tokenForm),
|
|
273
|
+
].find((c) => existsSync(c));
|
|
211
274
|
if (!found) {
|
|
212
275
|
emit({ ok: false, code: 'not-found', error: `file '${file}' not found in set '${set}'.` });
|
|
213
276
|
process.exit(1);
|
|
@@ -234,5 +297,5 @@ function main() {
|
|
|
234
297
|
}
|
|
235
298
|
|
|
236
299
|
main();
|
|
237
|
-
!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]="
|
|
238
|
-
//# debugId=
|
|
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
|