@eddacraft/anvil-aps 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.
Files changed (121) hide show
  1. package/AGENTS.md +155 -0
  2. package/LICENSE +14 -0
  3. package/README.md +57 -0
  4. package/TODO.md +40 -0
  5. package/dist/filter/context-bundle.d.ts +81 -0
  6. package/dist/filter/context-bundle.d.ts.map +1 -0
  7. package/dist/filter/context-bundle.js +230 -0
  8. package/dist/filter/index.d.ts +85 -0
  9. package/dist/filter/index.d.ts.map +1 -0
  10. package/dist/filter/index.js +169 -0
  11. package/dist/index.d.ts +16 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +15 -0
  14. package/dist/loader/index.d.ts +80 -0
  15. package/dist/loader/index.d.ts.map +1 -0
  16. package/dist/loader/index.js +253 -0
  17. package/dist/parser/index.d.ts +24 -0
  18. package/dist/parser/index.d.ts.map +1 -0
  19. package/dist/parser/index.js +22 -0
  20. package/dist/parser/parse-document.d.ts +17 -0
  21. package/dist/parser/parse-document.d.ts.map +1 -0
  22. package/dist/parser/parse-document.js +219 -0
  23. package/dist/parser/parse-index.d.ts +31 -0
  24. package/dist/parser/parse-index.d.ts.map +1 -0
  25. package/dist/parser/parse-index.js +251 -0
  26. package/dist/parser/parse-task.d.ts +30 -0
  27. package/dist/parser/parse-task.d.ts.map +1 -0
  28. package/dist/parser/parse-task.js +261 -0
  29. package/dist/state/index.d.ts +307 -0
  30. package/dist/state/index.d.ts.map +1 -0
  31. package/dist/state/index.js +689 -0
  32. package/dist/templates/generator.d.ts +71 -0
  33. package/dist/templates/generator.d.ts.map +1 -0
  34. package/dist/templates/generator.js +723 -0
  35. package/dist/templates/index.d.ts +5 -0
  36. package/dist/templates/index.d.ts.map +1 -0
  37. package/dist/templates/index.js +4 -0
  38. package/dist/types/index.d.ts +131 -0
  39. package/dist/types/index.d.ts.map +1 -0
  40. package/dist/types/index.js +107 -0
  41. package/dist/validator/index.d.ts +83 -0
  42. package/dist/validator/index.d.ts.map +1 -0
  43. package/dist/validator/index.js +611 -0
  44. package/docs/APS-Anvil-Integration.md +750 -0
  45. package/docs/APS-Conventions.md +635 -0
  46. package/docs/APS-NonGoals.md +455 -0
  47. package/docs/APS-Planning-Spec-v0.1.md +362 -0
  48. package/examples/README.md +170 -0
  49. package/examples/feature-auth.aps.md +87 -0
  50. package/examples/refactor-error-handling.aps.md +119 -0
  51. package/examples/system-ecommerce/APS.md +57 -0
  52. package/examples/system-ecommerce/modules/auth.aps.md +38 -0
  53. package/examples/system-ecommerce/modules/cart.aps.md +53 -0
  54. package/examples/system-ecommerce/modules/payments.aps.md +68 -0
  55. package/examples/system-ecommerce/modules/products.aps.md +53 -0
  56. package/package.json +34 -0
  57. package/project.json +37 -0
  58. package/scripts/generate-templates.js +33 -0
  59. package/src/filter/context-bundle.ts +312 -0
  60. package/src/filter/filter.test.ts +317 -0
  61. package/src/filter/index.ts +249 -0
  62. package/src/index.ts +16 -0
  63. package/src/loader/index.ts +364 -0
  64. package/src/loader/loader.test.ts +224 -0
  65. package/src/parser/__fixtures__/invalid-task-id-not-padded.aps.md +7 -0
  66. package/src/parser/__fixtures__/invalid-task-id.aps.md +8 -0
  67. package/src/parser/__fixtures__/minimal-task.aps.md +7 -0
  68. package/src/parser/__fixtures__/non-scope-hyphenated.aps.md +10 -0
  69. package/src/parser/__fixtures__/simple-index.aps.md +35 -0
  70. package/src/parser/__fixtures__/simple-plan.aps.md +19 -0
  71. package/src/parser/index.ts +30 -0
  72. package/src/parser/parse-document.test.ts +603 -0
  73. package/src/parser/parse-document.ts +262 -0
  74. package/src/parser/parse-index.test.ts +316 -0
  75. package/src/parser/parse-index.ts +298 -0
  76. package/src/parser/parse-task.test.ts +476 -0
  77. package/src/parser/parse-task.ts +325 -0
  78. package/src/state/__fixtures__/invalid-plan.aps.md +9 -0
  79. package/src/state/__fixtures__/test-plan.aps.md +20 -0
  80. package/src/state/index.ts +879 -0
  81. package/src/state/state.test.ts +645 -0
  82. package/src/templates/generator.test.ts +378 -0
  83. package/src/templates/generator.ts +776 -0
  84. package/src/templates/index.ts +5 -0
  85. package/src/types/index.ts +168 -0
  86. package/src/validator/__fixtures__/broken-links.aps.md +10 -0
  87. package/src/validator/__fixtures__/circular-deps-index.aps.md +26 -0
  88. package/src/validator/__fixtures__/circular-modules/module-a.aps.md +9 -0
  89. package/src/validator/__fixtures__/circular-modules/module-b.aps.md +9 -0
  90. package/src/validator/__fixtures__/circular-modules/module-c.aps.md +9 -0
  91. package/src/validator/__fixtures__/dup-modules/module-a.aps.md +9 -0
  92. package/src/validator/__fixtures__/dup-modules/module-b.aps.md +9 -0
  93. package/src/validator/__fixtures__/duplicate-ids-index.aps.md +15 -0
  94. package/src/validator/__fixtures__/invalid-task-id.aps.md +17 -0
  95. package/src/validator/__fixtures__/missing-confidence.aps.md +9 -0
  96. package/src/validator/__fixtures__/missing-h1.aps.md +5 -0
  97. package/src/validator/__fixtures__/missing-intent.aps.md +9 -0
  98. package/src/validator/__fixtures__/missing-modules-section.aps.md +7 -0
  99. package/src/validator/__fixtures__/missing-tasks-section.aps.md +7 -0
  100. package/src/validator/__fixtures__/modules/auth.aps.md +17 -0
  101. package/src/validator/__fixtures__/modules/payments.aps.md +13 -0
  102. package/src/validator/__fixtures__/scope-mismatch.aps.md +14 -0
  103. package/src/validator/__fixtures__/valid-index.aps.md +24 -0
  104. package/src/validator/__fixtures__/valid-leaf.aps.md +22 -0
  105. package/src/validator/index.ts +776 -0
  106. package/src/validator/validator.test.ts +269 -0
  107. package/templates/index-full.md +94 -0
  108. package/templates/index-minimal.md +16 -0
  109. package/templates/index-template.md +63 -0
  110. package/templates/leaf-full.md +76 -0
  111. package/templates/leaf-minimal.md +14 -0
  112. package/templates/leaf-template.md +55 -0
  113. package/templates/simple-full.md +56 -0
  114. package/templates/simple-minimal.md +14 -0
  115. package/templates/simple-template.md +30 -0
  116. package/tsconfig.json +19 -0
  117. package/tsconfig.lib.json +14 -0
  118. package/tsconfig.lib.tsbuildinfo +1 -0
  119. package/tsconfig.spec.json +9 -0
  120. package/tsconfig.tsbuildinfo +1 -0
  121. package/vitest.config.ts +15 -0
@@ -0,0 +1,635 @@
1
+ # APS Conventions
2
+
3
+ > Detailed conventions for Anvil Planning Spec documents.
4
+
5
+ ## File Naming
6
+
7
+ ### Leaf Specs
8
+
9
+ Leaf specs must use the `.aps.md` extension:
10
+
11
+ **Valid:**
12
+
13
+ - `auth.aps.md`
14
+ - `feature-payments.aps.md`
15
+ - `refactor-api.aps.md`
16
+
17
+ **Invalid:**
18
+
19
+ - `auth.md` (missing `.aps` marker)
20
+ - `auth.aps.txt` (wrong file extension)
21
+
22
+ ### Index Files
23
+
24
+ Index files should use `APS.md` or `<name>.aps.md`:
25
+
26
+ **Recommended:**
27
+
28
+ - `APS.md` (standard index name)
29
+ - `system.aps.md` (named index)
30
+
31
+ **Also valid:**
32
+
33
+ - `plan.aps.md`
34
+ - `roadmap.aps.md`
35
+
36
+ ### Directory Structure
37
+
38
+ Recommended structure for multi-module plans:
39
+
40
+ ```
41
+ docs/planning/
42
+ APS.md # Index file (or system.aps.md)
43
+ modules/ # Leaf specs
44
+ auth.aps.md
45
+ payments.aps.md
46
+ admin.aps.md
47
+ ```
48
+
49
+ ---
50
+
51
+ ## Root File Discovery
52
+
53
+ The loader searches for index files in this order:
54
+
55
+ 1. Explicit path provided to CLI (`anvil plan validate ./docs/planning/APS.md`)
56
+ 2. `docs/planning/APS.md` (conventional location)
57
+ 3. `APS.md` in repository root
58
+ 4. Any `*.aps.md` file if only one exists
59
+
60
+ **Best practice:** Use `docs/planning/APS.md` as your index file.
61
+
62
+ ---
63
+
64
+ ## Heading Hierarchy
65
+
66
+ ### Index Files
67
+
68
+ ```markdown
69
+ # Plan Title (H1 - exactly one)
70
+
71
+ ## Overview (H2 - optional)
72
+
73
+ ## Modules (H2 - required)
74
+
75
+ ### auth (H3 - module id)
76
+
77
+ ### payments (H3 - module id)
78
+
79
+ ## Open Questions (H2 - optional)
80
+
81
+ ## Decisions (H2 - optional)
82
+ ```
83
+
84
+ ### Leaf Specs
85
+
86
+ ```markdown
87
+ # Module Title (H1 - exactly one)
88
+
89
+ ## Tasks (H2 - required)
90
+
91
+ ### AUTH-001: Task title (H3 - task definition)
92
+
93
+ ### AUTH-002: Another task (H3 - task definition)
94
+
95
+ ## Dependencies (H2 - optional)
96
+
97
+ ## Notes (H2 - optional)
98
+ ```
99
+
100
+ **Rules:**
101
+
102
+ - Exactly one H1 per file
103
+ - Required sections must be H2
104
+ - Module IDs and tasks must be H3
105
+ - No heading levels beyond H3 in structured sections
106
+
107
+ ---
108
+
109
+ ## Link Rules
110
+
111
+ ### Format
112
+
113
+ All links must use Markdown link syntax:
114
+
115
+ ```markdown
116
+ [Link text](./path/to/file.md)
117
+ ```
118
+
119
+ ### Paths
120
+
121
+ - Must be **relative** to the current file
122
+ - Must point to files **within the repository**
123
+ - No absolute paths (`/home/...` or `C:\...`)
124
+ - No external URLs in structural links
125
+
126
+ **Valid:**
127
+
128
+ ```markdown
129
+ [Auth module](./modules/auth.aps.md) [Related spec](../other-plan.aps.md)
130
+ ```
131
+
132
+ **Invalid:**
133
+
134
+ ```markdown
135
+ [Auth module](/docs/planning/modules/auth.aps.md) (absolute)
136
+ [External](https://example.com/spec.md) (external URL)
137
+ ```
138
+
139
+ ### Link Target Validation
140
+
141
+ The validator checks:
142
+
143
+ - Target file exists
144
+ - No circular references
145
+ - Broken links are reported with `file:line` location
146
+
147
+ ---
148
+
149
+ ## Task ID Format
150
+
151
+ ### Structure
152
+
153
+ Task IDs follow the pattern: `<SCOPE>-<NUMBER>`
154
+
155
+ **Components:**
156
+
157
+ - **Scope:** UPPERCASE prefix (1-10 characters, alphanumeric)
158
+ - **Separator:** Single hyphen (`-`)
159
+ - **Number:** Zero-padded 3-digit number (001-999)
160
+
161
+ **Examples:**
162
+
163
+ - `AUTH-001` ✓
164
+ - `PAY-042` ✓
165
+ - `DB-999` ✓
166
+ - `ADMIN-123` ✓
167
+
168
+ **Invalid:**
169
+
170
+ - `auth-001` ✗ (lowercase scope)
171
+ - `AUTH_001` ✗ (underscore instead of hyphen)
172
+ - `AUTH001` ✗ (no separator)
173
+ - `AUTH-1` ✗ (not zero-padded)
174
+ - `AUTH-1234` ✗ (too many digits)
175
+
176
+ ### Uniqueness
177
+
178
+ Task IDs must be **globally unique** across the entire plan graph.
179
+
180
+ The validator will report duplicate IDs with file:line references:
181
+
182
+ ```
183
+ Error: Duplicate task ID 'AUTH-001'
184
+ Found in:
185
+ - docs/planning/modules/auth.aps.md:23
186
+ - docs/planning/modules/admin.aps.md:45
187
+ ```
188
+
189
+ ### Numbering Conventions
190
+
191
+ **Sequential numbering:**
192
+
193
+ ```markdown
194
+ AUTH-001: First task AUTH-002: Second task AUTH-003: Third task
195
+ ```
196
+
197
+ **Gap numbering (recommended for long-lived plans):**
198
+
199
+ ```markdown
200
+ AUTH-010: User model AUTH-020: Login endpoint AUTH-030: Password reset
201
+ ```
202
+
203
+ Gap numbering allows insertion of tasks without renumbering.
204
+
205
+ ---
206
+
207
+ ## Field Format
208
+
209
+ ### Key-Value Fields
210
+
211
+ Task and module metadata use bold key-value format:
212
+
213
+ ```markdown
214
+ **Key:** Value
215
+ ```
216
+
217
+ **Rules:**
218
+
219
+ - Key must be bold (surrounded by `**`)
220
+ - Key must end with colon (`:`)
221
+ - Value starts after the space following the colon
222
+ - Value continues to end of line
223
+
224
+ **Valid:**
225
+
226
+ ```markdown
227
+ **Intent:** Create login endpoint **Scope:** AUTH **Tags:** security, api
228
+ ```
229
+
230
+ **Invalid:**
231
+
232
+ ```markdown
233
+ Intent: Create login endpoint (key not bold) **Intent** Create login endpoint
234
+ (no colon) **Intent:**Create login endpoint (no space after colon)
235
+ ```
236
+
237
+ ### Multi-Line Fields
238
+
239
+ Some fields support multi-line values:
240
+
241
+ ```markdown
242
+ **Inputs:**
243
+
244
+ - User credentials
245
+ - Database connection
246
+ - Email service
247
+ ```
248
+
249
+ Fields that support lists:
250
+
251
+ - **Inputs:**
252
+ - **Dependencies:** (also supports inline comma-separated)
253
+ - **Tags:** (also supports inline comma-separated)
254
+
255
+ ### Inline Lists
256
+
257
+ Comma-separated values:
258
+
259
+ ```markdown
260
+ **Tags:** security, api, high-risk **Scopes:** AUTH, DB **Dependencies:**
261
+ AUTH-001, DB-002
262
+ ```
263
+
264
+ **Rules:**
265
+
266
+ - Comma-separated
267
+ - Optional space after comma
268
+ - No trailing comma
269
+
270
+ ---
271
+
272
+ ## Scope Naming
273
+
274
+ ### Scope Format
275
+
276
+ Scopes are UPPERCASE alphanumeric identifiers:
277
+
278
+ **Valid:**
279
+
280
+ - `AUTH`
281
+ - `PAY`
282
+ - `DB`
283
+ - `ADMIN`
284
+ - `API`
285
+
286
+ **Invalid:**
287
+
288
+ - `auth` (lowercase)
289
+ - `Auth` (mixed case)
290
+ - `AUTH_API` (underscore - use `AUTHAPI` or separate scopes)
291
+
292
+ ### Scope Assignment
293
+
294
+ **Module level:**
295
+
296
+ ```markdown
297
+ ### auth
298
+
299
+ - **Scope:** AUTH
300
+ ```
301
+
302
+ **Task level:**
303
+
304
+ ```markdown
305
+ **Scopes:** AUTH, DB
306
+ ```
307
+
308
+ **Note:** Task-level `Scopes` is plural, module-level `Scope` is singular.
309
+
310
+ ### Multi-Scope Tasks
311
+
312
+ Tasks can declare multiple scopes:
313
+
314
+ ```markdown
315
+ ### AUTH-001: Migrate user table
316
+
317
+ **Intent:** Add email_verified column to users table **Scopes:** AUTH, DB
318
+ ```
319
+
320
+ This task can modify both AUTH and DB code.
321
+
322
+ ---
323
+
324
+ ## Tag Conventions
325
+
326
+ ### Format
327
+
328
+ Tags are lowercase, kebab-case:
329
+
330
+ **Recommended:**
331
+
332
+ ```markdown
333
+ **Tags:** security, api, high-risk, needs-review
334
+ ```
335
+
336
+ **Also valid:**
337
+
338
+ ```markdown
339
+ **Tags:** security, api-v2, database-migration
340
+ ```
341
+
342
+ **Avoid:**
343
+
344
+ ```markdown
345
+ **Tags:** Security, API, HIGH_RISK (mixed case/underscores)
346
+ ```
347
+
348
+ ### Common Tags
349
+
350
+ Suggested tags for consistency:
351
+
352
+ **Type:**
353
+
354
+ - `api`, `ui`, `database`, `infrastructure`, `testing`
355
+
356
+ **Priority:**
357
+
358
+ - `high-priority`, `low-priority`, `nice-to-have`
359
+
360
+ **Risk:**
361
+
362
+ - `high-risk`, `breaking-change`, `security-critical`
363
+
364
+ **Process:**
365
+
366
+ - `needs-review`, `needs-testing`, `blocked`, `spike`
367
+
368
+ ---
369
+
370
+ ## Confidence Levels
371
+
372
+ ### Values
373
+
374
+ Three confidence levels:
375
+
376
+ - **`low`** — Uncertain approach, may require experimentation
377
+ - **medium`** — Generally clear, some unknowns
378
+ - **`high`** — Well-understood, clear path forward
379
+
380
+ ### Usage
381
+
382
+ Confidence helps prioritise and signal uncertainty:
383
+
384
+ ```markdown
385
+ ### AUTH-001: Implement login
386
+
387
+ **Confidence:** high **Intent:** Create standard JWT-based login
388
+
389
+ ### AUTH-010: Add OAuth support
390
+
391
+ **Confidence:** low **Intent:** Evaluate OAuth providers and integrate best fit
392
+ ```
393
+
394
+ **Low confidence** signals:
395
+
396
+ - May require research or spikes
397
+ - Approach not yet determined
398
+ - Higher risk of scope change
399
+
400
+ ---
401
+
402
+ ## Priority Levels
403
+
404
+ ### Values
405
+
406
+ Three priority levels:
407
+
408
+ - **`low`** — Nice to have, non-critical
409
+ - **`medium`** — Important, normal priority
410
+ - **`high`** — Critical, must complete soon
411
+
412
+ ### Module Priority
413
+
414
+ ```markdown
415
+ ### auth
416
+
417
+ - **Priority:** high
418
+ ```
419
+
420
+ ### Task Priority
421
+
422
+ Tasks inherit module priority unless overridden:
423
+
424
+ ```markdown
425
+ ### AUTH-001: Implement login
426
+
427
+ **Priority:** high (override module priority)
428
+ ```
429
+
430
+ ---
431
+
432
+ ## Owner Format
433
+
434
+ ### Syntax
435
+
436
+ Owners use `@username` format:
437
+
438
+ ```markdown
439
+ **Owner:** @alice
440
+ ```
441
+
442
+ ### Team Ownership
443
+
444
+ Teams can be prefixed with `@team/`:
445
+
446
+ ```markdown
447
+ **Owner:** @team/platform
448
+ ```
449
+
450
+ ### Multiple Owners
451
+
452
+ Use comma-separated list:
453
+
454
+ ```markdown
455
+ **Owner:** @alice, @bob
456
+ ```
457
+
458
+ ---
459
+
460
+ ## Dependency Format
461
+
462
+ ### Task Dependencies
463
+
464
+ Reference task IDs:
465
+
466
+ ```markdown
467
+ **Dependencies:** AUTH-001, DB-002
468
+ ```
469
+
470
+ ### Module Dependencies
471
+
472
+ Reference module IDs:
473
+
474
+ ```markdown
475
+ ### payments
476
+
477
+ - **Dependencies:** auth, database
478
+ ```
479
+
480
+ ### Dependency Resolution
481
+
482
+ Dependencies create a directed graph. The validator checks:
483
+
484
+ - All referenced IDs exist
485
+ - No circular dependencies
486
+
487
+ ---
488
+
489
+ ## Status Management
490
+
491
+ ### Where Status Lives
492
+
493
+ Task status is **NOT** stored in planning docs. It lives in `.anvil/state.json`:
494
+
495
+ **Planning doc (source):**
496
+
497
+ ```markdown
498
+ ### AUTH-001: Implement login
499
+
500
+ **Intent:** Create login endpoint (no status field)
501
+ ```
502
+
503
+ **State file (derived):**
504
+
505
+ ```json
506
+ {
507
+ "AUTH-001": {
508
+ "status": "locked",
509
+ "locked_at": "2025-12-17T10:30:00Z",
510
+ "locked_by": "alice",
511
+ "source": {
512
+ "file": "docs/planning/modules/auth.aps.md",
513
+ "line": 23
514
+ }
515
+ }
516
+ }
517
+ ```
518
+
519
+ ### Why Separate?
520
+
521
+ - Planning docs remain clean, version-controllable
522
+ - Status is execution state, not planning intent
523
+ - Avoids merge conflicts from concurrent work
524
+ - Single source of truth: `.anvil/state.json`
525
+
526
+ ---
527
+
528
+ ## Markdown Formatting
529
+
530
+ ### Code Blocks
531
+
532
+ Use fenced code blocks with language identifiers:
533
+
534
+ ````markdown
535
+ ```typescript
536
+ const user = await db.users.findOne({ email });
537
+ ```
538
+ ````
539
+
540
+ ### Lists
541
+
542
+ Use consistent list markers:
543
+
544
+ **Unordered:**
545
+
546
+ ```markdown
547
+ - First item
548
+ - Second item
549
+ - Nested item
550
+ ```
551
+
552
+ **Ordered:**
553
+
554
+ ```markdown
555
+ 1. First step
556
+ 2. Second step
557
+ 3. Third step
558
+ ```
559
+
560
+ ### Emphasis
561
+
562
+ - **Bold** for field keys and emphasis: `**Intent:**`
563
+ - _Italic_ for subtle emphasis: `_Note:_`
564
+ - `Code` for identifiers: `` `AUTH-001` ``
565
+
566
+ ---
567
+
568
+ ## Best Practices
569
+
570
+ ### Task Sizing
571
+
572
+ Keep tasks small and focused:
573
+
574
+ **Too large:**
575
+
576
+ ```markdown
577
+ ### AUTH-001: Implement entire auth system
578
+ ```
579
+
580
+ **Better:**
581
+
582
+ ```markdown
583
+ ### AUTH-001: Create user model
584
+
585
+ ### AUTH-002: Implement login endpoint
586
+
587
+ ### AUTH-003: Add password reset flow
588
+ ```
589
+
590
+ ### Intent Clarity
591
+
592
+ Intents should be concise but clear:
593
+
594
+ **Too vague:**
595
+
596
+ ```markdown
597
+ **Intent:** Fix auth
598
+ ```
599
+
600
+ **Better:**
601
+
602
+ ```markdown
603
+ **Intent:** Add email verification to signup flow
604
+ ```
605
+
606
+ ### Module Granularity
607
+
608
+ Group related functionality:
609
+
610
+ **Too granular:**
611
+
612
+ - `login.aps.md`
613
+ - `logout.aps.md`
614
+ - `signup.aps.md`
615
+
616
+ **Better:**
617
+
618
+ - `auth.aps.md` (contains login, logout, signup tasks)
619
+
620
+ ---
621
+
622
+ ## Validation Workflow
623
+
624
+ 1. Write planning doc
625
+ 2. Run `anvil plan validate`
626
+ 3. Fix errors (required)
627
+ 4. Consider warnings (recommended)
628
+ 5. Commit planning doc
629
+ 6. Lock tasks as needed: `anvil plan lock --task AUTH-001`
630
+
631
+ ---
632
+
633
+ ## Version History
634
+
635
+ - **v0.1** (2025-12-17) — Initial conventions