@rse/specbook 1.5.2 → 1.6.1
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/LICENSE.txt +201 -0
- package/README.md +288 -43
- package/dst/specbook-api.d.ts +23 -3
- package/dst/specbook-api.js +133 -59
- package/dst/specbook-cli.js +93 -26
- package/dst/specbook-cmd-describe.js +4 -4
- package/dst/specbook-cmd-export-schema.d.ts +8 -0
- package/dst/specbook-cmd-export-schema.js +441 -0
- package/dst/specbook-cmd-export.js +23 -6
- package/dst/specbook-cmd-init-sample.d.ts +4 -0
- package/dst/specbook-cmd-init-sample.js +322 -0
- package/dst/specbook-cmd-init.d.ts +1 -0
- package/dst/specbook-cmd-init.js +42 -10
- package/dst/specbook-cmd-lint.js +46 -48
- package/dst/specbook-cmd-query.d.ts +30 -0
- package/dst/specbook-cmd-query.js +165 -0
- package/dst/specbook-config.d.ts +9 -1
- package/dst/specbook-config.js +135 -10
- package/dst/specbook-coverage.js +2 -2
- package/dst/specbook-diagram.d.ts +7 -5
- package/dst/specbook-diagram.js +546 -143
- package/dst/specbook-export-ast.d.ts +1 -1
- package/dst/specbook-export-ast.js +11 -8
- package/dst/specbook-export-code.js +3 -3
- package/dst/specbook-export-common.d.ts +1 -1
- package/dst/specbook-export-common.js +3 -2
- package/dst/specbook-export-diagram.d.ts +1 -1
- package/dst/specbook-export-diagram.js +25 -7
- package/dst/specbook-export-html-fold.d.ts +16 -6
- package/dst/specbook-export-html-fold.js +65 -44
- package/dst/specbook-export-html-render.js +107 -26
- package/dst/specbook-export-html-search.js +18 -20
- package/dst/specbook-export-html-template.js +38 -9
- package/dst/specbook-export-html-widget.d.ts +2 -0
- package/dst/specbook-export-html-widget.js +219 -19
- package/dst/specbook-export-html.css +208 -38
- package/dst/specbook-export-html.js +96 -53
- package/dst/specbook-export-md.d.ts +2 -1
- package/dst/specbook-export-md.js +7 -8
- package/dst/specbook-export-pdf.js +1 -1
- package/dst/specbook-files.d.ts +2 -0
- package/dst/specbook-files.js +41 -0
- package/dst/specbook-format-meta.yaml +401 -0
- package/dst/specbook-format-pm.yaml +1240 -0
- package/dst/specbook-format-schema.d.ts +33 -3
- package/dst/specbook-format-schema.js +49 -3
- package/dst/specbook-format.md +427 -47
- package/dst/specbook-format.yaml +524 -228
- package/dst/specbook-ignore.js +2 -2
- package/dst/specbook-link.d.ts +4 -0
- package/dst/specbook-link.js +61 -6
- package/dst/specbook-mcp.js +103 -19
- package/dst/specbook-parse-semantic.d.ts +1 -0
- package/dst/specbook-parse-semantic.js +11 -4
- package/dst/specbook-parse-syntax.d.ts +1 -0
- package/dst/specbook-parse-syntax.js +1 -1
- package/dst/specbook-parse.d.ts +1 -1
- package/dst/specbook-parse.js +3 -3
- package/dst/specbook-project.d.ts +2 -0
- package/dst/specbook-project.js +15 -5
- package/dst/specbook-remote.d.ts +28 -0
- package/dst/specbook-remote.js +429 -0
- package/package.json +32 -20
package/README.md
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
|
|
2
|
-
<img src="https://raw.githubusercontent.com/rse/specbook/master/etc/specbook-logo-blue-light.svg"
|
|
2
|
+
<img src="https://raw.githubusercontent.com/rse/specbook/master/etc/specbook-logo-blue-light.svg"
|
|
3
|
+
width="400" align="right" alt=""/>
|
|
3
4
|
|
|
4
5
|
SpecBook
|
|
5
6
|
========
|
|
@@ -8,8 +9,13 @@ SpecBook
|
|
|
8
9
|
|
|
9
10
|
[specbook.tools](https://specbook.tools)
|
|
10
11
|
|
|
11
|
-
[![github (author stars)]
|
|
12
|
-
[![github (author followers)]
|
|
12
|
+
[![github (author stars)][badge-stars]](https://github.com/rse)
|
|
13
|
+
[![github (author followers)][badge-followers]](https://github.com/rse)
|
|
14
|
+
|
|
15
|
+
[badge-stars]:
|
|
16
|
+
https://img.shields.io/github/stars/rse?logo=github&label=author%20stars&color=%233377aa
|
|
17
|
+
[badge-followers]:
|
|
18
|
+
https://img.shields.io/github/followers/rse?label=author%20followers&logo=github&color=%234477aa
|
|
13
19
|
|
|
14
20
|
About
|
|
15
21
|
-----
|
|
@@ -19,7 +25,8 @@ format* which can be configured for the specifications of particular
|
|
|
19
25
|
contexts through a YAML-based *schema configuration*. SpecBook allows
|
|
20
26
|
specifications to be *initialized*, *linted*, *exported* (JSON, JSON5,
|
|
21
27
|
YAML, TOON, HTML, PDF, and normalized Markdown), *previewed* (HTML, live
|
|
22
|
-
in the browser), and *described*
|
|
28
|
+
in the browser), *queried* (ASTq selectors on the AST), and *described*
|
|
29
|
+
to LLMs.
|
|
23
30
|
|
|
24
31
|
**SpecBook** ships with an API class with methods `<xxx>()`, a
|
|
25
32
|
CLI with commands `specbook <xxx>`, and an MCP service with tools
|
|
@@ -29,7 +36,7 @@ CLI with commands `specbook <xxx>`, and an MCP service with tools
|
|
|
29
36
|
|
|
30
37
|
- **Hierarchical Object Model**:
|
|
31
38
|
A specification is a tree of typed objects, each with a kind and
|
|
32
|
-
name, an optional id, optional properties, optional description, and
|
|
39
|
+
name, an optional id, optional properties, an optional description, and
|
|
33
40
|
optional child objects. The allowed object hierarchy is defined per
|
|
34
41
|
context by the YAML schema configuration.
|
|
35
42
|
|
|
@@ -41,7 +48,7 @@ CLI with commands `specbook <xxx>`, and an MCP service with tools
|
|
|
41
48
|
|
|
42
49
|
- **Wiki-Style Object Linking**:
|
|
43
50
|
Objects can hierarchically reference each other through Wiki-style
|
|
44
|
-
`[[xxx]]` references, which are resolved against the locally
|
|
51
|
+
`[[xxx]]` references, which are resolved against the locally unique
|
|
45
52
|
ids and names of all objects. In the HTML and PDF exports they become
|
|
46
53
|
navigable links onto precise anchors.
|
|
47
54
|
|
|
@@ -58,9 +65,10 @@ CLI with commands `specbook <xxx>`, and an MCP service with tools
|
|
|
58
65
|
demands is reported as a warning only. A bundled standard schema
|
|
59
66
|
configuration applies if no particular one is given.
|
|
60
67
|
|
|
61
|
-
- **Object Model Diagram
|
|
62
|
-
Object kinds can declare "graph", "hub",
|
|
63
|
-
|
|
68
|
+
- **Object Model Diagram Visualization**:
|
|
69
|
+
Object kinds can declare one or more "graph", "hub", "grid", "state",
|
|
70
|
+
"layer", "slice", "tree", "matrix", "sequence", "petri", or "gantt" diagrams in
|
|
71
|
+
the schema, whose nodes and edges are automatically derived from the
|
|
64
72
|
object model and its references. The diagrams are rendered with the
|
|
65
73
|
sibling project [Gradia](https://github.com/rse/gradia), which is
|
|
66
74
|
specialized in rendering object models.
|
|
@@ -84,11 +92,15 @@ CLI with commands `specbook <xxx>`, and an MCP service with tools
|
|
|
84
92
|
a table-of-contents (also as a slide-in side panel for quick navigation),
|
|
85
93
|
a diagram-of-contents, a fuzzy full-text search, embedded images,
|
|
86
94
|
embedded Mermaid and D2 diagrams (inline or as files, in the theme colors),
|
|
87
|
-
embedded PDF pages,
|
|
95
|
+
embedded PDF pages, syntax-highlighted code listings (fenced or as
|
|
96
|
+
files, with line numbers and marked lines),
|
|
88
97
|
reference coverage tables (e.g. the share of the use cases, scenarios,
|
|
89
98
|
requirements, and rules the test cases verify), a
|
|
90
99
|
scroll progress meter (which also scrolls back to the top on click),
|
|
91
100
|
diagram maximization (into the viewport or the fullscreen),
|
|
101
|
+
folding of the diagrams and over-long table cells, an artifact
|
|
102
|
+
filter (which shows only the objects the selected artifacts reach
|
|
103
|
+
through their references),
|
|
92
104
|
description popups (which show the schema and corpus description of
|
|
93
105
|
an object kind, property, or object instance on hover), and a
|
|
94
106
|
light/dark theme toggle. It is intended for the day-to-day online
|
|
@@ -108,7 +120,8 @@ CLI with commands `specbook <xxx>`, and an MCP service with tools
|
|
|
108
120
|
The title object of the specification drives the entire document:
|
|
109
121
|
its title, subtitle, author, version, and logo fill the title page
|
|
110
122
|
(with an optional light/dark variant of the logo), its language
|
|
111
|
-
selects the smart typography quote style
|
|
123
|
+
selects the smart typography quote style and the translation of the
|
|
124
|
+
rationale keyword (like `BECAUSE (weil)`), its color tone seeds the
|
|
112
125
|
theme color spreads of both the light and the dark theme, and its
|
|
113
126
|
character set subsets the embedded fonts down to the actually needed
|
|
114
127
|
glyphs.
|
|
@@ -138,40 +151,67 @@ Commands:
|
|
|
138
151
|
$ specbook init \
|
|
139
152
|
[-v|--verbose [<level>]] \
|
|
140
153
|
[-c|--config <schema-yaml-file>] \
|
|
141
|
-
[-b|--basedir <spec-md-file-basedir>]
|
|
154
|
+
[-b|--basedir <spec-md-file-basedir>] \
|
|
155
|
+
[-F|--fetch <mode>] \
|
|
156
|
+
[-s|--sample]
|
|
142
157
|
|
|
143
158
|
$ specbook lint \
|
|
144
159
|
[-v|--verbose [<level>]] \
|
|
145
160
|
[-c|--config <schema-yaml-file>] \
|
|
146
|
-
[-b|--basedir <spec-md-file-basedir>]
|
|
161
|
+
[-b|--basedir <spec-md-file-basedir>] \
|
|
162
|
+
[-F|--fetch <mode>] \
|
|
163
|
+
[-g|--gitignore]
|
|
147
164
|
|
|
148
165
|
$ specbook export \
|
|
149
166
|
[-v|--verbose [<level>]] \
|
|
150
167
|
[-c|--config <schema-yaml-file>] \
|
|
151
168
|
[-b|--basedir <spec-md-file-basedir>] \
|
|
152
|
-
[-
|
|
169
|
+
[-F|--fetch <mode>] \
|
|
170
|
+
[-g|--gitignore] \
|
|
171
|
+
[-S|--schema] \
|
|
172
|
+
[-o|--output [<format>:]<output-file>] [...] \
|
|
153
173
|
[-w|--watch] \
|
|
154
|
-
[-O|--omit <aspect>[,...]]
|
|
155
|
-
[...]
|
|
174
|
+
[-O|--omit <aspect>[,...]]
|
|
156
175
|
|
|
157
176
|
$ specbook preview \
|
|
158
177
|
[-v|--verbose [<level>]] \
|
|
159
178
|
[-c|--config <schema-yaml-file>] \
|
|
160
179
|
[-b|--basedir <spec-md-file-basedir>] \
|
|
180
|
+
[-F|--fetch <mode>] \
|
|
181
|
+
[-g|--gitignore] \
|
|
182
|
+
[-S|--schema] \
|
|
161
183
|
[-O|--omit <aspect>[,...]] \
|
|
162
184
|
[-a|--addr <ip-addr>] \
|
|
163
185
|
[-p|--port <tcp-port>]
|
|
164
186
|
|
|
187
|
+
$ specbook query \
|
|
188
|
+
[-v|--verbose [<level>]] \
|
|
189
|
+
[-c|--config <schema-yaml-file>] \
|
|
190
|
+
[-b|--basedir <spec-md-file-basedir>] \
|
|
191
|
+
[-F|--fetch <mode>] \
|
|
192
|
+
[-g|--gitignore] \
|
|
193
|
+
[-S|--schema] \
|
|
194
|
+
[-P|--param <name>=<value>] [...] \
|
|
195
|
+
[-f|--format <format>] \
|
|
196
|
+
[-o|--output [<format>:]<output-file>] \
|
|
197
|
+
<selector>
|
|
198
|
+
|
|
165
199
|
$ specbook describe \
|
|
166
200
|
[-v|--verbose [<level>]] \
|
|
167
201
|
[-c|--config <schema-yaml-file>] \
|
|
168
202
|
[-b|--basedir <spec-md-file-basedir>] \
|
|
203
|
+
[-F|--fetch <mode>] \
|
|
169
204
|
[-e|--embed] \
|
|
170
205
|
[-z|--compress [<level>]] \
|
|
171
206
|
[-f|--format <format>] \
|
|
172
207
|
[-p|--part <part>] \
|
|
173
208
|
[-o|--output <output-file>]
|
|
174
209
|
|
|
210
|
+
$ specbook search \
|
|
211
|
+
[-v|--verbose [<level>]] \
|
|
212
|
+
[-F|--fetch <mode>] \
|
|
213
|
+
[<term> ...]
|
|
214
|
+
|
|
175
215
|
$ specbook mcp \
|
|
176
216
|
[-v|--verbose [<level>]]
|
|
177
217
|
```
|
|
@@ -180,7 +220,8 @@ Options:
|
|
|
180
220
|
|
|
181
221
|
- `-v|--verbose [<level>]`:
|
|
182
222
|
Enable verbose logging of processing information to `stderr` at the
|
|
183
|
-
given verbosity level: `0` (the default) logs the
|
|
223
|
+
given verbosity level: `0` (the default) logs the warnings and the
|
|
224
|
+
environment problems only, `1`
|
|
184
225
|
(the bare flag) also the regular processing information, `2` also
|
|
185
226
|
the reference coverage ratios, and `3` also the unreferenced objects
|
|
186
227
|
of a reference coverage.
|
|
@@ -188,12 +229,11 @@ Options:
|
|
|
188
229
|
- `-c|--config <schema-yaml-file>`:
|
|
189
230
|
The YAML schema configuration (default: the `config` entry of the
|
|
190
231
|
project configuration file `.specbook.yaml`, else the bundled standard
|
|
191
|
-
schema configuration `specbook-format.yaml`) determines the
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
A
|
|
195
|
-
|
|
196
|
-
file, unless it is `optional` itself. Both `lint` and `export` report
|
|
232
|
+
schema configuration `specbook-format.yaml`) determines the artifacts
|
|
233
|
+
of the specification, while its `file` fields drive `init` only: every
|
|
234
|
+
`.md` file below the base directory is loaded and parsed, whatever its
|
|
235
|
+
name. A base directory without any `.md` file is reported, and so is an
|
|
236
|
+
artifact absent from all of them, unless it is `optional`. Both `lint` and `export` report
|
|
197
237
|
all diagnostics and fail on any error among them (a warning, like a
|
|
198
238
|
lapse of the reference coverage a `referenced` object kind demands,
|
|
199
239
|
is reported only), so a partial or invalid specification is never
|
|
@@ -204,7 +244,11 @@ Options:
|
|
|
204
244
|
The option accepts glob patterns and can be given multiple times: the
|
|
205
245
|
matching files (in the order of the patterns and alphabetically within
|
|
206
246
|
a pattern, where the literal `std` names the bundled standard schema
|
|
207
|
-
configuration,
|
|
247
|
+
configuration, the literal `meta` the bundled meta one, which
|
|
248
|
+
describes a schema configuration itself, and the literal `pm` the
|
|
249
|
+
bundled project management one, which plans the delivery of a
|
|
250
|
+
solution in a handbook beside its specification, and where a pattern matching
|
|
251
|
+
no file is an error) are
|
|
208
252
|
merged in order into one effective schema configuration, the later
|
|
209
253
|
files into the earlier ones. The objects merge deeply, while the
|
|
210
254
|
elements of the lists are matched by identity (artifacts by `kind`
|
|
@@ -213,12 +257,61 @@ Options:
|
|
|
213
257
|
counterpart, an unmatched one is appended. Every file has to be valid
|
|
214
258
|
YAML on its own, while the merged result alone is validated against
|
|
215
259
|
the schema of the configuration.
|
|
260
|
+
Instead of a local file, the option also accepts a *remote reference*
|
|
261
|
+
(see "Remote References" below): `npm:<pkg>[@<range>][/<path>]`,
|
|
262
|
+
`github:<user>/<repo>[/<path>][#<ref>]`, or an `http://` or `https://`
|
|
263
|
+
URL of a single file, which is fetched into the download cache and then merged
|
|
264
|
+
exactly like a local file.
|
|
216
265
|
|
|
217
266
|
- `-b|--basedir <spec-md-file-basedir>`:
|
|
218
267
|
The base directory (default: the `basedir` entry of the project
|
|
219
|
-
configuration file `.specbook.yaml`, else `.`) is the directory
|
|
220
|
-
|
|
221
|
-
|
|
268
|
+
configuration file `.specbook.yaml`, else `.`) is the directory
|
|
269
|
+
whose `.md` files (recursively, except below `.`-prefixed entries)
|
|
270
|
+
make up the specification, and generated specification Markdown
|
|
271
|
+
files are placed inside it, too. A normalized Markdown export written
|
|
272
|
+
into it is refused, as it would be parsed as a specification file.
|
|
273
|
+
|
|
274
|
+
- `-F|--fetch <mode>`:
|
|
275
|
+
When to fetch the remote references of the schema configuration
|
|
276
|
+
through the network: `never` (the download cache only, where a
|
|
277
|
+
reference which is not cached is an error), `auto` (the default:
|
|
278
|
+
whenever the download cache lacks a reference or it is no longer
|
|
279
|
+
fresh), or `always` (ignoring the download cache).
|
|
280
|
+
|
|
281
|
+
- `-g|--gitignore` (`lint`, `export`, `preview`, and `query` only):
|
|
282
|
+
Set aside every specification file the Git exclude rules (the global
|
|
283
|
+
excludes file, the repository-local `info/exclude`, and the
|
|
284
|
+
`.gitignore` files, with Git's own precedence) exclude from its
|
|
285
|
+
project, as it is no part of the project: silently if all of its
|
|
286
|
+
artifacts are optional, else as the error `artifact file excluded by
|
|
287
|
+
Git`. A base directory outside any Git working tree excludes nothing.
|
|
288
|
+
|
|
289
|
+
- `-S|--schema` (`export`, `preview`, and `query` only):
|
|
290
|
+
Export (or preview, or query) the *effective schema configuration itself* --
|
|
291
|
+
the one `-c|--config` selects, merged out of its local, bundled, or
|
|
292
|
+
remote files -- as a SpecBook document, instead of the specification
|
|
293
|
+
below the base directory (which is not applicable then, so an
|
|
294
|
+
explicit `-b|--basedir` is an error, and `--watch` and `preview`
|
|
295
|
+
observe the configuration files only). The document is generated in
|
|
296
|
+
memory against the bundled meta schema configuration (`meta`) and
|
|
297
|
+
rendered like any other specification, in every export format: a
|
|
298
|
+
title page with the configuration references, the SpecBook version,
|
|
299
|
+
and the counts of the artifact kinds, artifacts, object kinds, and
|
|
300
|
+
reference relationships, an artifact-level overview graph as the
|
|
301
|
+
"Diagram of Contents", and one top-level `ARTIFACT-KIND` artifact per
|
|
302
|
+
artifact kind (with a graph of its artifacts and object kinds),
|
|
303
|
+
every artifact and object kind
|
|
304
|
+
(with its file, name pattern, optionality, `referenced`/`coverage`
|
|
305
|
+
patterns, `automaton`, `badge`, `multiple`, `diagram`, and `format`
|
|
306
|
+
configuration, its
|
|
307
|
+
description and literature references, and a hub diagram of its
|
|
308
|
+
references, every artifact also with a Mermaid UML class diagram of
|
|
309
|
+
it and its object kinds, omittable via `-O diagram:code` and left out
|
|
310
|
+
without relationships), and every property (with its value constraint and
|
|
311
|
+
flags, a reference-valued one additionally naming its target
|
|
312
|
+
artifacts and object kinds and its cardinality, and acting as an edge
|
|
313
|
+
of the diagrams). When several configuration files are merged, every
|
|
314
|
+
object also names the files contributing it.
|
|
222
315
|
|
|
223
316
|
- `-o|--output [<format>:]<output-file>` (`export` only):
|
|
224
317
|
The output file (`-` for stdout) is required and can be given multiple times.
|
|
@@ -230,8 +323,9 @@ Options:
|
|
|
230
323
|
|
|
231
324
|
- `-w|--watch` (`export` only):
|
|
232
325
|
Keep the outputs in sync with their sources: after the regular export,
|
|
233
|
-
the YAML schema configuration files, the
|
|
234
|
-
|
|
326
|
+
the YAML schema configuration files, the specification files, all
|
|
327
|
+
assets they embed, and the base directory itself (for added and removed
|
|
328
|
+
`.md` files) are observed, and every change re-exports the
|
|
235
329
|
specification once the sources stayed silent for one second. A failed
|
|
236
330
|
re-export is reported and leaves the observe loop intact, so a
|
|
237
331
|
transiently invalid specification (or configuration) does not end the
|
|
@@ -244,9 +338,12 @@ Options:
|
|
|
244
338
|
Omit content aspects (comma-separated, repeatable) from the HTML and
|
|
245
339
|
PDF outputs at generation time, instead of just leaving them foldable
|
|
246
340
|
in the browser. The aspects match the folding controls of the HTML
|
|
247
|
-
export: `diagram:graph`, `diagram:hub`, `diagram:grid`,
|
|
248
|
-
`diagram:
|
|
249
|
-
|
|
341
|
+
export: `diagram:graph`, `diagram:hub`, `diagram:grid`, `diagram:state`,
|
|
342
|
+
`diagram:layer`, `diagram:slice`, `diagram:tree`, `diagram:matrix`,
|
|
343
|
+
`diagram:sequence`, `diagram:petri`, `diagram:gantt`, `diagram:code`
|
|
344
|
+
(Mermaid/D2), `diagram:image` (images and PDF pages), and
|
|
345
|
+
`diagram:listing` (code listings) omit all diagrams of a type,
|
|
346
|
+
`diagram:1` (alias: `diagram`), `diagram:2`, and
|
|
250
347
|
`diagram:3` omit all diagrams from an object tree nesting level on
|
|
251
348
|
(level 1 hence all, including the "Diagram of Contents" page), and
|
|
252
349
|
`text:long` cuts every table cell whose estimated number of text
|
|
@@ -272,6 +369,28 @@ Options:
|
|
|
272
369
|
the connection state: its plug icon carries the search highlight
|
|
273
370
|
color while disconnected and blinks for 2s after every update.
|
|
274
371
|
|
|
372
|
+
- `-P|--param <name>=<value>`, `<selector>` (`query` only):
|
|
373
|
+
Query the specification (strictly validated like `export`) with the
|
|
374
|
+
XPath-like selector of [ASTq](https://github.com/rse/astq) and write
|
|
375
|
+
the matched nodes as an array (their subtrees included, the embedded
|
|
376
|
+
file contents dropped), where `-P|--param` (repeatable) gives the
|
|
377
|
+
value of a `{name}` parameter of the selector.
|
|
378
|
+
The root node is of type `specification`, its children are of type
|
|
379
|
+
`artifact` (attributes `created`, `modified`, and `file`), and the
|
|
380
|
+
objects below are typed by their kind (attributes `kind`, `id`,
|
|
381
|
+
`anchor`, `paren`, `name`, `primary`, `description`, `rationale`,
|
|
382
|
+
`elaboration`, and one per property key), e.g.
|
|
383
|
+
`specbook query "// USE-CASE [ @ACTOR == '[[ROLE:attendee]]' ]"`. The
|
|
384
|
+
query function `refs()` yields the objects the references of an object
|
|
385
|
+
resolve to, e.g. `specbook query "// REQUIREMENT [ count(refs()) == 0 ]"`.
|
|
386
|
+
|
|
387
|
+
- `-f|--format <format>`, `-o|--output [<format>:]<output-file>` (`query` only):
|
|
388
|
+
The output file (default: `-` for stdout) receives the matched nodes
|
|
389
|
+
in the format `json`, `json5`, `yaml`, or `toon`, where an explicit
|
|
390
|
+
`-f|--format` wins and the format is otherwise inferred exactly like
|
|
391
|
+
for an `export` output (a `<format>:` prefix, else the filename
|
|
392
|
+
extension, while plain `-` defaults to JSON).
|
|
393
|
+
|
|
275
394
|
- `-o|--output <output-file>` (`describe` only):
|
|
276
395
|
The output file (default: `-` for stdout) receives the described
|
|
277
396
|
Markdown document.
|
|
@@ -287,7 +406,8 @@ Options:
|
|
|
287
406
|
raw file content), so the configuration costs fewer tokens: `0`
|
|
288
407
|
emits it verbatim, `1` re-emits it with 2-space indentation, unwrapped
|
|
289
408
|
lines, and without comments, `2` additionally leaves out its `refs`,
|
|
290
|
-
`diagram`, and `format` fields, and `3`
|
|
409
|
+
`badge`, `multiple`, `diagram`, and `format` fields, and `3`
|
|
410
|
+
additionally leaves out its
|
|
291
411
|
`desc` fields of objects and properties. The MCP tool `specbook_describe` defaults to
|
|
292
412
|
`2` instead, as its consumer is an LLM.
|
|
293
413
|
|
|
@@ -317,8 +437,8 @@ basedir: docs/spec
|
|
|
317
437
|
```
|
|
318
438
|
|
|
319
439
|
The entry `config` is a single file or glob pattern or a list of them
|
|
320
|
-
(exactly like the repeatable `-c|--config`, including the
|
|
321
|
-
`std`), and the entry `basedir` is a directory. Relative paths resolve
|
|
440
|
+
(exactly like the repeatable `-c|--config`, including the literals
|
|
441
|
+
`std`, `meta`, and `pm`), and the entry `basedir` is a directory. Relative paths resolve
|
|
322
442
|
against the directory of the `.specbook.yaml` itself, the file is
|
|
323
443
|
validated (an unknown entry or a wrongly typed value fails the command),
|
|
324
444
|
and both an explicitly supplied option and its environment variable
|
|
@@ -326,7 +446,12 @@ win over its entry.
|
|
|
326
446
|
|
|
327
447
|
`specbook init` creates such a file in the current working directory
|
|
328
448
|
(unless one already applies), so the options of the initialization
|
|
329
|
-
stick for all subsequent commands.
|
|
449
|
+
stick for all subsequent commands. With `-s|--sample` it scaffolds a
|
|
450
|
+
small sample into the created artifact files instead of the bare
|
|
451
|
+
headings -- one object per allowed object kind, with every configured
|
|
452
|
+
property carrying a placeholder value satisfying the schema and the
|
|
453
|
+
first sentence of the schema description of the kind as its statement
|
|
454
|
+
-- so the format is learnable from the generated files alone.
|
|
330
455
|
|
|
331
456
|
The default value of every CLI option `--xxx` can be overridden
|
|
332
457
|
by a corresponding `SPECBOOK_XXX` environment variable (e.g.
|
|
@@ -345,11 +470,102 @@ an executable path and any other one as a Playwright channel name
|
|
|
345
470
|
`chrome-dev`, `chrome-canary`, `msedge`, `msedge-beta`, `msedge-dev`,
|
|
346
471
|
or `msedge-canary`). The variable itself has no default value: when it
|
|
347
472
|
is unset, the downloaded Playwright Chromium is used (the equivalent of
|
|
348
|
-
`chromium`) and only if that one is absent a system-installed *Google
|
|
473
|
+
`chromium`) and, only if that one is absent, a system-installed *Google
|
|
349
474
|
Chrome* (the equivalent of `chrome`). An explicitly configured browser
|
|
350
475
|
failing to launch fails the export instead of falling back onto another
|
|
351
476
|
browser.
|
|
352
477
|
|
|
478
|
+
### API
|
|
479
|
+
|
|
480
|
+
Third-party scripts generating foreign documents out of a specification
|
|
481
|
+
load it (strictly validated like `export`) and query its AST through the
|
|
482
|
+
very same ASTq selectors as `specbook query`, retrieving the *original*
|
|
483
|
+
AST nodes:
|
|
484
|
+
|
|
485
|
+
```ts
|
|
486
|
+
import { SpecBook, type SpecObject } from "@rse/specbook"
|
|
487
|
+
|
|
488
|
+
const specbook = new SpecBook()
|
|
489
|
+
const document = await specbook.load({ basedir: "docs/spec" })
|
|
490
|
+
|
|
491
|
+
/* register a custom query function (beside the built-in "refs()") */
|
|
492
|
+
document.func("contains", (_adapter, _node, list, item) =>
|
|
493
|
+
Array.isArray(list) && list.includes(item))
|
|
494
|
+
|
|
495
|
+
/* emit the roles with the use cases referencing them as Markdown */
|
|
496
|
+
for (const role of document.query("// ROLE") as SpecObject[]) {
|
|
497
|
+
console.log(`## ${document.plain(role.name)}\n`)
|
|
498
|
+
for (const useCase of document.query("// USE-CASE [ contains(refs(), {role}) ]",
|
|
499
|
+
{ role }) as SpecObject[])
|
|
500
|
+
console.log(`- ${document.plain(useCase.name)}`)
|
|
501
|
+
}
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
The `SpecBookDocument` returned by `load()` (options like `lint`, plus
|
|
505
|
+
`schema`) carries the `specification`, its `config`, and the warning
|
|
506
|
+
`diagnostics`, and provides `query(selector, params?)`, `parent(node)`
|
|
507
|
+
(the AST nodes carrying no parent references), `func(name, fn)`, and the
|
|
508
|
+
text helpers `plain(text, from?)` and `html(text, from?)`, which render
|
|
509
|
+
a Markdown text (a description part or property value) into plain text
|
|
510
|
+
resp. an HTML fragment, replacing every `[[...]]` reference by the name
|
|
511
|
+
of its target object.
|
|
512
|
+
|
|
513
|
+
Remote References
|
|
514
|
+
-----------------
|
|
515
|
+
|
|
516
|
+
Useful schema configurations should not stay buried in individual
|
|
517
|
+
project repositories. SpecBook hence resolves *remote references*
|
|
518
|
+
wherever a schema configuration is expected (`-c|--config`, the `config`
|
|
519
|
+
entry of `.specbook.yaml`, `SPECBOOK_CONFIG`):
|
|
520
|
+
|
|
521
|
+
- `npm:<pkg>[@<range>][/<path>]`: a package of the npm registry (the
|
|
522
|
+
package perhaps scoped, the version a semver range or dist-tag,
|
|
523
|
+
default `latest`), resolved and fetched through the npm registry
|
|
524
|
+
client itself, so the `registry`, the scoped `@scope:registry`, and
|
|
525
|
+
the `//host/:_authToken` credentials of your `.npmrc` files (and the
|
|
526
|
+
`npm_config_*` environment variables) are honored, while none of the
|
|
527
|
+
scripts of the package is ever run.
|
|
528
|
+
|
|
529
|
+
- `github:<user>/<repo>[/<path>][#<ref>]`: a GitHub repository at a
|
|
530
|
+
branch, tag, or commit (default: `HEAD`), fetched as its tarball,
|
|
531
|
+
where `GITHUB_TOKEN` (or `SPECBOOK_GITHUB_TOKEN`) authenticates the
|
|
532
|
+
private repositories.
|
|
533
|
+
|
|
534
|
+
- `http[s]://<host>[:<port>]/<path>/<file>`: a single schema
|
|
535
|
+
configuration file.
|
|
536
|
+
|
|
537
|
+
The `<path>` inside a package names a schema configuration file, a glob
|
|
538
|
+
pattern of such files, or a named building block of the
|
|
539
|
+
`"specbook": { "schema": { "<name>": "<file>", ... } }` map of the
|
|
540
|
+
`package.json` of the package. An absent path resolves through the
|
|
541
|
+
`"specbook": { "schema": "<file>" }` entry of the `package.json`, then
|
|
542
|
+
through the `config` entries of the `.specbook.yaml` of the package
|
|
543
|
+
(whose remote entries resolve transitively, a cycle being an error),
|
|
544
|
+
and finally through its `index.yaml`. A package may
|
|
545
|
+
declare the SpecBook versions it supports through
|
|
546
|
+
`"engines": { "specbook": "<range>" }` of its `package.json`, which is
|
|
547
|
+
checked. The artifacts several schema configuration files define (and
|
|
548
|
+
hence merge) are reported at verbosity level `2`, and unconditionally
|
|
549
|
+
if two remote files collide, as such a merge is hardly intended.
|
|
550
|
+
|
|
551
|
+
The downloads are cached under `SPECBOOK_CACHE` (default: the native
|
|
552
|
+
cache location of the platform, like `~/Library/Caches/specbook` on
|
|
553
|
+
macOS, `%LOCALAPPDATA%\specbook\Cache` on Windows, and
|
|
554
|
+
`$XDG_CACHE_HOME/specbook` or `~/.cache/specbook` elsewhere): an exact
|
|
555
|
+
npm version or a commit hash is immutable and stays cached forever,
|
|
556
|
+
while a floating reference (a range, a branch, a tag, a URL) is
|
|
557
|
+
fetched again after five minutes. With `-F|--fetch never` (or
|
|
558
|
+
`SPECBOOK_FETCH=never`), only the cache is consulted, and a reference
|
|
559
|
+
which is not cached is an error, while `-F|--fetch always` fetches every
|
|
560
|
+
reference again.
|
|
561
|
+
|
|
562
|
+
To share a schema configuration of your own, publish it as a plain npm
|
|
563
|
+
package carrying the keyword `specbook-schema` (or push it to a GitHub
|
|
564
|
+
repository carrying the same topic), so `specbook search [<term> ...]`
|
|
565
|
+
(and the MCP tool `specbook_search`) finds it, right after the bundled
|
|
566
|
+
schema configurations `std`, `meta`, and `pm`, which it always
|
|
567
|
+
lists first (and which are all it lists under `--fetch never`).
|
|
568
|
+
|
|
353
569
|
Agent Skill
|
|
354
570
|
-----------
|
|
355
571
|
|
|
@@ -364,10 +580,13 @@ $ claude plugin install specbook@specbook
|
|
|
364
580
|
|
|
365
581
|
```text
|
|
366
582
|
/specbook [-c|--config <yaml-file>] [-b|--basedir <basedir>] [<query>]
|
|
367
|
-
/specbook init [-c|--config <yaml-file>] [-b|--basedir <basedir>]
|
|
368
|
-
|
|
369
|
-
/specbook
|
|
370
|
-
[-
|
|
583
|
+
/specbook init [-c|--config <yaml-file>] [-b|--basedir <basedir>] [-F|--fetch <mode>]
|
|
584
|
+
[-s|--sample]
|
|
585
|
+
/specbook lint [-c|--config <yaml-file>] [-b|--basedir <basedir>] [-F|--fetch <mode>]
|
|
586
|
+
[-g|--gitignore]
|
|
587
|
+
/specbook export [-c|--config <yaml-file>] [-b|--basedir <basedir>] [-F|--fetch <mode>]
|
|
588
|
+
[-g|--gitignore] [-O|--omit <aspect>[,...]]
|
|
589
|
+
[-o|--output [<format>:]<output-file>] [...]
|
|
371
590
|
/specbook edit [-c|--config <yaml-file>] [-b|--basedir <basedir>] [-g|--grill]
|
|
372
591
|
[-r|--grill-rounds <n>] [-v|--verify] [-l|--loop] [<query>]
|
|
373
592
|
```
|
|
@@ -395,7 +614,7 @@ query (`--loop`). All commands leave an absent `--config` and
|
|
|
395
614
|
Example: Simple
|
|
396
615
|
---------------
|
|
397
616
|
|
|
398
|
-
Check out the *simple* specification of simple
|
|
617
|
+
Check out the *simple* specification of a simple
|
|
399
618
|
example data model:
|
|
400
619
|
|
|
401
620
|
### Sources
|
|
@@ -446,6 +665,32 @@ $ specbook export -v \
|
|
|
446
665
|
|
|
447
666
|

|
|
448
667
|
|
|
668
|
+
Example: Project Management
|
|
669
|
+
---------------------------
|
|
670
|
+
|
|
671
|
+
Check out the *project management handbook* of the Broadcast
|
|
672
|
+
project, based on **SpecBook**'s built-in "pm" schema, which plans the
|
|
673
|
+
delivery of a solution (the project charter with its objectives,
|
|
674
|
+
constraints, assumptions, and budget, the team, the deliverables, the
|
|
675
|
+
work breakdown, the project plan as a Gantt chart, the risks and
|
|
676
|
+
opportunities, the governance, and the change log of the issues) in a
|
|
677
|
+
handbook of its own beside the specification:
|
|
678
|
+
|
|
679
|
+
### Sources
|
|
680
|
+
|
|
681
|
+
- [Specification](smp/pm/)
|
|
682
|
+
- [Schema](src/specbook-format-schema.d/)
|
|
683
|
+
|
|
684
|
+
### Generation
|
|
685
|
+
|
|
686
|
+
```bash
|
|
687
|
+
$ specbook export -v \
|
|
688
|
+
-c pm \
|
|
689
|
+
-b smp/pm \
|
|
690
|
+
-o smp/pm.html \
|
|
691
|
+
-o smp/pm.pdf
|
|
692
|
+
```
|
|
693
|
+
|
|
449
694
|
See Also
|
|
450
695
|
--------
|
|
451
696
|
|
|
@@ -458,7 +703,7 @@ Support
|
|
|
458
703
|
**SpecBook** is developed in the experience context of industrial Software
|
|
459
704
|
Engineering at the [*msg group*](https://www.msg.group) and in the
|
|
460
705
|
educational context of the *Software Engineering Academy (SEA)*. **SpecBook**
|
|
461
|
-
development is supported by *msg Research* and *Software Engineering
|
|
706
|
+
development is supported by *msg Research* and the *Software Engineering
|
|
462
707
|
Academy (SEA)*.
|
|
463
708
|
|
|
464
709
|
License
|
package/dst/specbook-api.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { projectFile } from "./specbook-project.js";
|
|
2
|
+
import { version, standardConfig, metaConfig, pmConfig, cacheDir, fetchModes, parseFetchMode, type SearchHit, type FetchMode } from "./specbook-remote.js";
|
|
2
3
|
import { renderDiagnostic, renderDiagnosticVerbose, type Diagnostic, type DiagnosticSeverity } from "./specbook-diagnostic.js";
|
|
3
4
|
import { type LintResult } from "./specbook-cmd-lint.js";
|
|
4
5
|
import { parseOutputSpec, formats, omitAspects, type ExportFormat } from "./specbook-cmd-export.js";
|
|
6
|
+
import { SpecBookDocument, renderNodes, queryFormats, parseQueryOutput, type SpecNode, type SpecQueryFunc, type SpecQueryAdapter, type QueryFormat } from "./specbook-cmd-query.js";
|
|
5
7
|
import { previewAddr, previewPort } from "./specbook-cmd-preview.js";
|
|
6
8
|
import { describeFormats, describeParts, parseDescribeFormat, parseDescribePart, compressLevels, parseCompressLevel, type DescribeFormat, type DescribePart, type CompressLevel } from "./specbook-cmd-describe.js";
|
|
7
9
|
import { literal, renderVerbose, verbosities, verbosityOf, parseVerbosity, type Verbose, type VerboseLevel, type Verbosity } from "./specbook-verbose.js";
|
|
@@ -15,10 +17,10 @@ export { compressLevels, parseCompressLevel };
|
|
|
15
17
|
export { type DescribeFormat, type DescribePart, type CompressLevel };
|
|
16
18
|
export { renderDiagnostic, renderDiagnosticVerbose, type Diagnostic, type DiagnosticSeverity };
|
|
17
19
|
export { type LintResult };
|
|
20
|
+
export { SpecBookDocument, renderNodes, queryFormats, parseQueryOutput, type SpecNode, type SpecQueryFunc, type SpecQueryAdapter, type QueryFormat };
|
|
21
|
+
export { version, standardConfig, metaConfig, pmConfig, cacheDir, fetchModes, parseFetchMode, type FetchMode, type SearchHit };
|
|
18
22
|
export type { Spec, SpecArtifact, SpecObject, SpecDescription, SpecProperty } from "./specbook-format-spec.js";
|
|
19
23
|
export type { Schema, SchemaObject, SchemaProperty } from "./specbook-format-schema.js";
|
|
20
|
-
export declare const version: string;
|
|
21
|
-
export declare const standardConfig: string;
|
|
22
24
|
export type VerboseSink = (cmd: string, msg: string, level: VerboseLevel) => void;
|
|
23
25
|
export interface SpecBookOptions {
|
|
24
26
|
verbose?: VerboseSink;
|
|
@@ -27,16 +29,23 @@ export interface ProjectOptions {
|
|
|
27
29
|
config?: string[];
|
|
28
30
|
basedir?: string;
|
|
29
31
|
cwd?: string;
|
|
32
|
+
fetch?: FetchMode;
|
|
30
33
|
}
|
|
31
34
|
export interface InitResult {
|
|
32
35
|
files: string[];
|
|
33
36
|
project?: string;
|
|
34
37
|
}
|
|
38
|
+
export interface SearchRequest {
|
|
39
|
+
term?: string;
|
|
40
|
+
cwd?: string;
|
|
41
|
+
fetch?: FetchMode;
|
|
42
|
+
}
|
|
35
43
|
export interface ExportRequest extends ProjectOptions {
|
|
36
44
|
formats?: ExportFormat[];
|
|
37
45
|
realtime?: boolean;
|
|
38
46
|
omit?: string[];
|
|
39
47
|
gitignore?: boolean;
|
|
48
|
+
schema?: boolean;
|
|
40
49
|
rebase?: (string | undefined)[];
|
|
41
50
|
}
|
|
42
51
|
export interface WatchRequest extends ExportRequest {
|
|
@@ -48,14 +57,24 @@ export declare class SpecBook {
|
|
|
48
57
|
constructor(options?: SpecBookOptions);
|
|
49
58
|
private verboseOf;
|
|
50
59
|
private project;
|
|
60
|
+
private remoteOptions;
|
|
51
61
|
private configFiles;
|
|
52
62
|
private requireConfig;
|
|
53
|
-
init(options: ProjectOptions
|
|
63
|
+
init(options: ProjectOptions & {
|
|
64
|
+
sample?: boolean;
|
|
65
|
+
}): Promise<InitResult>;
|
|
54
66
|
lint(options: ProjectOptions & {
|
|
55
67
|
gitignore?: boolean;
|
|
56
68
|
}): Promise<LintResult>;
|
|
69
|
+
load(options: ProjectOptions & {
|
|
70
|
+
gitignore?: boolean;
|
|
71
|
+
schema?: boolean;
|
|
72
|
+
}): Promise<SpecBookDocument>;
|
|
73
|
+
search(options: SearchRequest): Promise<SearchHit[]>;
|
|
57
74
|
private renderFormats;
|
|
58
75
|
private rebaseOf;
|
|
76
|
+
private guardRebase;
|
|
77
|
+
private parseSource;
|
|
59
78
|
export(options: ExportRequest): Promise<Buffer[]>;
|
|
60
79
|
private observe;
|
|
61
80
|
watch(options: WatchRequest): Promise<void>;
|
|
@@ -64,6 +83,7 @@ export declare class SpecBook {
|
|
|
64
83
|
port?: number;
|
|
65
84
|
omit?: string[];
|
|
66
85
|
gitignore?: boolean;
|
|
86
|
+
schema?: boolean;
|
|
67
87
|
}): Promise<void>;
|
|
68
88
|
describe(options: ProjectOptions & {
|
|
69
89
|
embed?: boolean;
|