@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,5 @@
1
+ /**
2
+ * Template generation for APS planning documents
3
+ */
4
+
5
+ export * from './generator.js';
@@ -0,0 +1,168 @@
1
+ /**
2
+ * APS type definitions and schemas
3
+ */
4
+
5
+ import { z } from 'zod';
6
+
7
+ /**
8
+ * Task confidence levels
9
+ */
10
+ export const ConfidenceSchema = z.enum(['low', 'medium', 'high']);
11
+ export type Confidence = z.infer<typeof ConfidenceSchema>;
12
+
13
+ /**
14
+ * Task status values
15
+ * Note: Status is managed externally in .anvil/state.json
16
+ */
17
+ export const TaskStatusSchema = z.enum(['open', 'locked', 'completed', 'cancelled']);
18
+ export type TaskStatus = z.infer<typeof TaskStatusSchema>;
19
+
20
+ /**
21
+ * Priority levels
22
+ */
23
+ export const PrioritySchema = z.enum(['low', 'medium', 'high']);
24
+ export type Priority = z.infer<typeof PrioritySchema>;
25
+
26
+ /**
27
+ * Parsed task from APS document
28
+ */
29
+ /** Task ID regex: 1-10 uppercase alphanumeric scope, hyphen, 3-digit zero-padded number */
30
+ export const TASK_ID_REGEX = /^[A-Z0-9]{1,10}-\d{3}$/;
31
+
32
+ export const TaskSchema = z.object({
33
+ /** Task ID in format SCOPE-NUMBER (e.g., AUTH-001, LLM2-007) */
34
+ id: z.string().regex(TASK_ID_REGEX),
35
+
36
+ /** Task title (after the ID and colon in H3 heading) */
37
+ title: z.string(),
38
+
39
+ /** What the task aims to achieve (required) */
40
+ intent: z.string(),
41
+
42
+ /** Success criteria (optional) */
43
+ expectedOutcome: z.string().optional(),
44
+
45
+ /** Command or method to verify task completion (optional) */
46
+ validation: z.string().optional(),
47
+
48
+ /** Certainty about approach (optional, defaults to 'medium') */
49
+ confidence: ConfidenceSchema.default('medium'),
50
+
51
+ /** What can be changed - LLM file access constraints (optional) */
52
+ scopes: z.array(z.string()).optional(),
53
+
54
+ /** What will NOT be changed (optional) */
55
+ nonScope: z.array(z.string()).optional(),
56
+
57
+ /** Best-effort list of files that may be affected (optional) */
58
+ files: z.array(z.string()).optional(),
59
+
60
+ /** Labels for filtering and search (optional) */
61
+ tags: z.array(z.string()).optional(),
62
+
63
+ /** Tasks that must complete first (optional) */
64
+ dependencies: z.array(z.string()).optional(),
65
+
66
+ /** Required inputs or context (optional) */
67
+ inputs: z.array(z.string()).optional(),
68
+
69
+ /** Potential risks associated with this task (optional) */
70
+ risks: z.array(z.string()).optional(),
71
+
72
+ /** Packages affected by this task (monorepo support) */
73
+ packages: z.array(z.string()).optional(),
74
+
75
+ /** External link (e.g., Jira ticket) (optional) */
76
+ link: z.string().optional(),
77
+
78
+ /** Current execution state (optional, managed externally) */
79
+ status: TaskStatusSchema.optional(),
80
+
81
+ /** Source file path where this task was parsed from */
82
+ sourcePath: z.string().optional(),
83
+
84
+ /** Line number in source file where this task starts */
85
+ sourceLineNumber: z.number().optional(),
86
+ });
87
+
88
+ export type Task = z.infer<typeof TaskSchema>;
89
+
90
+ /**
91
+ * Module status values
92
+ * Legacy values (Draft, Complete) are accepted during parsing but normalised
93
+ * to their canonical equivalents (Proposed, Done).
94
+ */
95
+ export const ModuleStatusSchema = z.enum(['Proposed', 'Ready', 'In Progress', 'Done', 'Blocked']);
96
+ export type ModuleStatus = z.infer<typeof ModuleStatusSchema>;
97
+
98
+ /**
99
+ * Module metadata from index files or leaf spec headers
100
+ */
101
+ export const ModuleMetadataSchema = z.object({
102
+ /** Module identifier (e.g., 'auth', 'payments') */
103
+ id: z.string().optional(),
104
+
105
+ /** Module title from H1 heading */
106
+ title: z.string().optional(),
107
+
108
+ /** Path to leaf spec file (for index files) */
109
+ path: z.string().optional(),
110
+
111
+ /** Scope prefix for task IDs (e.g., AUTH, PAY) */
112
+ scope: z.string().optional(),
113
+
114
+ /** Person/team responsible */
115
+ owner: z.string().optional(),
116
+
117
+ /** Current module status */
118
+ status: ModuleStatusSchema.optional(),
119
+
120
+ /** Priority level */
121
+ priority: PrioritySchema.optional(),
122
+
123
+ /** Tags for filtering */
124
+ tags: z.array(z.string()).optional(),
125
+
126
+ /** Modules this depends on */
127
+ dependencies: z.array(z.string()).optional(),
128
+
129
+ /** Packages affected by this module (monorepo support) */
130
+ packages: z.array(z.string()).optional(),
131
+ });
132
+
133
+ export type ModuleMetadata = z.infer<typeof ModuleMetadataSchema>;
134
+
135
+ /**
136
+ * Parsed leaf spec document result
137
+ * For index files, use ParsedIndex from the parser module
138
+ */
139
+ export interface ParsedDocument {
140
+ /** Document title from H1 */
141
+ title: string;
142
+
143
+ /** Module metadata from header line */
144
+ metadata?: ModuleMetadata;
145
+
146
+ /** List of tasks */
147
+ tasks: Task[];
148
+
149
+ /** Source file path */
150
+ sourcePath?: string;
151
+ }
152
+
153
+ /**
154
+ * Parser error with context
155
+ */
156
+ export class ParseError extends Error {
157
+ constructor(
158
+ message: string,
159
+ public readonly sourcePath?: string,
160
+ public readonly lineNumber?: number,
161
+ public readonly context?: string
162
+ ) {
163
+ super(message);
164
+ this.name = 'ParseError';
165
+ }
166
+ }
167
+
168
+ // ValidationResult is exported from validator/index.ts
@@ -0,0 +1,10 @@
1
+ # Project Plan
2
+
3
+ > Index with broken module links.
4
+
5
+ ## Modules
6
+
7
+ ### auth
8
+
9
+ - **Path:** [./modules/nonexistent.aps.md](./modules/nonexistent.aps.md)
10
+ - **Scope:** AUTH
@@ -0,0 +1,26 @@
1
+ # Project Plan
2
+
3
+ > Index for testing circular dependency detection.
4
+
5
+ ## Modules
6
+
7
+ ### module-a
8
+
9
+ - **Path:**
10
+ [./circular-modules/module-a.aps.md](./circular-modules/module-a.aps.md)
11
+ - **Scope:** CIRC
12
+ - **Dependencies:** module-b
13
+
14
+ ### module-b
15
+
16
+ - **Path:**
17
+ [./circular-modules/module-b.aps.md](./circular-modules/module-b.aps.md)
18
+ - **Scope:** CIRC
19
+ - **Dependencies:** module-c
20
+
21
+ ### module-c
22
+
23
+ - **Path:**
24
+ [./circular-modules/module-c.aps.md](./circular-modules/module-c.aps.md)
25
+ - **Scope:** CIRC
26
+ - **Dependencies:** module-a
@@ -0,0 +1,9 @@
1
+ # Module A
2
+
3
+ **Scope:** CIRC
4
+
5
+ ## Tasks
6
+
7
+ ### CIRC-001: Task A
8
+
9
+ **Intent:** Task in module A **Confidence:** high
@@ -0,0 +1,9 @@
1
+ # Module B
2
+
3
+ **Scope:** CIRC
4
+
5
+ ## Tasks
6
+
7
+ ### CIRC-002: Task B
8
+
9
+ **Intent:** Task in module B **Confidence:** high
@@ -0,0 +1,9 @@
1
+ # Module C
2
+
3
+ **Scope:** CIRC
4
+
5
+ ## Tasks
6
+
7
+ ### CIRC-003: Task C
8
+
9
+ **Intent:** Task in module C **Confidence:** high
@@ -0,0 +1,9 @@
1
+ # Module A
2
+
3
+ **Scope:** DUP
4
+
5
+ ## Tasks
6
+
7
+ ### DUP-001: First task
8
+
9
+ **Intent:** This task ID will be duplicated **Confidence:** high
@@ -0,0 +1,9 @@
1
+ # Module B
2
+
3
+ **Scope:** DUP
4
+
5
+ ## Tasks
6
+
7
+ ### DUP-001: Duplicate task
8
+
9
+ **Intent:** This task ID is duplicated from module-a **Confidence:** high
@@ -0,0 +1,15 @@
1
+ # Project Plan
2
+
3
+ > Index for testing duplicate ID detection.
4
+
5
+ ## Modules
6
+
7
+ ### module-a
8
+
9
+ - **Path:** [./dup-modules/module-a.aps.md](./dup-modules/module-a.aps.md)
10
+ - **Scope:** DUP
11
+
12
+ ### module-b
13
+
14
+ - **Path:** [./dup-modules/module-b.aps.md](./dup-modules/module-b.aps.md)
15
+ - **Scope:** DUP
@@ -0,0 +1,17 @@
1
+ # Test Module
2
+
3
+ **Scope:** TEST
4
+
5
+ ## Tasks
6
+
7
+ ### test-001: Lowercase ID
8
+
9
+ **Intent:** This ID is lowercase which is invalid
10
+
11
+ ### T-1: Too short number
12
+
13
+ **Intent:** This ID number should be 3 digits
14
+
15
+ ### VERYLONGSCOPE123-001: Scope too long
16
+
17
+ **Intent:** Scope should be 1-10 characters
@@ -0,0 +1,9 @@
1
+ # Test Module
2
+
3
+ **Scope:** TEST
4
+
5
+ ## Tasks
6
+
7
+ ### TEST-001: Task without confidence
8
+
9
+ **Intent:** Do something without specifying confidence
@@ -0,0 +1,5 @@
1
+ ## Tasks
2
+
3
+ ### TEST-001: Some task
4
+
5
+ **Intent:** Do something
@@ -0,0 +1,9 @@
1
+ # Test Module
2
+
3
+ **Scope:** TEST
4
+
5
+ ## Tasks
6
+
7
+ ### TEST-001: Task without intent
8
+
9
+ **Confidence:** high **Expected Outcome:** Something happens
@@ -0,0 +1,7 @@
1
+ # Project Plan
2
+
3
+ > This index file is missing the Modules section.
4
+
5
+ ## Open Questions
6
+
7
+ - What modules do we need?
@@ -0,0 +1,7 @@
1
+ # Test Module
2
+
3
+ **Scope:** TEST
4
+
5
+ ## Notes
6
+
7
+ This module has no Tasks section.
@@ -0,0 +1,17 @@
1
+ # Authentication Module
2
+
3
+ **Scope:** AUTH **Owner:** @alice
4
+
5
+ ## Tasks
6
+
7
+ ### AUTH-001: Implement login
8
+
9
+ **Intent:** Create login endpoint **Confidence:** high
10
+
11
+ ### AUTH-002: Add logout
12
+
13
+ **Intent:** Create logout endpoint **Confidence:** high
14
+
15
+ ## Notes
16
+
17
+ - Use JWT tokens
@@ -0,0 +1,13 @@
1
+ # Payments Module
2
+
3
+ **Scope:** PAY **Owner:** @bob
4
+
5
+ ## Tasks
6
+
7
+ ### PAY-001: Integrate Stripe
8
+
9
+ **Intent:** Set up Stripe payment processing **Confidence:** medium
10
+
11
+ ### PAY-002: Add invoicing
12
+
13
+ **Intent:** Generate PDF invoices **Confidence:** low **Dependencies:** PAY-001
@@ -0,0 +1,14 @@
1
+ # Test Module
2
+
3
+ **Scope:** TEST
4
+
5
+ ## Tasks
6
+
7
+ ### AUTH-001: Wrong scope prefix
8
+
9
+ **Intent:** This task has AUTH prefix but module scope is TEST **Confidence:**
10
+ high
11
+
12
+ ### TEST-001: Correct scope prefix
13
+
14
+ **Intent:** This task has matching scope **Confidence:** high
@@ -0,0 +1,24 @@
1
+ # Project Plan
2
+
3
+ > A multi-module project plan for testing validation.
4
+
5
+ ## Modules
6
+
7
+ ### auth
8
+
9
+ - **Path:** [./modules/auth.aps.md](./modules/auth.aps.md)
10
+ - **Scope:** AUTH
11
+ - **Owner:** @alice
12
+ - **Priority:** high
13
+
14
+ ### payments
15
+
16
+ - **Path:** [./modules/payments.aps.md](./modules/payments.aps.md)
17
+ - **Scope:** PAY
18
+ - **Owner:** @bob
19
+ - **Priority:** medium
20
+ - **Dependencies:** auth
21
+
22
+ ## Open Questions
23
+
24
+ - How do we handle rate limiting?
@@ -0,0 +1,22 @@
1
+ # Authentication Module
2
+
3
+ **Scope:** AUTH **Owner:** @alice **Priority:** high
4
+
5
+ > Handles user authentication and session management.
6
+
7
+ ## Tasks
8
+
9
+ ### AUTH-001: Implement login endpoint
10
+
11
+ **Intent:** Create POST /auth/login endpoint with JWT response **Confidence:**
12
+ high **Expected Outcome:** Returns JWT token on success, 401 on failure
13
+ **Tags:** security, api
14
+
15
+ ### AUTH-002: Add password reset
16
+
17
+ **Intent:** Implement password reset flow with email verification
18
+ **Confidence:** medium **Dependencies:** AUTH-001
19
+
20
+ ## Notes
21
+
22
+ - Consider OAuth support in future