@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.
Files changed (63) hide show
  1. package/LICENSE.txt +201 -0
  2. package/README.md +288 -43
  3. package/dst/specbook-api.d.ts +23 -3
  4. package/dst/specbook-api.js +133 -59
  5. package/dst/specbook-cli.js +93 -26
  6. package/dst/specbook-cmd-describe.js +4 -4
  7. package/dst/specbook-cmd-export-schema.d.ts +8 -0
  8. package/dst/specbook-cmd-export-schema.js +441 -0
  9. package/dst/specbook-cmd-export.js +23 -6
  10. package/dst/specbook-cmd-init-sample.d.ts +4 -0
  11. package/dst/specbook-cmd-init-sample.js +322 -0
  12. package/dst/specbook-cmd-init.d.ts +1 -0
  13. package/dst/specbook-cmd-init.js +42 -10
  14. package/dst/specbook-cmd-lint.js +46 -48
  15. package/dst/specbook-cmd-query.d.ts +30 -0
  16. package/dst/specbook-cmd-query.js +165 -0
  17. package/dst/specbook-config.d.ts +9 -1
  18. package/dst/specbook-config.js +135 -10
  19. package/dst/specbook-coverage.js +2 -2
  20. package/dst/specbook-diagram.d.ts +7 -5
  21. package/dst/specbook-diagram.js +546 -143
  22. package/dst/specbook-export-ast.d.ts +1 -1
  23. package/dst/specbook-export-ast.js +11 -8
  24. package/dst/specbook-export-code.js +3 -3
  25. package/dst/specbook-export-common.d.ts +1 -1
  26. package/dst/specbook-export-common.js +3 -2
  27. package/dst/specbook-export-diagram.d.ts +1 -1
  28. package/dst/specbook-export-diagram.js +25 -7
  29. package/dst/specbook-export-html-fold.d.ts +16 -6
  30. package/dst/specbook-export-html-fold.js +65 -44
  31. package/dst/specbook-export-html-render.js +107 -26
  32. package/dst/specbook-export-html-search.js +18 -20
  33. package/dst/specbook-export-html-template.js +38 -9
  34. package/dst/specbook-export-html-widget.d.ts +2 -0
  35. package/dst/specbook-export-html-widget.js +219 -19
  36. package/dst/specbook-export-html.css +208 -38
  37. package/dst/specbook-export-html.js +96 -53
  38. package/dst/specbook-export-md.d.ts +2 -1
  39. package/dst/specbook-export-md.js +7 -8
  40. package/dst/specbook-export-pdf.js +1 -1
  41. package/dst/specbook-files.d.ts +2 -0
  42. package/dst/specbook-files.js +41 -0
  43. package/dst/specbook-format-meta.yaml +401 -0
  44. package/dst/specbook-format-pm.yaml +1240 -0
  45. package/dst/specbook-format-schema.d.ts +33 -3
  46. package/dst/specbook-format-schema.js +49 -3
  47. package/dst/specbook-format.md +427 -47
  48. package/dst/specbook-format.yaml +524 -228
  49. package/dst/specbook-ignore.js +2 -2
  50. package/dst/specbook-link.d.ts +4 -0
  51. package/dst/specbook-link.js +61 -6
  52. package/dst/specbook-mcp.js +103 -19
  53. package/dst/specbook-parse-semantic.d.ts +1 -0
  54. package/dst/specbook-parse-semantic.js +11 -4
  55. package/dst/specbook-parse-syntax.d.ts +1 -0
  56. package/dst/specbook-parse-syntax.js +1 -1
  57. package/dst/specbook-parse.d.ts +1 -1
  58. package/dst/specbook-parse.js +3 -3
  59. package/dst/specbook-project.d.ts +2 -0
  60. package/dst/specbook-project.js +15 -5
  61. package/dst/specbook-remote.d.ts +28 -0
  62. package/dst/specbook-remote.js +429 -0
  63. package/package.json +32 -20
@@ -0,0 +1,41 @@
1
+ /*
2
+ ** Specification Book (SpecBook)
3
+ ** Copyright (c) 2026 Dr. Ralf S. Engelschall <rse@engelschall.com>
4
+ ** Licensed under Apache 2.0 <https://spdx.org/licenses/Apache-2.0>
5
+ */
6
+ import * as fs from "node:fs";
7
+ import * as path from "node:path";
8
+ /* collect the specification Markdown files below the base directory:
9
+ every ".md" file, recursively, as all of them are taken for SpecBook
10
+ ones, except below the "."-prefixed entries (like ".git"), sorted by
11
+ path for a deterministic parse order (the artifacts are ordered
12
+ along the schema configuration afterwards anyway) */
13
+ export const specFiles = (basedir) => {
14
+ const files = new Array();
15
+ const scan = (dir) => {
16
+ let entries;
17
+ try {
18
+ entries = fs.readdirSync(dir, { withFileTypes: true });
19
+ }
20
+ catch {
21
+ /* an unreadable directory contributes no files */
22
+ return;
23
+ }
24
+ for (const entry of entries) {
25
+ if (entry.name.startsWith("."))
26
+ continue;
27
+ const file = path.join(dir, entry.name);
28
+ if (entry.isDirectory())
29
+ scan(file);
30
+ else if (entry.isFile() && path.extname(entry.name) === ".md")
31
+ files.push(file);
32
+ }
33
+ };
34
+ scan(basedir);
35
+ return files.sort();
36
+ };
37
+ /* whether a file or directory resides at or below a directory */
38
+ export const isBelow = (file, dir) => {
39
+ const rel = path.relative(path.resolve(dir), path.resolve(file));
40
+ return rel === "" || (!path.isAbsolute(rel) && rel !== ".." && !rel.startsWith(`..${path.sep}`));
41
+ };
@@ -0,0 +1,401 @@
1
+ ##
2
+ ## Specification Book (SpecBook)
3
+ ## Copyright (c) 2026 Dr. Ralf S. Engelschall <rse@engelschall.com>
4
+ ## Licensed under Apache 2.0 <https://spdx.org/licenses/Apache-2.0>
5
+ ##
6
+
7
+ # This is the "Meta" SpecBook schema.
8
+ #
9
+ # Modeling Purpose
10
+ # ----------------
11
+ #
12
+ # This schema describes a SpecBook schema configuration itself as a SpecBook
13
+ # specification ("eat your own dogfood"): its artifact kinds, their artifacts,
14
+ # the object kinds nested below them, and the properties and references of
15
+ # all of them. The "specbook export --schema" and "specbook preview --schema"
16
+ # commands generate such a specification in memory out of the effective schema
17
+ # configuration and render it through this schema, while "-c meta" also allows
18
+ # a specification to be authored against it directly.
19
+ #
20
+ # Modeling Decisions
21
+ # ------------------
22
+ #
23
+ # - The artifact kinds are the level 1 objects, so they head the
24
+ # table of contents: as their number and names depend on the
25
+ # described schema configuration, ARTIFACT-KIND is a recurring
26
+ # artifact (configured with neither name nor id), which any
27
+ # number of level 1 objects of its kind match.
28
+ #
29
+ # - The object kinds of an artifact are listed flat below it, as the
30
+ # nesting of a schema configuration is unbounded, while a schema
31
+ # bounds it: the PARENT reference of an object kind names the
32
+ # artifact or object kind it is nested directly below.
33
+ #
34
+ # - A reference-valued property is a REFERENCE object, so it acts as
35
+ # the edge of the diagrams (from its object kind to every TARGET),
36
+ # while every other property is a PROPERTY object.
37
+ #
38
+
39
+ - kind: META
40
+ name: Title
41
+ id: TI
42
+ file: 00-META-TI-Title.md
43
+ desc: >
44
+ The top-level meta information of the schema configuration document.
45
+ Some of the information is rendered onto the title page.
46
+ optional: true
47
+ diagram:
48
+ type: graph
49
+ nodes: "[[ARTIFACT-KIND:*]], [[ARTIFACT:*]]"
50
+ deep: true
51
+ ordered: true
52
+ nest:
53
+ parent: true
54
+ crossing: target
55
+ config:
56
+ graph-columns-max: 2
57
+ props:
58
+ - name: LOGO
59
+ desc: The logo of the document.
60
+ optional: true
61
+ - name: TITLE
62
+ desc: The title of the document.
63
+ optional: true
64
+ - name: SUBTITLE
65
+ desc: The subtitle of the document.
66
+ optional: true
67
+ - name: AUTHOR
68
+ desc: The author of the document.
69
+ optional: true
70
+ - name: VERSION
71
+ desc: The version of the document.
72
+ optional: true
73
+ - name: LANG
74
+ desc: The language of the document texts (ISO 639-1 code).
75
+ value: /^[a-z]{2}(-[A-Za-z0-9]+)?$/
76
+ optional: true
77
+ - name: CHARSET
78
+ desc: The character set the embedded fonts are subsetted to.
79
+ value: enum(US-ASCII,ISO-8859-1,ISO-Latin-1,ISO-8859-15,ISO-Latin-15,UTF-8)
80
+ optional: true
81
+ - name: PAPER-SIZE
82
+ desc: The paper size the print/PDF rendering is targeted at.
83
+ value: enum(A4,Letter,Legal)
84
+ optional: true
85
+ - name: THEME-STYLE
86
+ desc: The theme style.
87
+ value: enum(Dark,Light)
88
+ optional: true
89
+ - name: THEME-TONE
90
+ desc: The theme color tone, optionally followed by the complement color tone (else derived).
91
+ value: /^#[0-9a-fA-F]{6}(\s+#[0-9a-fA-F]{6})?$/
92
+ optional: true
93
+
94
+ - kind: ARTIFACT-KIND
95
+ file: 10-ARTIFACT-KINDS.md
96
+ desc: >
97
+ An artifact kind of the schema configuration, i.e. the
98
+ `kind` of its level 1 objects (like `REQS`), grouping all
99
+ artifacts of this kind. The diagram shows the relationships
100
+ among the object kinds of the artifact kind, with the
101
+ object kinds nested into their artifacts and parent kinds.
102
+ diagram:
103
+ type: graph
104
+ nodes: "[[ARTIFACT:*]], [[OBJECT-KIND:*]]"
105
+ edges: "[[REFERENCE:*]]"
106
+ local: true
107
+ nest:
108
+ properties:
109
+ - PARENT
110
+ props:
111
+ - name: ORIGIN
112
+ desc: >
113
+ The schema configuration file(s) contributing the
114
+ artifact kind (present when several files are merged).
115
+ optional: true
116
+ children:
117
+ - kind: ARTIFACT
118
+ desc: >
119
+ An artifact of the schema configuration, i.e. one of
120
+ its level 1 object kinds, named after its `name` and
121
+ identified by its `id`. The diagram shows the
122
+ references from and to the artifact itself.
123
+ optional: true
124
+ diagram:
125
+ type: hub
126
+ nodes: "[[ARTIFACT:*]], [[OBJECT-KIND:*]]"
127
+ edges: "[[REFERENCE:*]]"
128
+ labeled: true
129
+ props:
130
+ - name: ORIGIN
131
+ desc: >
132
+ The schema configuration file(s) contributing
133
+ the artifact (present when several files are merged).
134
+ optional: true
135
+ - name: FILE
136
+ desc: The Markdown file the artifact resides in (`file`).
137
+ optional: true
138
+ - name: OPTIONAL
139
+ desc: Whether the artifact may be absent from its file (`optional`).
140
+ value: enum(true,false)
141
+ - name: REFERENCED
142
+ desc: >
143
+ The reference patterns matching the objects from which every
144
+ object of the kind has to be referenced (`referenced`).
145
+ optional: true
146
+ - name: COVERAGE
147
+ desc: >
148
+ The reference patterns matching the objects whose reference
149
+ coverage every object of the kind reports (`coverage`).
150
+ optional: true
151
+ - name: AUTOMATON
152
+ desc: The finite state machine the child objects form (`automaton`).
153
+ optional: true
154
+ - name: BADGE
155
+ desc: The badge icon of the objects of the kind in the diagrams (`badge`).
156
+ optional: true
157
+ - name: MULTIPLE
158
+ desc: The multiplicity of the objects of the kind in the diagrams (`multiple`).
159
+ optional: true
160
+ - name: DIAGRAM
161
+ desc: The diagram(s) derived for every object of the kind (`diagram`).
162
+ optional: true
163
+ - name: FORMAT
164
+ desc: The HTML/PDF rendering format of the objects of the kind (`format`).
165
+ optional: true
166
+ children:
167
+ - kind: OBJECT-KIND
168
+ desc: >
169
+ An object kind nested (directly or deeper, see `PARENT`)
170
+ below the artifact. The diagram shows the references
171
+ from and to the object kind.
172
+ optional: true
173
+ diagram:
174
+ type: hub
175
+ nodes: "[[ARTIFACT:*]], [[OBJECT-KIND:*]]"
176
+ edges: "[[REFERENCE:*]]"
177
+ labeled: true
178
+ props:
179
+ - name: ORIGIN
180
+ desc: >
181
+ The schema configuration file(s) contributing
182
+ the object kind (present when several files are merged).
183
+ optional: true
184
+ - name: PARENT
185
+ desc: >
186
+ The artifact or object kind the object kind is
187
+ nested directly below (`children`).
188
+ value: list([[ARTIFACT:*]], [[OBJECT-KIND:*]])
189
+ - name: NAME
190
+ desc: The regular expression the object names have to match (`name`).
191
+ optional: true
192
+ - name: OPTIONAL
193
+ desc: Whether the object kind may be absent below its parent (`optional`).
194
+ value: enum(true,false)
195
+ - name: REFERENCED
196
+ desc: >
197
+ The reference patterns matching the objects from which every
198
+ object of the kind has to be referenced (`referenced`).
199
+ optional: true
200
+ - name: COVERAGE
201
+ desc: >
202
+ The reference patterns matching the objects whose reference
203
+ coverage every object of the kind reports (`coverage`).
204
+ optional: true
205
+ - name: AUTOMATON
206
+ desc: The finite state machine the child objects form (`automaton`).
207
+ optional: true
208
+ - name: BADGE
209
+ desc: The badge icon of the objects of the kind in the diagrams (`badge`).
210
+ optional: true
211
+ - name: MULTIPLE
212
+ desc: The multiplicity of the objects of the kind in the diagrams (`multiple`).
213
+ optional: true
214
+ - name: DIAGRAM
215
+ desc: The diagram(s) derived for every object of the kind (`diagram`).
216
+ optional: true
217
+ - name: FORMAT
218
+ desc: The HTML/PDF rendering format of the objects of the kind (`format`).
219
+ optional: true
220
+ children:
221
+ - kind: PROPERTY
222
+ desc: >
223
+ A property allowed on the objects of the kind, with
224
+ its value constraint and its flags.
225
+ optional: true
226
+ props:
227
+ - name: ORIGIN
228
+ desc: >
229
+ The schema configuration file(s) contributing
230
+ the property (present when several files are merged).
231
+ optional: true
232
+ - name: OPTIONAL
233
+ desc: Whether the property may be absent (`optional`).
234
+ value: enum(true,false)
235
+ - name: VALUE
236
+ desc: The value constraint of the property (`value`).
237
+ optional: true
238
+ - name: UNIQUE
239
+ desc: >
240
+ The uniqueness of the value among the sibling objects
241
+ (`unique`): `true`, or the expression selecting the values.
242
+ optional: true
243
+ - name: PRESENT
244
+ desc: >
245
+ The presence of the value among the sibling objects
246
+ (`present`): `true`, or the expression selecting the values.
247
+ optional: true
248
+ - name: LOCAL
249
+ desc: Whether the referenced objects have to lie below the parent object (`local`).
250
+ value: enum(true)
251
+ optional: true
252
+ - name: SYMMETRIC
253
+ desc: Whether the referenced objects have to reference back (`symmetric`).
254
+ value: enum(true)
255
+ optional: true
256
+ - name: ACYCLIC
257
+ desc: Whether the references must not form a cycle (`acyclic`).
258
+ value: enum(true)
259
+ optional: true
260
+ - kind: REFERENCE
261
+ desc: >
262
+ A reference-valued property allowed on the objects
263
+ of the kind, drawn as an edge from the object kind
264
+ to every object kind its `TARGET` names.
265
+ optional: true
266
+ format:
267
+ type: compact
268
+ props:
269
+ - name: ORIGIN
270
+ desc: >
271
+ The schema configuration file(s) contributing
272
+ the property (present when several files are merged).
273
+ optional: true
274
+ - name: OPTIONAL
275
+ desc: Whether the property may be absent (`optional`).
276
+ value: enum(true,false)
277
+ - name: VALUE
278
+ desc: The value constraint of the property (`value`).
279
+ optional: true
280
+ - name: TARGET
281
+ desc: The artifacts and object kinds the value constraint references.
282
+ value: list([[ARTIFACT:*]], [[OBJECT-KIND:*]])
283
+ - name: ARITY
284
+ desc: >
285
+ The cardinality of the reference: `1` (a single required
286
+ reference), `0..1` (a single optional one), `1..n` (a
287
+ required list), or `0..n` (an optional list).
288
+ value: enum(1,0..1,1..n,0..n)
289
+ - name: UNIQUE
290
+ desc: >
291
+ The uniqueness of the value among the sibling objects
292
+ (`unique`): `true`, or the expression selecting the values.
293
+ optional: true
294
+ - name: PRESENT
295
+ desc: >
296
+ The presence of the value among the sibling objects
297
+ (`present`): `true`, or the expression selecting the values.
298
+ optional: true
299
+ - name: LOCAL
300
+ desc: Whether the referenced objects have to lie below the parent object (`local`).
301
+ value: enum(true)
302
+ optional: true
303
+ - name: SYMMETRIC
304
+ desc: Whether the referenced objects have to reference back (`symmetric`).
305
+ value: enum(true)
306
+ optional: true
307
+ - name: ACYCLIC
308
+ desc: Whether the references must not form a cycle (`acyclic`).
309
+ value: enum(true)
310
+ optional: true
311
+ - kind: PROPERTY
312
+ desc: >
313
+ A property allowed on the artifact itself, with
314
+ its value constraint and its flags.
315
+ optional: true
316
+ props:
317
+ - name: ORIGIN
318
+ desc: >
319
+ The schema configuration file(s) contributing
320
+ the property (present when several files are merged).
321
+ optional: true
322
+ - name: OPTIONAL
323
+ desc: Whether the property may be absent (`optional`).
324
+ value: enum(true,false)
325
+ - name: VALUE
326
+ desc: The value constraint of the property (`value`).
327
+ optional: true
328
+ - name: UNIQUE
329
+ desc: >
330
+ The uniqueness of the value among the sibling objects
331
+ (`unique`): `true`, or the expression selecting the values.
332
+ optional: true
333
+ - name: PRESENT
334
+ desc: >
335
+ The presence of the value among the sibling objects
336
+ (`present`): `true`, or the expression selecting the values.
337
+ optional: true
338
+ - name: LOCAL
339
+ desc: Whether the referenced objects have to lie below the parent object (`local`).
340
+ value: enum(true)
341
+ optional: true
342
+ - name: SYMMETRIC
343
+ desc: Whether the referenced objects have to reference back (`symmetric`).
344
+ value: enum(true)
345
+ optional: true
346
+ - name: ACYCLIC
347
+ desc: Whether the references must not form a cycle (`acyclic`).
348
+ value: enum(true)
349
+ optional: true
350
+ - kind: REFERENCE
351
+ desc: >
352
+ A reference-valued property allowed on the artifact
353
+ itself, drawn as an edge from the artifact to every
354
+ object kind its `TARGET` names.
355
+ optional: true
356
+ format:
357
+ type: compact
358
+ props:
359
+ - name: ORIGIN
360
+ desc: >
361
+ The schema configuration file(s) contributing
362
+ the property (present when several files are merged).
363
+ optional: true
364
+ - name: OPTIONAL
365
+ desc: Whether the property may be absent (`optional`).
366
+ value: enum(true,false)
367
+ - name: VALUE
368
+ desc: The value constraint of the property (`value`).
369
+ optional: true
370
+ - name: TARGET
371
+ desc: The artifacts and object kinds the value constraint references.
372
+ value: list([[ARTIFACT:*]], [[OBJECT-KIND:*]])
373
+ - name: ARITY
374
+ desc: >
375
+ The cardinality of the reference: `1` (a single required
376
+ reference), `0..1` (a single optional one), `1..n` (a
377
+ required list), or `0..n` (an optional list).
378
+ value: enum(1,0..1,1..n,0..n)
379
+ - name: UNIQUE
380
+ desc: >
381
+ The uniqueness of the value among the sibling objects
382
+ (`unique`): `true`, or the expression selecting the values.
383
+ optional: true
384
+ - name: PRESENT
385
+ desc: >
386
+ The presence of the value among the sibling objects
387
+ (`present`): `true`, or the expression selecting the values.
388
+ optional: true
389
+ - name: LOCAL
390
+ desc: Whether the referenced objects have to lie below the parent object (`local`).
391
+ value: enum(true)
392
+ optional: true
393
+ - name: SYMMETRIC
394
+ desc: Whether the referenced objects have to reference back (`symmetric`).
395
+ value: enum(true)
396
+ optional: true
397
+ - name: ACYCLIC
398
+ desc: Whether the references must not form a cycle (`acyclic`).
399
+ value: enum(true)
400
+ optional: true
401
+