speckeeper 0.9.2 → 0.9.3

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.
@@ -0,0 +1,67 @@
1
+ # Model Entity Catalog
2
+
3
+ Created: 2026-02-03
4
+ Version: 0.5
5
+
6
+ ---
7
+
8
+ ## 1. Overview
9
+
10
+ This document is a catalog of models defined in speckeeper and registered in the framework.
11
+
12
+ ---
13
+
14
+ ## 2. Registered Models
15
+
16
+ Models defined in `design/_models/` and registered in speckeeper:
17
+
18
+ <!--@embedoc:models format="full-table"-->
19
+ | Model ID | Name | Level | Lint | Export | External SSOT | Coverage | Description |
20
+ |----------|------|-------|------|--------|---------------|----------|-------------|
21
+ | `usecase` | UseCase | L0 | ✅ | ✅ | - | - | Defines use cases (business flows) |
22
+ | `actor` | Actor | L0 | ✅ | ✅ | - | - | Defines actors |
23
+ | `term` | Term | L0 | ✅ | ✅ | - | - | Defines terms (glossary) |
24
+ | `functional-requirement` | Functional Requirement | L1 | ✅ | ✅ | - | ✅ | Defines functional requirements |
25
+ | `nonfunctional-requirement` | Non-Functional Requirement | L1 | ✅ | ✅ | - | - | Defines non-functional requirements (quality attributes) |
26
+ | `constraint` | Constraint | L1 | ✅ | ✅ | - | - | Defines constraints |
27
+ | `entity` | Entity | L2 | ✅ | ✅ | - | ✅ | Defines conceptual entities (domain model) |
28
+ | `actor-component` | Actor (Architecture) | L2 | ✅ | ✅ | - | - | Defines actors (people) in the architecture |
29
+ | `external-system` | External System | L2 | ✅ | ✅ | - | - | Defines external systems |
30
+ | `container` | Container | L2 | ✅ | ✅ | - | ✅ | Defines containers (deployable units) |
31
+ | `boundary` | Boundary | L2 | ❌ | ❌ | - | - | Defines system boundaries (context) |
32
+ | `layer` | Layer | L2 | ❌ | ❌ | - | - | Defines architecture layers |
33
+ | `relation` | Relation | L2 | ✅ | ❌ | - | - | Defines relations between components |
34
+ | `artifact` | Artifact | L3 | ✅ | ✅ | - | - | Defines artifacts (docs/, specs/) |
35
+ | `directory-entry` | DirectoryEntry | L3 | ✅ | ✅ | - | - | Defines directory structure |
36
+ | `cli-command` | CLICommand | L3 | ✅ | ✅ | ✅ | - | Defines CLI command specifications |
37
+ | `test-ref` | TestRef | L3 | ✅ | ✅ | ✅ Test Code | ✅ | Test reference (association between test code and requirements) |
38
+ <!--@embedoc:end-->
39
+
40
+ ---
41
+
42
+ ## 3. SSOT Types
43
+
44
+ Each entity has a clear SSOT (Single Source of Truth) type indicating where it should be managed.
45
+
46
+ | SSOT Type | Description | Example |
47
+ |---------|------|-----|
48
+ | **TS-SSOT** | Managed in this framework's TypeScript models | Requirements, concept model, screen specs |
49
+ | **External SSOT** | Managed directly in existing tools/formats. TS only references them | OpenAPI, DDL, IaC |
50
+ | **TS-Ref** | TS holds only reference information (ID, path, etc.) and links to external SSOT | APIRef, TableRef |
51
+
52
+ ---
53
+
54
+ ## 4. Model Levels
55
+
56
+ Models are classified by abstraction level:
57
+
58
+ | Level | Name | Description | Examples |
59
+ |-------|------|-------------|----------|
60
+ | L0 | Business + Domain | Why / Problem space - Goals, business flows, actors, terms, business rules | UseCase, Actor, Term |
61
+ | L1 | Requirements | What - Functional/non-functional requirements, constraints, acceptance criteria | Requirement |
62
+ | L2 | Design | How (approach) - Architecture, component decomposition, domain model, main sequences | Component, Entity, Layer, Boundary |
63
+ | L3 | Detailed Design / Implementation | How to build - Screen/API/DB definitions, external SSOT references | Artifact, DirectoryEntry, CLICommand, TestRef |
64
+
65
+ ---
66
+
67
+ End of document
@@ -0,0 +1,357 @@
1
+ # speckeeper scaffold: Mermaid Input Specification
2
+
3
+ The `speckeeper scaffold` command takes a mermaid flowchart describing a specification metamodel as input and auto-generates skeleton code for `design/_models/` and spec data files.
4
+
5
+ This document defines the format, constraints, and vocabulary of the mermaid flowchart accepted by scaffold.
6
+
7
+ ---
8
+
9
+ ## 1. Overall Structure
10
+
11
+ A Markdown file processed by scaffold must contain one or more mermaid code blocks. scaffold processes the first `flowchart` block found.
12
+
13
+ ```mermaid
14
+ flowchart TB
15
+ Node definitions
16
+ Edge definitions
17
+ classDef / class definitions
18
+ ```
19
+
20
+ - The direction specifier (`TB`, `LR`, etc.) is optional and does not affect scaffold behavior.
21
+ - The `graph` keyword is treated equivalently to `flowchart`.
22
+ - Lines starting with `%%` are ignored as comments.
23
+
24
+ ---
25
+
26
+ ## 2. Node Definitions
27
+
28
+ ### 2.1 Syntax
29
+
30
+ ```
31
+ ID[Label]
32
+ ```
33
+
34
+ | Element | Required | Description |
35
+ |---------|----------|-------------|
36
+ | `ID` | Required | Alphanumeric characters and underscores. Must start with a letter or underscore |
37
+ | `[Label]` | Optional | Display text enclosed in square brackets. May contain any characters. If omitted, the ID is used as the label |
38
+
39
+ ### 2.2 Node Declaration Locations
40
+
41
+ Nodes may first appear within edge definitions. When the same ID appears multiple times, the first definition with a label takes precedence.
42
+
43
+ ```
44
+ SR -->|refines| FR[Functional Requirement] %% FR label defined here
45
+ FR -->|includes| AT[Acceptance Test] %% FR already defined, label ignored
46
+ ```
47
+
48
+ ---
49
+
50
+ ## 3. Subgraph Definitions
51
+
52
+ Subgraphs determine the model level (L0–L3) for all nodes contained within them. The level is inferred from the subgraph label using keyword matching (case-insensitive).
53
+
54
+ | Subgraph Label Pattern | Inferred Level |
55
+ |------------------------|----------------|
56
+ | `L0`, `Business`, `Domain` | L0 |
57
+ | `L1`, `Requirements` | L1 |
58
+ | `L2`, `Design`, `Architecture` | L2 |
59
+ | `L3`, `Implementation`, `External` | L3 |
60
+ | (no subgraph) | L0 (default) |
61
+
62
+ ```
63
+ subgraph L0[Domain]
64
+ TERM[Term]
65
+ CDM[Conceptual Data Model]
66
+ end
67
+
68
+ subgraph L1[Requirements]
69
+ SR[System Requirement]
70
+ FR[Functional Requirement]
71
+ NFR[Non-Functional Requirement]
72
+ UC[Use Case]
73
+ end
74
+
75
+ subgraph L2[Design]
76
+ LDM[Logical Data Model]
77
+ AT[Acceptance Test]
78
+ end
79
+ ```
80
+
81
+ Nested subgraphs are supported; the innermost subgraph determines the level.
82
+
83
+ ---
84
+
85
+ ## 4. Class Assignments
86
+
87
+ ### 4.1 speckeeper-Managed Nodes
88
+
89
+ scaffold generates model files only for nodes explicitly declared as **speckeeper-managed** via `classDef` + `class`.
90
+
91
+ ```
92
+ classDef speckeeper fill:#2563EB,stroke:#1D4ED8,color:#fff,stroke-width:2px
93
+ class TERM,SR,FR,NFR,CDM,UC,LDM,AT speckeeper
94
+ ```
95
+
96
+ | Line | Required | Description |
97
+ |------|----------|-------------|
98
+ | `classDef speckeeper ...` | Required | CSS style definition. Style values are arbitrary |
99
+ | `class ID1,ID2,... speckeeper` | Required | Comma-separated list of speckeeper-managed node IDs |
100
+
101
+ - The class name must be `speckeeper`. scaffold filters by this class name.
102
+ - Nodes not listed in the `class` line are treated as "external nodes" and no model files are generated for them.
103
+
104
+ ### 4.2 Artifact Class Assignment
105
+
106
+ In addition to the `speckeeper` class, nodes can be assigned an **artifact class** that determines how they are grouped into model files.
107
+
108
+ ```
109
+ class FR,NFR requirement
110
+ class TERM term
111
+ class CDM,LDM entity
112
+ class SR systemRequirement
113
+ class UC useCase
114
+ class AT acceptanceTest
115
+ ```
116
+
117
+ The artifact class controls three things:
118
+
119
+ 1. **Model name**: PascalCase of the class name (e.g., `requirement` → `Requirement`)
120
+ 2. **File name**: kebab-case of the class name (e.g., `acceptanceTest` → `acceptance-test.ts`)
121
+ 3. **Node grouping**: Multiple nodes assigned the same class are consolidated into a single model file
122
+
123
+ Any class name is valid — there is no fixed registry. All artifact classes use the same base template (schema, lint rule stubs, exporter stubs).
124
+
125
+ If a speckeeper-managed node has no artifact class assigned, scaffold derives a default class from the node ID (lowercased).
126
+
127
+ ### 4.3 External Node Classes
128
+
129
+ Classes assigned to external (non-speckeeper) nodes determine the checker factory used when `implements` or `verifiedBy` edges point to them.
130
+
131
+ | External Class | Checker Factory |
132
+ |----------------|-----------------|
133
+ | `openapi` | `externalOpenAPIChecker` |
134
+ | `sqlschema` | `externalSqlSchemaChecker` |
135
+ | `test` | `testChecker` |
136
+ | (no class) | Generic checker stub |
137
+
138
+ ```
139
+ class API openapi
140
+ class DDL sqlschema
141
+ class UT,IT,E2ET test
142
+ ```
143
+
144
+ ---
145
+
146
+ ## 5. Edge Definitions
147
+
148
+ ### 5.1 Syntax
149
+
150
+ ```
151
+ SourceID -->|Label| TargetID[Label]
152
+ SourceID <-->|Label| TargetID[Label]
153
+ ```
154
+
155
+ | Arrow | Name | Direction |
156
+ |-------|------|-----------|
157
+ | `-->` | Unidirectional | forward |
158
+ | `<-->` | Bidirectional | bidirectional |
159
+ | `--->`, `---->` | Unidirectional (long) | forward |
160
+ | `<--->`, `<---->` | Bidirectional (long) | bidirectional |
161
+ | `-.->` | Dotted unidirectional | forward |
162
+ | `==>` | Thick unidirectional | forward |
163
+
164
+ Labels (`|...|`) are optional, but since scaffold determines the type of generated code based on labels, **labeling is strongly recommended**. Edges without labels are excluded from scaffold generation.
165
+
166
+ ---
167
+
168
+ ## 6. Edge Label Specification
169
+
170
+ ### 6.1 Basic Rules
171
+
172
+ Labels on edges involving speckeeper-managed nodes (where at least one of source or target is speckeeper-managed) must be **strings matching speckeeper's `RELATION_TYPES`**.
173
+
174
+ Edges **between non-managed nodes only** may use any free-form label text.
175
+
176
+ ### 6.2 Available Labels (= speckeeper RELATION_TYPES)
177
+
178
+ **Category A: Lint (speckeeper ↔ speckeeper reference integrity)**
179
+
180
+ | Label | Arrow | Description |
181
+ |-------|-------|-------------|
182
+ | `refines` | `-->` | Refines higher-level into lower-level. Lint checks reference existence + level constraint (source.level > target.level) |
183
+ | `relatedTo` | `<-->` | Bidirectional association. Lint checks bidirectional reference existence |
184
+ | `uses` | `-->` | Reference / dependency. Lint checks target existence |
185
+ | `dependsOn` | `-->` | Dependency. Lint checks target existence |
186
+ | `satisfies` | `-->` | Satisfies a requirement. Lint checks target existence |
187
+ | `includes` | `-->` | Parent contains child. Lint checks target existence |
188
+ | `traces` | `-->` | Derives target from source. Lint checks target existence |
189
+
190
+ **Category B: Check (speckeeper → external)**
191
+
192
+ | Label | Arrow | Description |
193
+ |-------|-------|-------------|
194
+ | `implements` | `-->` | Spec implemented as external artifact. Checker factory selected by the target node's class |
195
+ | `verifiedBy` | `-->` | Spec verified by external test code. Checker factory selected by the target node's class |
196
+
197
+ **Category C: External (no checker generated)**
198
+
199
+ | Label | Arrow | Description |
200
+ |-------|-------|-------------|
201
+ | `verifies` | `-->` | Test verifies implementation. Used between external nodes (external→external). No checker is generated |
202
+
203
+ ### 6.3 Labels Between Non-Managed Nodes (Free Text)
204
+
205
+ Edges between non-managed nodes may use any labels. scaffold does not validate these edges.
206
+
207
+ Commonly used external labels:
208
+
209
+ | Label | Example Usage |
210
+ |-------|---------------|
211
+ | `generate` | Auto-generation by external tools |
212
+ | `apply` | Application to external systems |
213
+ | `deploy` | Deployment |
214
+
215
+ ### 6.4 Label Normalization
216
+
217
+ For edges involving speckeeper-managed nodes, labels with modifiers are normalized using the following logic:
218
+
219
+ 1. **Exact match**: Label matches a RelationType exactly (case-insensitive)
220
+ 2. **Suffix match**: Label ends with a RelationType (longest match wins)
221
+ 3. **Substring match**: Label contains a RelationType (longest match wins)
222
+ 4. **Fallback**: If none of the above match, a warning is emitted and reference integrity lint is still applied
223
+
224
+ ---
225
+
226
+ ## 7. Checker Binding
227
+
228
+ When scaffold detects `implements` or `verifiedBy` edges from speckeeper-managed nodes to external nodes, it emits **checker binding guidance as comments** in the generated model file. No separate `_checkers/` directory is generated.
229
+
230
+ The checker factory is selected based on the external node's class (see Section 4.3):
231
+
232
+ | Edge | Target Class | Checker Factory | Validation Levels |
233
+ |------|--------------|-----------------|-------------------|
234
+ | `implements` | `openapi` | `externalOpenAPIChecker` | Existence (operationId, path, schema, x-spec-id), Structural (HTTP method), Type (parameter/response property types) |
235
+ | `implements` | `sqlschema` | `externalSqlSchemaChecker` | Existence (table name), Structural (column names), Type (column type containment) |
236
+ | `verifiedBy` | `test` | `testChecker` | Existence (test file + spec ID reference in describe/it/test blocks) |
237
+ | `implements` / `verifiedBy` | (unknown) | Generic checker stub | N/A |
238
+
239
+ Users activate the binding by importing the factory from `speckeeper/dsl` and assigning it to the model's `externalChecker` property.
240
+
241
+ ---
242
+
243
+ ## 8. scaffold Validation
244
+
245
+ At execution time, scaffold validates the mermaid diagram's consistency and emits diagnostic messages (warning/error).
246
+
247
+ | Rule | Severity | Condition |
248
+ |------|----------|-----------|
249
+ | Invalid label | warning | Edge label involving a speckeeper-managed node cannot be normalized to a RelationType |
250
+ | Arrow direction mismatch | warning | `relatedTo` written with `-->`, or `refines` etc. written with `<-->` |
251
+ | `implements` between speckeeper nodes | warning | `implements` used between speckeeper → speckeeper (recommend `refines` etc.) |
252
+ | `verifiedBy` between speckeeper nodes | warning | `verifiedBy` used between speckeeper → speckeeper (should target external test nodes) |
253
+ | No speckeeper-managed node declaration | error | No `class ... speckeeper` line exists |
254
+
255
+ Edges between non-managed nodes are not validated.
256
+
257
+ ---
258
+
259
+ ## 9. Generated Outputs
260
+
261
+ Files generated by scaffold:
262
+
263
+ | Path | Generation Condition | Content |
264
+ |------|---------------------|---------|
265
+ | `_models/<class>.ts` | Per artifact class (deduplicated) | Base model: schema, lint rule stubs (`requireField`), exporter stubs. Checker binding comments for `implements`/`verifiedBy` edges |
266
+ | `_models/index.ts` | Always | Re-exports all models + `allModels` array |
267
+ | `<class>.ts` | Per artifact class | Spec data file with `defineSpecs()` |
268
+ | `index.ts` | Always | Entry point with `mergeSpecs()` |
269
+
270
+ ---
271
+
272
+ ## 10. Complete Example
273
+
274
+ ```mermaid
275
+ flowchart TB
276
+ subgraph L0[Domain]
277
+ TERM[Term]
278
+ CDM[Conceptual Data Model]
279
+ end
280
+
281
+ subgraph L1[Requirements]
282
+ SR[System Requirement]
283
+ FR[Functional Requirement]
284
+ NFR[Non-Functional Requirement]
285
+ UC[Use Case]
286
+ end
287
+
288
+ subgraph L2[Design]
289
+ LDM[Logical Data Model]
290
+ AT[Acceptance Test]
291
+ end
292
+
293
+ TERM <-->|relatedTo| SR
294
+ TERM <-->|relatedTo| CDM
295
+ SR -->|refines| FR
296
+ SR -->|refines| NFR
297
+ FR -->|refines| UC
298
+ FR <-->|relatedTo| CDM
299
+ UC -->|uses| CDM
300
+
301
+ CDM -->|refines| LDM
302
+ FR -->|includes| AT
303
+ UC -->|includes| AT
304
+ NFR -->|includes| AT
305
+
306
+ UC -->|implements| API[API Spec]
307
+ LDM -->|implements| DDL[DDL]
308
+ FR -->|verifiedBy| UT[Unit Test]
309
+ AT -->|verifiedBy| E2ET[E2E Test]
310
+
311
+ DDL -->|generate| DBS[schema.sql]
312
+ UT -->|verifies| API
313
+
314
+ classDef speckeeper fill:#2563EB,stroke:#1D4ED8,color:#fff,stroke-width:2px
315
+ class TERM,SR,FR,NFR,CDM,UC,LDM,AT speckeeper
316
+
317
+ class TERM term
318
+ class CDM,LDM entity
319
+ class SR systemRequirement
320
+ class FR,NFR requirement
321
+ class UC useCase
322
+ class AT acceptanceTest
323
+
324
+ class API openapi
325
+ class DDL sqlschema
326
+ class UT,E2ET test
327
+ ```
328
+
329
+ From this diagram, scaffold generates the following:
330
+
331
+ **_models/**
332
+ - `term.ts` — TERM (level: L0)
333
+ - `entity.ts` — CDM, LDM (levels: L0, L2)
334
+ - `system-requirement.ts` — SR (level: L1)
335
+ - `requirement.ts` — FR, NFR (level: L1). Contains checker binding comments for `implements → openapi` (via UC) and `verifiedBy → test` (UT)
336
+ - `use-case.ts` — UC (level: L1). Contains checker binding comments for `implements → openapi` (API)
337
+ - `acceptance-test.ts` — AT (level: L2). Contains checker binding comments for `verifiedBy → test` (E2ET)
338
+ - `index.ts`
339
+
340
+ **Spec data files:**
341
+ - `term.ts`, `entity.ts`, `system-requirement.ts`, `requirement.ts`, `use-case.ts`, `acceptance-test.ts` — each with `defineSpecs()` calls
342
+ - `index.ts` — entry point with `mergeSpecs()`
343
+
344
+ ---
345
+
346
+ ## 11. CLI Reference
347
+
348
+ ```
349
+ speckeeper scaffold --source <path> [--output <dir>] [--force] [--dry-run]
350
+ ```
351
+
352
+ | Option | Required | Default | Description |
353
+ |--------|----------|---------|-------------|
354
+ | `--source`, `-s` | Required | - | Path to the Markdown file containing a mermaid flowchart |
355
+ | `--output`, `-o` | Optional | `design/` | Output directory |
356
+ | `--force`, `-f` | Optional | false | Overwrite existing files |
357
+ | `--dry-run` | Optional | false | Print generated content to stdout without writing files |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "speckeeper",
3
- "version": "0.9.2",
3
+ "version": "0.9.3",
4
4
  "description": "TypeScript-first specification validation framework with external SSOT integration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -24,7 +24,9 @@
24
24
  },
25
25
  "files": [
26
26
  "dist",
27
- "bin"
27
+ "bin",
28
+ "docs",
29
+ "cli-contract.yaml"
28
30
  ],
29
31
  "scripts": {
30
32
  "build": "tsup",
@@ -38,6 +40,8 @@
38
40
  "prepublishOnly": "npm run build",
39
41
  "docs": "embedoc build",
40
42
  "docs:watch": "embedoc watch",
43
+ "contract:validate": "npx cli-contracts validate",
44
+ "contract:generate": "npx cli-contracts generate",
41
45
  "ci": "npm run ci:validate && npm run ci:generate && npm run ci:verify",
42
46
  "ci:validate": "npm run typecheck && npm run lint && npm run lint:design && npm run build && npx speckeeper lint && npm run test:run",
43
47
  "ci:generate": "embedoc build",
@@ -73,6 +77,7 @@
73
77
  "@typescript-eslint/eslint-plugin": "^8.54.0",
74
78
  "@typescript-eslint/parser": "^8.54.0",
75
79
  "@vitest/coverage-v8": "^1.6.1",
80
+ "cli-contracts": "^0.2.0",
76
81
  "eslint": "^9.39.2",
77
82
  "tsup": "^8.0.1",
78
83
  "typescript": "^5.3.3",