spec-layer 0.9.0 → 0.10.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.
Files changed (3) hide show
  1. package/README.md +67 -16
  2. package/dist/cli.js +2556 -210
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -65,19 +65,23 @@ Module 2025.10 files, rather than `ai/foundation.yaml`, needs 0.4.0 or later.
65
65
  need 0.7.0 or later. The `census` and `config_hash` blocks inside
66
66
  `resolver.json`, and the `transform` and `resolved` fields in
67
67
  `spec-layer.meta.json`, need 0.8.2 or later; an earlier version pulls the same
68
- files without those fields.
68
+ files without those fields. Markdown component pages (`componentSpecsFormat`
69
+ and `--component-format`) need 0.10.0 or later. An earlier version ignores the
70
+ key, and refuses to pull into a `component-specs/` that already holds
71
+ Markdown pages, so every CLI that pulls a repository using Markdown needs
72
+ 0.10.0.
69
73
 
70
74
  ## Commands
71
75
 
72
76
  | Command | What it does |
73
77
  |---|---|
74
- | `setup --id lib_... --key sl_... [--out DIR] [--platform P]... [selection]` | Writes `speclayer.json`, stores the key in `speclayer.local.json`, then pulls. The command the plugin copies. |
75
- | `init --id lib_... [--out DIR] [--platform P]... [selection]` | Writes `speclayer.json` so later commands need no flags. No key, no network. |
76
- | `pull [--id lib_...] [--key sl_...] [--platform P]... [selection]` | Fetches the library and writes it into `DIR` (default `.speclayer`). |
77
- | `status [--id lib_...] [--key sl_...]` | Checks freshness without writing. Exits `2` when the local copy is behind. |
78
+ | `setup --id lib_... --key sl_... [--out DIR] [--platform P]... [selection] [--component-format yaml\|md]` | Writes `speclayer.json`, stores the key in `speclayer.local.json`, then pulls. The command the plugin copies. |
79
+ | `init --id lib_... [--out DIR] [--platform P]... [selection] [--component-format yaml\|md]` | Writes `speclayer.json` so later commands need no flags. No key, no network. |
80
+ | `pull [--id lib_...] [--key sl_...] [--platform P]... [selection] [--component-format yaml\|md]` | Fetches the library and writes it into `DIR` (default `.speclayer`). |
81
+ | `status [--id lib_...] [--key sl_...]` | Checks freshness without writing. Prints the library version when the service reports one. Exits `2` when the local copy is behind. |
78
82
  | `list` | Lists every artifact in the last pull, with its file path or `not written`. |
79
83
  | `show foundation [--canonical]` | Prints the Foundation's DTCG document to stdout. |
80
- | `show component NAME [--canonical]` | Prints one component's AI YAML to stdout. |
84
+ | `show component NAME [--component-format yaml\|md] [--canonical]` | Prints one component's AI YAML or Markdown page to stdout. |
81
85
  | `tools [--json]` | Lists every command with what it reaches, needs, and writes. |
82
86
  | `skill [--install] [--agent HOST]... [--platform P] [--json]` | Prints a guide for a coding agent, adapted to this repository and the last pull; `--install` writes it where the agent reads instructions. |
83
87
 
@@ -186,12 +190,37 @@ The selection only decides which `component-specs/` files are written. `bundle.j
186
190
  always holds the whole library, so `list` and `show` can answer for any
187
191
  artifact, written or not, and `status` compares one hash.
188
192
 
193
+ ## Component format
194
+
195
+ `component-specs/` holds YAML by default: the same compact brief the plugin's
196
+ **Copy for AI** copies. Set `componentSpecsFormat` to `md` to write one
197
+ Markdown page per component instead:
198
+
199
+ ```json
200
+ {
201
+ "libraryId": "lib_...",
202
+ "outDir": ".speclayer",
203
+ "componentSpecsDir": "component-specs",
204
+ "componentSpecsFormat": "md"
205
+ }
206
+ ```
207
+
208
+ `setup` and `init` store `--component-format yaml|md`; `pull` and `show` use
209
+ the flag for one run. The page is rendered from the published canonical
210
+ artifact at pull time, so every library already published gets it without a
211
+ republish. It opens with front matter carrying the same `spec_layer` envelope
212
+ the YAML does, with `profile: markdown`, and marks any AI-written section as
213
+ AI written. Switching formats removes the other format's files on the next
214
+ pull. Foundations are unaffected: `.speclayer/tokens/` stays DTCG in either
215
+ format, and the CSS output directory from `outputs` is unaffected too.
216
+
189
217
  ## Reading one artifact
190
218
 
191
219
  `show` prints exactly one artifact and nothing else, so it pipes cleanly:
192
220
 
193
221
  ```bash
194
222
  npx spec-layer show component Button # the compact AI YAML
223
+ npx spec-layer show component Button --component-format md # the Markdown page
195
224
  npx spec-layer show foundation --canonical # the canonical v5 JSON artifact
196
225
  ```
197
226
 
@@ -249,7 +278,7 @@ matter what the ignore rules say.
249
278
  ```text
250
279
  .speclayer/
251
280
  bundle.json the published bundle, verbatim
252
- manifest.json every artifact indexed by content hash and path, plus the selection, outputs, and componentSpecsDir
281
+ manifest.json every artifact indexed by content hash and path, plus the selection, outputs, componentSpecsDir, componentSpecsFormat, and the library version when one was reported
253
282
  tokens/ the Foundation as Design Tokens Format Module 2025.10 files
254
283
  <collection>.<mode>.json one file per collection and mode, rooted at the collection name
255
284
  styles.typography.json text styles as typography composites (when present)
@@ -261,7 +290,7 @@ matter what the ignore rules say.
261
290
  web-css.map.json DTCG path -> CSS custom property, where the name came from, and which file declares it
262
291
  web-css.report.json what the CSS files could not express
263
292
  component-specs/
264
- <name>.yaml one brief per selected component, byte-identical to Copy for AI
293
+ <name>.yaml | <name>.md one brief per selected component: the Copy for AI YAML, or a Markdown page
265
294
  tokens/
266
295
  index.css imports every file below, in resolver order
267
296
  <collection>.css one file per single-mode collection, at :root
@@ -269,10 +298,10 @@ tokens/
269
298
  ```
270
299
 
271
300
  Point your agent at `component-specs/` and `.speclayer/tokens/`, and import
272
- `tokens/index.css` from the platform's root stylesheet. The component YAML is
273
- the same compact form the plugin's **Copy for AI** puts on your clipboard;
274
- `bundle.json` additionally holds the full canonical artifacts if you need
275
- them.
301
+ `tokens/index.css` from the platform's root stylesheet. In the default format,
302
+ the component YAML is the same compact form the plugin's **Copy for AI** puts
303
+ on your clipboard; `bundle.json` additionally holds the full canonical
304
+ artifacts if you need them.
276
305
 
277
306
  In `manifest.json`, an artifact the selection left unwritten has `"path":
278
307
  null`. A manifest from CLI 0.1.0 has no `selection` field and means
@@ -285,10 +314,10 @@ non-empty directory it did not write, since the swap replaces that directory.
285
314
 
286
315
  `component-specs/` and `tokens/` are written in place, not swapped. `pull`
287
316
  owns exactly the files there that begin with its marker (the CSS header, or
288
- the brief's opening `spec_layer:` lines): it replaces or removes those,
289
- ignores dotfiles, and refuses to run when anything else is present. A
290
- repository that already uses a path can set `componentSpecsDir` or
291
- `outputs[].path`.
317
+ a brief's opening `spec_layer:` lines, after `---` for a Markdown page): it
318
+ replaces or removes those, ignores dotfiles, and refuses to run when anything
319
+ else is present. A repository that already uses a path can set
320
+ `componentSpecsDir` or `outputs[].path`.
292
321
 
293
322
  When nothing changed since the last pull with the same selection, `pull`
294
323
  prints `Already up to date` and writes nothing. Every republish stamps a new
@@ -419,6 +448,28 @@ Commit `.speclayer/`, `speclayer.json`, `component-specs/`, and the output
419
448
  paths. A repository that would rather regenerate in CI ignores them and runs
420
449
  `pull` there; `status` exits `2` when a pull is due.
421
450
 
451
+ ## Library versions
452
+
453
+ A published library carries a semantic version, assigned by the publish
454
+ service when the plugin publishes. `pull`, `status`, and `list` print it
455
+ beside the publish date, for example `Up to date (v1.5.0, published …)`. A
456
+ library published before versioning has none until its next publish, and
457
+ the CLI then prints the date alone rather than a guessed version.
458
+
459
+ The minimum bump is computed from the Figma facts in the bundle. Prose,
460
+ descriptions, and export metadata never move it. The publisher may raise the
461
+ bump, never lower it.
462
+
463
+ | Change | Bump |
464
+ |---|---|
465
+ | A component, property, option, variant axis, state, anatomy part, collection, mode, or token removed or renamed | major |
466
+ | Any of those added | minor |
467
+ | A binding, layout or effect value, token value, or style added, removed, or changed | patch |
468
+ | A property's kind or default, or a part's type or visibility toggle, changed | patch |
469
+
470
+ Pinned pulls (`pull --version`) are not available yet: `pull` always fetches
471
+ the current version.
472
+
422
473
  ## Exit codes
423
474
 
424
475
  | Code | Meaning |