htmlspec-kit 0.1.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/README.md +78 -0
- package/bin/htmlspec.ts +9 -0
- package/package.json +33 -0
- package/skills/htmlspec-kit/SKILL.md +584 -0
- package/skills/htmlspec-kit/agents/openai.yaml +4 -0
- package/skills/htmlspec-kit/assets/change-template.html +692 -0
- package/skills/htmlspec-kit/assets/spec.schema.json +155 -0
- package/src/cli.ts +422 -0
- package/src/html-document.ts +56 -0
- package/src/json-patch.ts +177 -0
- package/src/paths.ts +76 -0
- package/src/spec-data.ts +265 -0
- package/src/types.ts +106 -0
|
@@ -0,0 +1,584 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: htmlspec-kit
|
|
3
|
+
description: HTMLSpec is a spec-driven workflow that stores each change as a single browser-rendered .html dossier whose JSON payload lives in `script#SPEC`. Use when the user wants to plan, draft, validate, implement, or archive HTMLSpec changes - especially proposals, requirement specs, design notes, tasks, JSON Patch updates, or htmlspec-kit/htmlspec CLI commands such as `htmlspec task done`, `task in-progress`, `spec update`, `design update`, or `patch`.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# HTMLSpec Kit
|
|
7
|
+
|
|
8
|
+
HTMLSpec is the HTML-backed spec driven development. The visible page is template chrome; the editable source of truth is the JSON inside `script#SPEC`. The default project folder is `spec/`. Run the CLI with `npx htmlspec-kit` (or `bunx htmlspec-kit`); either is fine, pick whichever the project already uses.
|
|
9
|
+
|
|
10
|
+
## TL;DR Quick Checklist
|
|
11
|
+
|
|
12
|
+
- Search existing work: `npx htmlspec-kit list`, then `npx htmlspec-kit show <change-id> --json` for any candidate. Use `rg` only for full-text searches across `spec/`.
|
|
13
|
+
- Decide scope: new capability vs modify existing capability.
|
|
14
|
+
- Pick a unique `change-id`: kebab-case, verb-led (`add-`, `update-`, `remove-`, `refactor-`).
|
|
15
|
+
- Scaffold: one `spec/changes/<change-id>.html` containing `proposal`, `spec` deltas, `design` (only if needed), and `tasks`.
|
|
16
|
+
- Write deltas: in `spec.operations[]` use `ADDED | MODIFIED | REMOVED | RENAMED`; every requirement MUST have at least one scenario with `when` and `then`.
|
|
17
|
+
- Validate: `npx htmlspec-kit validate <change-id>` and fix issues.
|
|
18
|
+
- Request approval: do not start implementation until the proposal is approved.
|
|
19
|
+
|
|
20
|
+
## Three-Stage Workflow
|
|
21
|
+
|
|
22
|
+
### Stage 1: Creating Changes
|
|
23
|
+
|
|
24
|
+
Create a change when you need to:
|
|
25
|
+
|
|
26
|
+
- Add features or functionality
|
|
27
|
+
- Make breaking changes (API, schema)
|
|
28
|
+
- Change architecture or patterns
|
|
29
|
+
- Optimize performance (changes behavior)
|
|
30
|
+
- Update security patterns
|
|
31
|
+
|
|
32
|
+
Triggers (examples):
|
|
33
|
+
|
|
34
|
+
- "Help me create a change proposal"
|
|
35
|
+
- "Help me plan a change"
|
|
36
|
+
- "Help me create a proposal"
|
|
37
|
+
- "I want to create a spec proposal"
|
|
38
|
+
- "I want to create a spec"
|
|
39
|
+
|
|
40
|
+
Loose matching guidance:
|
|
41
|
+
|
|
42
|
+
- Contains one of: `proposal`, `change`, `spec`, `htmlspec`
|
|
43
|
+
- With one of: `create`, `plan`, `make`, `start`, `help`
|
|
44
|
+
|
|
45
|
+
Skip a change for:
|
|
46
|
+
|
|
47
|
+
- Bug fixes that restore intended behavior
|
|
48
|
+
- Typos, formatting, comments
|
|
49
|
+
- Dependency updates (non-breaking)
|
|
50
|
+
- Configuration changes
|
|
51
|
+
- Tests for existing behavior
|
|
52
|
+
|
|
53
|
+
**Workflow**
|
|
54
|
+
|
|
55
|
+
1. Review `spec/specs/`, `npx htmlspec-kit list`, and any project conventions to understand current context.
|
|
56
|
+
2. Choose a unique verb-led `change-id` and scaffold one `spec/changes/<change-id>.html` containing the four sections (`proposal`, `spec`, `design`, `tasks`).
|
|
57
|
+
3. Draft `spec.operations` using `ADDED | MODIFIED | REMOVED | RENAMED` with at least one scenario per requirement.
|
|
58
|
+
4. Run `npx htmlspec-kit validate <change-id>` and resolve any issues before sharing the change.
|
|
59
|
+
|
|
60
|
+
### Stage 2: Implementing Changes
|
|
61
|
+
|
|
62
|
+
Track these as TODOs and complete them one by one.
|
|
63
|
+
|
|
64
|
+
1. **Read the SPEC JSON** with `npx htmlspec-kit show <change-id> --json`. Do not load the whole HTML file for routine work.
|
|
65
|
+
2. **Read `proposal`** to understand what is being built.
|
|
66
|
+
3. **Read `design`** when it exists to understand the technical decisions.
|
|
67
|
+
4. **Read `tasks`** to get the implementation checklist.
|
|
68
|
+
5. **Implement tasks sequentially**: mark each one in progress, edit code, then mark it done.
|
|
69
|
+
6. **Confirm completion**: ensure every task in `tasks[].items[]` is `done` before changing the change status.
|
|
70
|
+
7. **Approval gate**: do not start implementation until the change is reviewed and approved.
|
|
71
|
+
|
|
72
|
+
Apply through CLI commands so the parser only rewrites the JSON payload:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
npx htmlspec-kit task in-progress <change-id> 2.1
|
|
76
|
+
npx htmlspec-kit task done <change-id> 2.1
|
|
77
|
+
npx htmlspec-kit state <change-id> in-progress
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Stage 3: Archiving Changes
|
|
81
|
+
|
|
82
|
+
After deployment, in a separate PR:
|
|
83
|
+
|
|
84
|
+
- Move `spec/changes/<change-id>.html` to `spec/archive/YYYY-MM-DD-<change-id>.html`.
|
|
85
|
+
- Update `spec/specs/` if capabilities changed.
|
|
86
|
+
- Use `npx htmlspec-kit state <change-id> archived` to record the transition.
|
|
87
|
+
- Run `npx htmlspec-kit validate <change-id>` to confirm the archived change still passes.
|
|
88
|
+
|
|
89
|
+
## Before Any Task
|
|
90
|
+
|
|
91
|
+
**Context Checklist**
|
|
92
|
+
|
|
93
|
+
- [ ] Read relevant specs in `spec/specs/<capability>/spec.html`
|
|
94
|
+
- [ ] Check pending changes in `spec/changes/` for conflicts
|
|
95
|
+
- [ ] Check project conventions if present (for example `AGENTS.md` or `README.md`)
|
|
96
|
+
- [ ] Run `npx htmlspec-kit list` to see active changes
|
|
97
|
+
- [ ] Run `npx htmlspec-kit list --json` to see all dossiers with their status
|
|
98
|
+
|
|
99
|
+
**Before Creating Specs**
|
|
100
|
+
|
|
101
|
+
- Always check whether the capability already exists.
|
|
102
|
+
- Prefer modifying existing specs over duplicating.
|
|
103
|
+
- Use `npx htmlspec-kit show <change-or-spec> --json` to review current state.
|
|
104
|
+
- If the request is ambiguous, ask one or two clarifying questions before scaffolding.
|
|
105
|
+
|
|
106
|
+
### Search Guidance
|
|
107
|
+
|
|
108
|
+
- Enumerate dossiers: `npx htmlspec-kit list` (or `--json` for scripts).
|
|
109
|
+
- Show details: `npx htmlspec-kit show <change-id> --json`.
|
|
110
|
+
- Full-text search: use ripgrep against the SPEC payloads.
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
rg -n '"id"|"title"|"status"' spec/changes
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Quick Start
|
|
117
|
+
|
|
118
|
+
### CLI Commands
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
# Essential commands
|
|
122
|
+
npx htmlspec-kit list # List active changes
|
|
123
|
+
npx htmlspec-kit list --json # Machine readable
|
|
124
|
+
npx htmlspec-kit show <change-id> --json # Show SPEC JSON
|
|
125
|
+
npx htmlspec-kit validate <change-id> # Validate one change
|
|
126
|
+
npx htmlspec-kit validate # Validate every dossier under spec/
|
|
127
|
+
npx htmlspec-kit state <change-id> archived # Mark archived after deploy
|
|
128
|
+
|
|
129
|
+
# Project management
|
|
130
|
+
npx htmlspec-kit init # Initialize spec/ folder
|
|
131
|
+
npx htmlspec-kit new <change-id> --title "<human title>" # Scaffold a change
|
|
132
|
+
|
|
133
|
+
# Mutations (parser-safe)
|
|
134
|
+
npx htmlspec-kit task add <change-id> "Title" --group "Implementation"
|
|
135
|
+
npx htmlspec-kit task in-progress <change-id> <task-id>
|
|
136
|
+
npx htmlspec-kit task done <change-id> <task-id>
|
|
137
|
+
npx htmlspec-kit spec update <change-id> --from /tmp/spec-fragment.html
|
|
138
|
+
npx htmlspec-kit design update <change-id> --from /tmp/design-fragment.html
|
|
139
|
+
npx htmlspec-kit patch <change-id> --patch '[{"op":"replace","path":"/status","value":"ready"}]'
|
|
140
|
+
npx htmlspec-kit patch <change-id> --replace /proposal/whyHtml --string-value '<p>Why now...</p>'
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
`bunx htmlspec-kit ...` works the same way. Either is fine.
|
|
144
|
+
|
|
145
|
+
### Command Flags
|
|
146
|
+
|
|
147
|
+
- `--json` - machine-readable output
|
|
148
|
+
- `--from <file>` - read HTML or JSON fragment from a file
|
|
149
|
+
- `--patch '<rfc6902>'` - inline JSON Patch array
|
|
150
|
+
- `--replace <pointer>` - shorthand for a single replace operation
|
|
151
|
+
- `--value <json>` / `--string-value <text>` - value for `--replace`
|
|
152
|
+
|
|
153
|
+
## Reading and Editing Rules
|
|
154
|
+
|
|
155
|
+
Most of the time, read and edit only the SPEC JSON. Direct HTML edits are allowed when adjusting visual chrome, Alpine rendering, CSS, metadata, or carefully scoped manual JSON edits. For ordinary proposal/spec/design/task changes, prefer the CLI so the parser rewrites only the JSON payload.
|
|
156
|
+
|
|
157
|
+
Use `npx htmlspec-kit patch` for targeted edits. It accepts RFC 6902 JSON Patch arrays (`add`, `replace`, `remove`, `move`, `copy`, `test`) and a convenience replace mode.
|
|
158
|
+
|
|
159
|
+
## Project Layout
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
spec/
|
|
163
|
+
├── specs/ # Current truth - capabilities that are built
|
|
164
|
+
│ └── <capability>/
|
|
165
|
+
│ └── spec.html # Requirements and scenarios for that capability
|
|
166
|
+
├── changes/ # Proposed - dossiers for changes in flight
|
|
167
|
+
│ └── <change-id>.html # Single dossier per change (proposal, spec, design, tasks)
|
|
168
|
+
├── archive/ # Completed changes
|
|
169
|
+
│ └── YYYY-MM-DD-<change-id>.html
|
|
170
|
+
└── templates/
|
|
171
|
+
└── change-template.html # Project-local copy of the bootstrap template
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Creating Changes
|
|
175
|
+
|
|
176
|
+
### Decision Tree
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
New request?
|
|
180
|
+
├─ Bug fix that restores spec behavior? → Fix directly
|
|
181
|
+
├─ Typo/format/comment? → Fix directly
|
|
182
|
+
├─ New feature/capability? → Create change
|
|
183
|
+
├─ Breaking change? → Create change
|
|
184
|
+
├─ Architecture change? → Create change
|
|
185
|
+
└─ Unclear? → Create change (safer)
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Scaffolding
|
|
189
|
+
|
|
190
|
+
1. **Create the dossier**:
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
npx htmlspec-kit new <change-id> --title "<human title>"
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
2. **Draft the `proposal` section** so the SPEC JSON looks like:
|
|
197
|
+
|
|
198
|
+
```json
|
|
199
|
+
{
|
|
200
|
+
"proposal": {
|
|
201
|
+
"whyHtml": "<p>1-2 sentences on the problem or opportunity.</p>",
|
|
202
|
+
"whatChanges": [
|
|
203
|
+
"Bullet list of changes. Mark breaking changes with BREAKING."
|
|
204
|
+
],
|
|
205
|
+
"capabilities": {
|
|
206
|
+
"new": [
|
|
207
|
+
{
|
|
208
|
+
"name": "user-auth",
|
|
209
|
+
"description": "Brief capability description."
|
|
210
|
+
}
|
|
211
|
+
],
|
|
212
|
+
"modified": []
|
|
213
|
+
},
|
|
214
|
+
"impact": ["Affected code, APIs, dependencies, or systems."]
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Apply with `npx htmlspec-kit patch <change-id>` or by editing the SPEC JSON directly.
|
|
220
|
+
|
|
221
|
+
3. **Draft `spec` deltas** for every capability listed in `proposal.capabilities`:
|
|
222
|
+
|
|
223
|
+
```json
|
|
224
|
+
{
|
|
225
|
+
"spec": {
|
|
226
|
+
"overviewHtml": "<p>Describe observable behavior.</p>",
|
|
227
|
+
"operations": [
|
|
228
|
+
{
|
|
229
|
+
"type": "ADDED",
|
|
230
|
+
"requirements": [
|
|
231
|
+
{
|
|
232
|
+
"id": "REQ-001",
|
|
233
|
+
"title": "Two-Factor Authentication",
|
|
234
|
+
"bodyHtml": "<p>Users MUST provide a second factor during login.</p>",
|
|
235
|
+
"scenarios": [
|
|
236
|
+
{
|
|
237
|
+
"id": "SCN-001",
|
|
238
|
+
"title": "OTP required",
|
|
239
|
+
"given": "valid credentials are provided",
|
|
240
|
+
"when": "the user submits the login form",
|
|
241
|
+
"then": "an OTP challenge is required"
|
|
242
|
+
}
|
|
243
|
+
]
|
|
244
|
+
}
|
|
245
|
+
]
|
|
246
|
+
}
|
|
247
|
+
]
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
4. **Draft `tasks`**:
|
|
253
|
+
|
|
254
|
+
```json
|
|
255
|
+
{
|
|
256
|
+
"tasks": [
|
|
257
|
+
{
|
|
258
|
+
"id": "1",
|
|
259
|
+
"title": "Implementation",
|
|
260
|
+
"items": [
|
|
261
|
+
{ "id": "1.1", "title": "Create database schema", "status": "todo" },
|
|
262
|
+
{ "id": "1.2", "title": "Implement API endpoint", "status": "todo" },
|
|
263
|
+
{ "id": "1.3", "title": "Add frontend component", "status": "todo" },
|
|
264
|
+
{ "id": "1.4", "title": "Write tests", "status": "todo" }
|
|
265
|
+
]
|
|
266
|
+
}
|
|
267
|
+
]
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
5. **Draft `design` only when needed**. Create the `design` section if any of the following apply, otherwise leave it as the placeholder:
|
|
272
|
+
- Cross-cutting change (multiple services/modules) or a new architectural pattern
|
|
273
|
+
- New external dependency or significant data model changes
|
|
274
|
+
- Security, performance, or migration complexity
|
|
275
|
+
- Ambiguity that benefits from technical decisions before coding
|
|
276
|
+
|
|
277
|
+
Minimal `design` shape:
|
|
278
|
+
|
|
279
|
+
```json
|
|
280
|
+
{
|
|
281
|
+
"design": {
|
|
282
|
+
"contextHtml": "<p>Background, constraints, stakeholders.</p>",
|
|
283
|
+
"goals": ["What this design achieves."],
|
|
284
|
+
"nonGoals": ["What is explicitly out of scope."],
|
|
285
|
+
"decisions": [
|
|
286
|
+
{
|
|
287
|
+
"id": "architecture",
|
|
288
|
+
"title": "Architecture",
|
|
289
|
+
"decisionHtml": "<p>What and why.</p>",
|
|
290
|
+
"rationaleHtml": "<p>Why this approach over alternatives.</p>",
|
|
291
|
+
"alternatives": ["Alternative considered + rationale."]
|
|
292
|
+
}
|
|
293
|
+
],
|
|
294
|
+
"risksTradeoffs": ["Risk -> mitigation."],
|
|
295
|
+
"migrationPlan": ["Steps to deploy, rollback strategy."],
|
|
296
|
+
"openQuestions": ["Outstanding decisions or unknowns."]
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## Spec Authoring Format
|
|
302
|
+
|
|
303
|
+
### Critical: Scenario Shape
|
|
304
|
+
|
|
305
|
+
Every requirement MUST have at least one scenario with `when` and `then`. `given` is optional.
|
|
306
|
+
|
|
307
|
+
CORRECT:
|
|
308
|
+
|
|
309
|
+
```json
|
|
310
|
+
{
|
|
311
|
+
"id": "SCN-101",
|
|
312
|
+
"title": "User login success",
|
|
313
|
+
"when": "valid credentials are provided",
|
|
314
|
+
"then": "the system returns a JWT token"
|
|
315
|
+
}
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
WRONG:
|
|
319
|
+
|
|
320
|
+
- Free-form prose mixed into `bodyHtml` instead of a real scenario record.
|
|
321
|
+
- Empty `scenarios` arrays.
|
|
322
|
+
- Missing `when` or `then`.
|
|
323
|
+
|
|
324
|
+
### Requirement Wording
|
|
325
|
+
|
|
326
|
+
Use SHALL / MUST for normative requirements; avoid `should`/`may` unless intentionally non-normative.
|
|
327
|
+
|
|
328
|
+
### Delta Operations
|
|
329
|
+
|
|
330
|
+
`spec.operations[].type` must be one of:
|
|
331
|
+
|
|
332
|
+
- `ADDED` - new capabilities
|
|
333
|
+
- `MODIFIED` - changed behavior (carry over the full requirement before editing)
|
|
334
|
+
- `REMOVED` - deprecated features (include `reasonHtml` and `migrationHtml`)
|
|
335
|
+
- `RENAMED` - name changes (use `from` and `to` strings on the requirement)
|
|
336
|
+
|
|
337
|
+
Headers and ids are matched after trimming whitespace.
|
|
338
|
+
|
|
339
|
+
#### When to use ADDED vs MODIFIED
|
|
340
|
+
|
|
341
|
+
- `ADDED` when the change is orthogonal to existing requirements.
|
|
342
|
+
- `MODIFIED` when you change behavior, scope, or acceptance criteria of an existing requirement. Always paste the full updated requirement (including all scenarios) - the archiver replaces the entire requirement with what you provide.
|
|
343
|
+
- `RENAMED` when only the name changes; combine with `MODIFIED` if behavior also changes.
|
|
344
|
+
|
|
345
|
+
Common pitfall: using `MODIFIED` with partial content. That loses detail at archive time. If you are not actually changing the existing requirement, add a new one under `ADDED`.
|
|
346
|
+
|
|
347
|
+
Authoring a `MODIFIED` requirement correctly:
|
|
348
|
+
|
|
349
|
+
1. Locate the existing requirement in `spec/specs/<capability>/spec.html` (read the SPEC JSON, not the whole HTML file).
|
|
350
|
+
2. Copy the entire requirement object (including every scenario).
|
|
351
|
+
3. Place it under a `{ "type": "MODIFIED", "requirements": [ ... ] }` operation in the change dossier.
|
|
352
|
+
4. Edit to reflect the new behavior. Keep at least one scenario with `when` and `then`.
|
|
353
|
+
|
|
354
|
+
`RENAMED` example:
|
|
355
|
+
|
|
356
|
+
```json
|
|
357
|
+
{
|
|
358
|
+
"type": "RENAMED",
|
|
359
|
+
"requirements": [
|
|
360
|
+
{
|
|
361
|
+
"id": "REQ-203",
|
|
362
|
+
"title": "User Authentication",
|
|
363
|
+
"from": "Login",
|
|
364
|
+
"to": "User Authentication"
|
|
365
|
+
}
|
|
366
|
+
]
|
|
367
|
+
}
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
## JSON Schema
|
|
371
|
+
|
|
372
|
+
The full JSON Schema for the `script#SPEC` payload is bundled at `assets/spec.schema.json`. Use it when creating or patching dossiers. Required top-level fields: `format`, `version`, `id`, `title`, `status`, `owner`, `createdAt`, `updatedAt`, `summaryHtml`, `proposal`, `spec`, `design`, `tasks`, `history`.
|
|
373
|
+
|
|
374
|
+
```json
|
|
375
|
+
{
|
|
376
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
377
|
+
"$id": "https://htmlspec.dev/schemas/spec.schema.json",
|
|
378
|
+
"title": "HTMLSpec SPEC payload",
|
|
379
|
+
"type": "object",
|
|
380
|
+
"additionalProperties": false,
|
|
381
|
+
"required": [
|
|
382
|
+
"format",
|
|
383
|
+
"version",
|
|
384
|
+
"id",
|
|
385
|
+
"title",
|
|
386
|
+
"status",
|
|
387
|
+
"owner",
|
|
388
|
+
"createdAt",
|
|
389
|
+
"updatedAt",
|
|
390
|
+
"summaryHtml",
|
|
391
|
+
"proposal",
|
|
392
|
+
"spec",
|
|
393
|
+
"design",
|
|
394
|
+
"tasks",
|
|
395
|
+
"history"
|
|
396
|
+
],
|
|
397
|
+
"properties": {
|
|
398
|
+
"format": { "const": "htmlspec" },
|
|
399
|
+
"version": { "type": "string" },
|
|
400
|
+
"id": { "type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$" },
|
|
401
|
+
"title": { "type": "string", "minLength": 1 },
|
|
402
|
+
"status": { "enum": ["draft", "ready", "in-progress", "done", "archived"] },
|
|
403
|
+
"owner": { "type": "string" },
|
|
404
|
+
"createdAt": { "type": "string", "format": "date-time" },
|
|
405
|
+
"updatedAt": { "type": "string", "format": "date-time" },
|
|
406
|
+
"summaryHtml": { "type": "string" },
|
|
407
|
+
"proposal": { "$ref": "#/$defs/proposal" },
|
|
408
|
+
"spec": { "$ref": "#/$defs/spec" },
|
|
409
|
+
"design": { "$ref": "#/$defs/design" },
|
|
410
|
+
"tasks": { "type": "array", "items": { "$ref": "#/$defs/taskGroup" } },
|
|
411
|
+
"history": { "type": "array", "items": { "$ref": "#/$defs/historyEntry" } }
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
The `$defs` for `proposal`, `capability`, `spec`, `requirementDelta`, `requirement`, `scenario`, `design`, `designDecision`, `taskGroup`, `task`, and `historyEntry` are in `assets/spec.schema.json`. Read the bundled file when you need the full constraints.
|
|
417
|
+
|
|
418
|
+
## Troubleshooting
|
|
419
|
+
|
|
420
|
+
### Common Errors
|
|
421
|
+
|
|
422
|
+
**Change must have at least one delta**
|
|
423
|
+
|
|
424
|
+
- Check that `spec.operations` has at least one entry under `spec/changes/<change-id>.html`.
|
|
425
|
+
- Each operation must declare `type` (`ADDED`/`MODIFIED`/`REMOVED`/`RENAMED`).
|
|
426
|
+
|
|
427
|
+
**Requirement must have at least one scenario**
|
|
428
|
+
|
|
429
|
+
- Make sure each requirement object has a non-empty `scenarios` array.
|
|
430
|
+
- Each scenario needs `id`, `title`, `when`, and `then`.
|
|
431
|
+
|
|
432
|
+
**Silent scenario parsing failures**
|
|
433
|
+
|
|
434
|
+
- The schema requires the exact shape above. Strings such as `WHEN ...` inside `bodyHtml` are not parsed as scenarios.
|
|
435
|
+
- Debug with: `npx htmlspec-kit show <change-id> --json | jq '.spec.operations'`.
|
|
436
|
+
|
|
437
|
+
### Validation Tips
|
|
438
|
+
|
|
439
|
+
```bash
|
|
440
|
+
npx htmlspec-kit validate <change-id>
|
|
441
|
+
npx htmlspec-kit show <change-id> --json | jq '.tasks[] | .items[]'
|
|
442
|
+
npx htmlspec-kit show <change-id> --json | jq '.spec.operations[].requirements[].scenarios'
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
## Happy Path Script
|
|
446
|
+
|
|
447
|
+
```bash
|
|
448
|
+
# 1) Explore current state
|
|
449
|
+
npx htmlspec-kit list
|
|
450
|
+
# Optional full-text search:
|
|
451
|
+
# rg -n '"Requirement"|"Scenario"' spec/changes spec/specs
|
|
452
|
+
|
|
453
|
+
# 2) Choose change id and scaffold
|
|
454
|
+
CHANGE=add-two-factor-auth
|
|
455
|
+
npx htmlspec-kit new "$CHANGE" --title "Add two-factor authentication"
|
|
456
|
+
|
|
457
|
+
# 3) Add a requirement and a task
|
|
458
|
+
npx htmlspec-kit patch "$CHANGE" --patch '[
|
|
459
|
+
{ "op": "add", "path": "/spec/operations/0/requirements/-", "value": {
|
|
460
|
+
"id": "REQ-201",
|
|
461
|
+
"title": "Two-Factor Authentication",
|
|
462
|
+
"bodyHtml": "<p>Users MUST provide a second factor during login.</p>",
|
|
463
|
+
"scenarios": [
|
|
464
|
+
{ "id": "SCN-201", "title": "OTP required",
|
|
465
|
+
"given": "valid credentials are provided",
|
|
466
|
+
"when": "the user submits the login form",
|
|
467
|
+
"then": "an OTP challenge is required" }
|
|
468
|
+
]
|
|
469
|
+
} }
|
|
470
|
+
]'
|
|
471
|
+
npx htmlspec-kit task add "$CHANGE" "Implement OTP challenge" --group "Implementation"
|
|
472
|
+
|
|
473
|
+
# 4) Validate
|
|
474
|
+
npx htmlspec-kit validate "$CHANGE"
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
## Multi-Capability Example
|
|
478
|
+
|
|
479
|
+
```
|
|
480
|
+
spec/changes/add-2fa-notify.html
|
|
481
|
+
└── (script#SPEC)
|
|
482
|
+
└── proposal.capabilities.new = [{ "name": "auth" }, { "name": "notifications" }]
|
|
483
|
+
└── spec.operations = [
|
|
484
|
+
{ "type": "ADDED", "requirements": [ /* auth: Two-Factor Authentication */ ] },
|
|
485
|
+
{ "type": "ADDED", "requirements": [ /* notifications: OTP Email */ ] }
|
|
486
|
+
]
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
Both capabilities live in the same dossier; their requirements are grouped by the `requirements[]` array inside each `ADDED` operation. Promote them into `spec/specs/<capability>/spec.html` when archiving.
|
|
490
|
+
|
|
491
|
+
## Best Practices
|
|
492
|
+
|
|
493
|
+
### Simplicity First
|
|
494
|
+
|
|
495
|
+
- Default to small dossiers. If a change needs many decisions, prefer splitting into multiple changes.
|
|
496
|
+
- Avoid frameworks without clear justification.
|
|
497
|
+
- Choose boring, proven patterns.
|
|
498
|
+
|
|
499
|
+
### Complexity Triggers
|
|
500
|
+
|
|
501
|
+
Only add complexity with:
|
|
502
|
+
|
|
503
|
+
- Performance data showing the current solution is too slow.
|
|
504
|
+
- Concrete scale requirements (>1000 users, >100 MB data).
|
|
505
|
+
- Multiple proven use cases requiring abstraction.
|
|
506
|
+
|
|
507
|
+
### Clear References
|
|
508
|
+
|
|
509
|
+
- Use `file.ts:42` format for code locations.
|
|
510
|
+
- Reference specs as `spec/specs/<capability>/spec.html`.
|
|
511
|
+
- Link related changes and PRs in `proposal.impact`.
|
|
512
|
+
|
|
513
|
+
### Capability Naming
|
|
514
|
+
|
|
515
|
+
- Use verb-noun: `user-auth`, `payment-capture`.
|
|
516
|
+
- Single purpose per capability.
|
|
517
|
+
- Ten-minute understandability rule.
|
|
518
|
+
- Split if the description needs "AND".
|
|
519
|
+
|
|
520
|
+
### Change ID Naming
|
|
521
|
+
|
|
522
|
+
- Use kebab-case, short and descriptive: `add-two-factor-auth`.
|
|
523
|
+
- Prefer verb-led prefixes: `add-`, `update-`, `remove-`, `refactor-`.
|
|
524
|
+
- Ensure uniqueness; if taken, append `-2`, `-3`, etc.
|
|
525
|
+
|
|
526
|
+
## Tool Selection Guide
|
|
527
|
+
|
|
528
|
+
| Task | Tool | Why |
|
|
529
|
+
| --------------------- | ---------- | ------------------------ |
|
|
530
|
+
| Find files by pattern | Glob | Fast pattern matching |
|
|
531
|
+
| Search code content | Grep / rg | Optimized regex search |
|
|
532
|
+
| Read specific files | Read | Direct file access |
|
|
533
|
+
| Inspect SPEC JSON | `npx htmlspec-kit` | Parser-safe and scoped |
|
|
534
|
+
| Explore unknown scope | Subagent | Multi-step investigation |
|
|
535
|
+
|
|
536
|
+
## Error Recovery
|
|
537
|
+
|
|
538
|
+
### Change Conflicts
|
|
539
|
+
|
|
540
|
+
1. Run `npx htmlspec-kit list` to see active changes.
|
|
541
|
+
2. Check for overlapping capability names in `proposal.capabilities`.
|
|
542
|
+
3. Coordinate with change owners.
|
|
543
|
+
4. Consider combining proposals into one dossier.
|
|
544
|
+
|
|
545
|
+
### Validation Failures
|
|
546
|
+
|
|
547
|
+
1. Run `npx htmlspec-kit validate <change-id>`.
|
|
548
|
+
2. Inspect with `--json` to localize the failure.
|
|
549
|
+
3. Verify each requirement has a non-empty `scenarios` array.
|
|
550
|
+
4. Verify task ids follow `X.Y`.
|
|
551
|
+
|
|
552
|
+
### Missing Context
|
|
553
|
+
|
|
554
|
+
1. Read project conventions (root `AGENTS.md`, `README.md`) first.
|
|
555
|
+
2. Read related capability dossiers in `spec/specs/`.
|
|
556
|
+
3. Review recent archives in `spec/archive/`.
|
|
557
|
+
4. Ask the user for clarification.
|
|
558
|
+
|
|
559
|
+
## Quick Reference
|
|
560
|
+
|
|
561
|
+
### Stage Indicators
|
|
562
|
+
|
|
563
|
+
- `spec/changes/` - proposed, not yet built.
|
|
564
|
+
- `spec/specs/` - built and deployed.
|
|
565
|
+
- `spec/archive/` - completed changes.
|
|
566
|
+
|
|
567
|
+
### Section Purposes
|
|
568
|
+
|
|
569
|
+
- `proposal` - why and what.
|
|
570
|
+
- `spec` - requirements and scenarios.
|
|
571
|
+
- `design` - technical decisions.
|
|
572
|
+
- `tasks` - implementation steps.
|
|
573
|
+
|
|
574
|
+
### CLI Essentials
|
|
575
|
+
|
|
576
|
+
```bash
|
|
577
|
+
npx htmlspec-kit list # What is in progress?
|
|
578
|
+
npx htmlspec-kit show <change-id> # View summary
|
|
579
|
+
npx htmlspec-kit show <change-id> --json
|
|
580
|
+
npx htmlspec-kit validate <change-id> # Is it correct?
|
|
581
|
+
npx htmlspec-kit state <change-id> archived
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
Remember: the JSON in `script#SPEC` is the truth. Changes are proposals. Keep them in sync.
|