@eddacraft/anvil-adapters 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 (183) hide show
  1. package/AGENTS.md +180 -0
  2. package/BMAD_ADAPTER_SPEC.md +489 -0
  3. package/LICENSE +14 -0
  4. package/README.md +500 -0
  5. package/dist/aps-markdown/adapter.d.ts +102 -0
  6. package/dist/aps-markdown/adapter.d.ts.map +1 -0
  7. package/dist/aps-markdown/adapter.js +351 -0
  8. package/dist/aps-markdown/index.d.ts +8 -0
  9. package/dist/aps-markdown/index.d.ts.map +1 -0
  10. package/dist/aps-markdown/index.js +7 -0
  11. package/dist/base/file-discovery.d.ts +63 -0
  12. package/dist/base/file-discovery.d.ts.map +1 -0
  13. package/dist/base/file-discovery.js +246 -0
  14. package/dist/base/index.d.ts +10 -0
  15. package/dist/base/index.d.ts.map +1 -0
  16. package/dist/base/index.js +9 -0
  17. package/dist/base/registry.d.ts +155 -0
  18. package/dist/base/registry.d.ts.map +1 -0
  19. package/dist/base/registry.js +227 -0
  20. package/dist/base/testing.d.ts +102 -0
  21. package/dist/base/testing.d.ts.map +1 -0
  22. package/dist/base/testing.js +221 -0
  23. package/dist/base/types.d.ts +255 -0
  24. package/dist/base/types.d.ts.map +1 -0
  25. package/dist/base/types.js +78 -0
  26. package/dist/base/utils.d.ts +127 -0
  27. package/dist/base/utils.d.ts.map +1 -0
  28. package/dist/base/utils.js +254 -0
  29. package/dist/bmad/format-adapter.d.ts +76 -0
  30. package/dist/bmad/format-adapter.d.ts.map +1 -0
  31. package/dist/bmad/format-adapter.js +186 -0
  32. package/dist/bmad/index.d.ts +12 -0
  33. package/dist/bmad/index.d.ts.map +1 -0
  34. package/dist/bmad/index.js +10 -0
  35. package/dist/bmad/parser.d.ts +12 -0
  36. package/dist/bmad/parser.d.ts.map +1 -0
  37. package/dist/bmad/parser.js +181 -0
  38. package/dist/bmad/serializer.d.ts +16 -0
  39. package/dist/bmad/serializer.d.ts.map +1 -0
  40. package/dist/bmad/serializer.js +170 -0
  41. package/dist/bmad/types.d.ts +127 -0
  42. package/dist/bmad/types.d.ts.map +1 -0
  43. package/dist/bmad/types.js +47 -0
  44. package/dist/bmad/utils.d.ts +120 -0
  45. package/dist/bmad/utils.d.ts.map +1 -0
  46. package/dist/bmad/utils.js +480 -0
  47. package/dist/common/index.d.ts +3 -0
  48. package/dist/common/index.d.ts.map +1 -0
  49. package/dist/common/index.js +2 -0
  50. package/dist/common/registry.d.ts +18 -0
  51. package/dist/common/registry.d.ts.map +1 -0
  52. package/dist/common/registry.js +58 -0
  53. package/dist/common/types.d.ts +68 -0
  54. package/dist/common/types.d.ts.map +1 -0
  55. package/dist/common/types.js +12 -0
  56. package/dist/generic/format-adapter.d.ts +64 -0
  57. package/dist/generic/format-adapter.d.ts.map +1 -0
  58. package/dist/generic/format-adapter.js +159 -0
  59. package/dist/generic/index.d.ts +10 -0
  60. package/dist/generic/index.d.ts.map +1 -0
  61. package/dist/generic/index.js +9 -0
  62. package/dist/generic/parser.d.ts +11 -0
  63. package/dist/generic/parser.d.ts.map +1 -0
  64. package/dist/generic/parser.js +106 -0
  65. package/dist/generic/serializer.d.ts +11 -0
  66. package/dist/generic/serializer.d.ts.map +1 -0
  67. package/dist/generic/serializer.js +118 -0
  68. package/dist/generic/types.d.ts +52 -0
  69. package/dist/generic/types.d.ts.map +1 -0
  70. package/dist/generic/types.js +6 -0
  71. package/dist/generic/utils.d.ts +51 -0
  72. package/dist/generic/utils.d.ts.map +1 -0
  73. package/dist/generic/utils.js +232 -0
  74. package/dist/index.d.ts +15 -0
  75. package/dist/index.d.ts.map +1 -0
  76. package/dist/index.js +31 -0
  77. package/dist/speckit/export.d.ts +22 -0
  78. package/dist/speckit/export.d.ts.map +1 -0
  79. package/dist/speckit/export.js +384 -0
  80. package/dist/speckit/format-adapter.d.ts +104 -0
  81. package/dist/speckit/format-adapter.d.ts.map +1 -0
  82. package/dist/speckit/format-adapter.js +488 -0
  83. package/dist/speckit/import-v2.d.ts +33 -0
  84. package/dist/speckit/import-v2.d.ts.map +1 -0
  85. package/dist/speckit/import-v2.js +361 -0
  86. package/dist/speckit/import.d.ts +16 -0
  87. package/dist/speckit/import.d.ts.map +1 -0
  88. package/dist/speckit/import.js +247 -0
  89. package/dist/speckit/index.d.ts +5 -0
  90. package/dist/speckit/index.d.ts.map +1 -0
  91. package/dist/speckit/index.js +4 -0
  92. package/dist/speckit/parser.d.ts +28 -0
  93. package/dist/speckit/parser.d.ts.map +1 -0
  94. package/dist/speckit/parser.js +283 -0
  95. package/dist/speckit/parsers/plan-parser.d.ts +71 -0
  96. package/dist/speckit/parsers/plan-parser.d.ts.map +1 -0
  97. package/dist/speckit/parsers/plan-parser.js +216 -0
  98. package/dist/speckit/parsers/spec-parser.d.ts +67 -0
  99. package/dist/speckit/parsers/spec-parser.d.ts.map +1 -0
  100. package/dist/speckit/parsers/spec-parser.js +255 -0
  101. package/dist/speckit/parsers/tasks-parser.d.ts +57 -0
  102. package/dist/speckit/parsers/tasks-parser.d.ts.map +1 -0
  103. package/dist/speckit/parsers/tasks-parser.js +157 -0
  104. package/package.json +23 -0
  105. package/project.json +29 -0
  106. package/src/__tests__/adapter-edge-cases.test.ts +937 -0
  107. package/src/__tests__/bmad-format-adapter.test.ts +1470 -0
  108. package/src/__tests__/fixtures/aps/expected-output.json +83 -0
  109. package/src/__tests__/fixtures/bmad/invalid-malformed-yaml.md +16 -0
  110. package/src/__tests__/fixtures/bmad/invalid-no-requirements.md +23 -0
  111. package/src/__tests__/fixtures/bmad/invalid-only-yaml.md +16 -0
  112. package/src/__tests__/fixtures/bmad/invalid-too-short.md +3 -0
  113. package/src/__tests__/fixtures/bmad/invalid-wrong-format.md +40 -0
  114. package/src/__tests__/fixtures/bmad/valid-agent.md +27 -0
  115. package/src/__tests__/fixtures/bmad/valid-architecture.md +116 -0
  116. package/src/__tests__/fixtures/bmad/valid-complex-prd.md +161 -0
  117. package/src/__tests__/fixtures/bmad/valid-epic.md +73 -0
  118. package/src/__tests__/fixtures/bmad/valid-minimal-prd.md +19 -0
  119. package/src/__tests__/fixtures/bmad/valid-prd.md +107 -0
  120. package/src/__tests__/fixtures/bmad/valid-story.md +107 -0
  121. package/src/__tests__/fixtures/bmad/valid-task.md +79 -0
  122. package/src/__tests__/fixtures/bmad/valid-v6-prd.md +35 -0
  123. package/src/__tests__/fixtures/generic/plan-detailed.md +39 -0
  124. package/src/__tests__/fixtures/generic/prd-simple.md +27 -0
  125. package/src/__tests__/fixtures/generic/rfc-example.md +26 -0
  126. package/src/__tests__/fixtures/generic/todo-list.md +23 -0
  127. package/src/__tests__/fixtures/speckit/sample-plan.md +63 -0
  128. package/src/__tests__/fixtures/speckit/sample-spec-namespaced.md +50 -0
  129. package/src/__tests__/fixtures/speckit/sample-spec.md +105 -0
  130. package/src/__tests__/fixtures/speckit/sample-tasks.md +87 -0
  131. package/src/__tests__/fixtures/speckit-official/auth-feature/plan.md +272 -0
  132. package/src/__tests__/fixtures/speckit-official/auth-feature/spec.md +149 -0
  133. package/src/__tests__/fixtures/speckit-official/auth-feature/tasks.md +169 -0
  134. package/src/__tests__/generic-format-adapter.test.ts +398 -0
  135. package/src/__tests__/speckit-export.test.ts +233 -0
  136. package/src/__tests__/speckit-format-adapter.test.ts +832 -0
  137. package/src/__tests__/speckit-import-v2.test.ts +253 -0
  138. package/src/__tests__/speckit-import.test.ts +209 -0
  139. package/src/__tests__/speckit-parser.test.ts +219 -0
  140. package/src/__tests__/speckit-spec-parser.test.ts +120 -0
  141. package/src/aps-markdown/__tests__/__fixtures__/simple-leaf.aps.md +17 -0
  142. package/src/aps-markdown/__tests__/adapter.test.ts +393 -0
  143. package/src/aps-markdown/adapter.ts +455 -0
  144. package/src/aps-markdown/index.ts +8 -0
  145. package/src/base/__tests__/registry.test.ts +515 -0
  146. package/src/base/file-discovery.ts +305 -0
  147. package/src/base/index.ts +10 -0
  148. package/src/base/registry.ts +263 -0
  149. package/src/base/testing.ts +334 -0
  150. package/src/base/types.ts +342 -0
  151. package/src/base/utils.ts +306 -0
  152. package/src/bmad/format-adapter.ts +227 -0
  153. package/src/bmad/index.ts +21 -0
  154. package/src/bmad/parser.ts +224 -0
  155. package/src/bmad/serializer.ts +206 -0
  156. package/src/bmad/types.ts +135 -0
  157. package/src/bmad/utils.ts +575 -0
  158. package/src/common/index.ts +2 -0
  159. package/src/common/registry.ts +72 -0
  160. package/src/common/types.ts +84 -0
  161. package/src/generic/__tests__/serializer.test.ts +167 -0
  162. package/src/generic/format-adapter.ts +200 -0
  163. package/src/generic/index.ts +11 -0
  164. package/src/generic/parser.ts +129 -0
  165. package/src/generic/serializer.ts +134 -0
  166. package/src/generic/types.ts +53 -0
  167. package/src/generic/utils.ts +270 -0
  168. package/src/index.ts +48 -0
  169. package/src/speckit/export.ts +489 -0
  170. package/src/speckit/format-adapter.ts +595 -0
  171. package/src/speckit/import-v2.ts +445 -0
  172. package/src/speckit/import.ts +305 -0
  173. package/src/speckit/index.ts +4 -0
  174. package/src/speckit/parser.ts +351 -0
  175. package/src/speckit/parsers/plan-parser.ts +342 -0
  176. package/src/speckit/parsers/spec-parser.ts +379 -0
  177. package/src/speckit/parsers/tasks-parser.ts +246 -0
  178. package/tsconfig.json +26 -0
  179. package/tsconfig.lib.json +21 -0
  180. package/tsconfig.lib.tsbuildinfo +1 -0
  181. package/tsconfig.spec.json +9 -0
  182. package/tsconfig.tsbuildinfo +1 -0
  183. package/vitest.config.ts +14 -0
package/README.md ADDED
@@ -0,0 +1,500 @@
1
+ # Anvil Format Adapters
2
+
3
+ Format adapters for converting between external planning formats (SpecKit, BMAD,
4
+ etc.) and Anvil Plan Specification (APS).
5
+
6
+ ## Overview
7
+
8
+ The adapter framework provides a pluggable architecture for working with
9
+ different planning document formats. Users can continue using their preferred
10
+ format while benefiting from APS validation and gate execution internally.
11
+
12
+ ## Architecture
13
+
14
+ ### Core Concepts
15
+
16
+ - **FormatAdapter**: Interface for converting between external formats and APS
17
+ - **AdapterRegistry**: Central registry for adapter discovery and lookup
18
+ - **Auto-detection**: Content-based format detection with confidence scoring
19
+ - **Round-trip fidelity**: Parse and serialize maintain document integrity
20
+
21
+ ### Package Structure
22
+
23
+ ```
24
+ packages/adapters/
25
+ ├── src/
26
+ │ ├── base/ # Framework core
27
+ │ │ ├── types.ts # Core interfaces and types
28
+ │ │ ├── registry.ts # Adapter registry
29
+ │ │ ├── utils.ts # Helper utilities
30
+ │ │ └── testing.ts # Testing utilities
31
+ │ ├── speckit/ # SpecKit adapter ✅
32
+ │ ├── bmad/ # BMAD adapter ✅
33
+ │ └── generic/ # Generic markdown adapter ✅
34
+ └── README.md
35
+ ```
36
+
37
+ ## Usage
38
+
39
+ ### Using Adapters
40
+
41
+ ```typescript
42
+ import { registry } from '@eddacraft/anvil-adapters';
43
+ import { SpecKitAdapter } from '@eddacraft/anvil-adapters/speckit';
44
+
45
+ // Register adapter
46
+ const speckit = new SpecKitAdapter();
47
+ registry.register(speckit);
48
+
49
+ // Auto-detect format
50
+ const content = await fs.readFile('plan.md', 'utf-8');
51
+ const match = registry.detectAdapter(content);
52
+
53
+ if (match) {
54
+ console.log(`Detected: ${match.adapter.metadata.displayName}`);
55
+ console.log(`Confidence: ${match.detection.confidence}%`);
56
+
57
+ // Parse to APS
58
+ const result = await match.adapter.parse(content);
59
+ if (result.success) {
60
+ console.log('Parsed plan:', result.data);
61
+ }
62
+ }
63
+
64
+ // Find adapter by format
65
+ const adapter = registry.getAdapterForFormat('speckit');
66
+ if (adapter) {
67
+ const result = await adapter.parse(content);
68
+ }
69
+ ```
70
+
71
+ ### Creating Custom Adapters
72
+
73
+ See [ADAPTER_WORKFLOW_GUIDE.md](./ADAPTER_WORKFLOW_GUIDE.md) for:
74
+
75
+ - Complete workflow guide with real-world examples
76
+ - Technical deep dive into adapter implementation
77
+ - Step-by-step guide for adding new adapters
78
+ - CLI integration patterns
79
+ - Testing strategies
80
+
81
+ ## API Reference
82
+
83
+ See [packages/adapters/src/base/](./src/base/) for complete API documentation.
84
+
85
+ ### Key Interfaces
86
+
87
+ - `FormatAdapter` - Main adapter interface
88
+ - `AdapterRegistry` - Adapter registration and lookup
89
+ - `ParseResult` - Result of parsing external format to APS
90
+ - `SerializeResult` - Result of serializing APS to external format
91
+ - `DetectionResult` - Result of format detection
92
+
93
+ ## Supported Formats
94
+
95
+ ### SpecKit ✅ COMPLETE
96
+
97
+ GitHub's official spec-driven development format. Supports the complete spec-kit
98
+ workflow with three document types.
99
+
100
+ - **Extensions**: `spec.md`, `plan.md`, `tasks.md`
101
+ - **Status**: ✅ Fully implemented (November 2025)
102
+ - **Version**: 2.0.0
103
+ - **Code**: ~2,469 lines
104
+ - **Tests**: 114 tests (45 format adapter + 69 parsers, all passing ✅)
105
+ - **Coverage**: >95%
106
+
107
+ #### Document Types
108
+
109
+ **spec.md** - Requirements and user scenarios (WHAT and WHY)
110
+
111
+ - Feature metadata (branch, date, status)
112
+ - User scenarios & testing (prioritized user stories with acceptance criteria)
113
+ - Functional requirements (testable requirements with clarification markers)
114
+ - Key entities (data model definitions)
115
+ - Success criteria (quantitative and qualitative metrics)
116
+
117
+ **plan.md** - Technical implementation (HOW)
118
+
119
+ - Summary of technical approach
120
+ - Technical context (language, dependencies, constraints)
121
+ - Constitution check (compliance with project principles)
122
+ - Project structure (directory layout, file organisation)
123
+ - Implementation details (API endpoints, database schema, etc.)
124
+ - Complexity tracking (design decisions and justifications)
125
+
126
+ **tasks.md** - Executable breakdown
127
+
128
+ - Tasks organised by phases with IDs
129
+ - Parallel execution markers
130
+ - Checkpoints after each phase
131
+ - Dependencies and execution order
132
+ - Implementation strategies
133
+
134
+ #### Usage Example
135
+
136
+ ```typescript
137
+ import { SpecKitImportAdapterV2 } from '@eddacraft/anvil-adapters/speckit';
138
+
139
+ const adapter = new SpecKitImportAdapterV2();
140
+
141
+ // Import complete spec-kit feature directory
142
+ const result = await adapter.convertToAPS({
143
+ format: 'speckit',
144
+ version: '2.0.0',
145
+ content: {
146
+ spec: { content: specMdContent },
147
+ plan: { content: planMdContent },
148
+ tasks: { content: tasksMdContent },
149
+ },
150
+ });
151
+
152
+ if (result.success) {
153
+ // APS plan with full metadata from all documents
154
+ const plan = result.data;
155
+
156
+ // Access spec.md data
157
+ console.log(plan.metadata?.userScenarios);
158
+ console.log(plan.metadata?.clarifications);
159
+
160
+ // Access plan.md data
161
+ console.log(plan.metadata?.technicalContext);
162
+ console.log(plan.metadata?.implementationDetails);
163
+
164
+ // Access tasks.md data
165
+ console.log(plan.metadata?.phases);
166
+ console.log(plan.metadata?.taskDependencies);
167
+ }
168
+ ```
169
+
170
+ #### APS Mapping
171
+
172
+ - **User Scenarios** → `proposed_changes` with scenario metadata (user story,
173
+ acceptance criteria, edge cases)
174
+ - **Functional Requirements** → `metadata.requirements.functional[]`
175
+ - **Key Entities** → `metadata.requirements.entities[]`
176
+ - **Success Criteria** → `metadata.successCriteria`
177
+ - **Clarifications** → `metadata.clarifications[]` (all `[NEEDS CLARIFICATION]`
178
+ markers)
179
+ - **Technical Context** → `metadata.technicalContext`
180
+ - **Project Structure** → `metadata.projectStructure`
181
+ - **Implementation Details** → `metadata.implementationDetails`
182
+ - **Phases & Tasks** → `metadata.phases[]`, `metadata.taskDependencies[]`
183
+
184
+ ### BMAD ✅ COMPLETE
185
+
186
+ Business Model and Architecture Document format - enterprise requirements and
187
+ PRD format.
188
+
189
+ - **Extensions**: `.md` (PRD, Architecture, Epic, Story formats)
190
+ - **Status**: ✅ Fully implemented (November 2025)
191
+ - **Version**: 1.0.0
192
+ - **Code**: ~800 lines
193
+ - **Tests**: 86 tests (all passing ✅) - exceeds 50+ target
194
+ - **Coverage**: >95%
195
+ - **CLI Integration**: 100% (validate, gate, export commands)
196
+
197
+ #### Document Types Supported
198
+
199
+ **PRD (Product Requirements Document)**
200
+
201
+ - Functional Requirements (FR-01, FR-02, etc.)
202
+ - Non-Functional Requirements (NFR-01, NFR-02, etc.)
203
+ - Epics and User Stories (US-01, US-02, etc.)
204
+ - YAML front-matter metadata
205
+ - Change log tables
206
+
207
+ **Architecture Documents**
208
+
209
+ - Technical Summary
210
+ - High Level Architecture
211
+ - System Components
212
+ - Tech Stack
213
+ - API Specifications
214
+
215
+ **Epic and Story Documents**
216
+
217
+ - Epic goals and related stories
218
+ - User story format: "As a... I want... so that..."
219
+ - Acceptance criteria
220
+ - Implementation details
221
+
222
+ #### Format Detection
223
+
224
+ Confidence-based algorithm with 5 weighted indicators (100-point scale):
225
+
226
+ - YAML front-matter: 30 points
227
+ - Requirement identifiers (FR/NFR/US): 25 points
228
+ - User story format: 20 points
229
+ - Change log table: 15 points
230
+ - Document title: 10 points
231
+ - **Detection threshold**: 50%
232
+ - **Typical confidence**: 90-100% for valid BMAD documents
233
+
234
+ #### Usage Example
235
+
236
+ ```typescript
237
+ import { BMADFormatAdapter } from '@eddacraft/anvil-adapters/bmad';
238
+
239
+ const adapter = new BMADFormatAdapter();
240
+
241
+ // Detect BMAD format
242
+ const detection = adapter.detect(content);
243
+ console.log(`Confidence: ${detection.confidence}%`);
244
+
245
+ // Parse BMAD to APS
246
+ const parseResult = await adapter.parse(content);
247
+ if (parseResult.success) {
248
+ console.log('Parsed plan:', parseResult.data);
249
+ }
250
+
251
+ // Serialize APS to BMAD
252
+ const serializeResult = await adapter.serialize(apsPlan);
253
+ if (serializeResult.success) {
254
+ console.log('Generated BMAD:', serializeResult.content);
255
+ }
256
+ ```
257
+
258
+ #### CLI Integration
259
+
260
+ ```bash
261
+ # Validate BMAD PRD
262
+ anvil validate docs/prd.md
263
+ # ✓ Detected format: bmad (100% confidence)
264
+
265
+ # Run quality gates on BMAD document
266
+ anvil gate docs/architecture.md
267
+ # ✓ All quality gates passed
268
+
269
+ # Convert BMAD to APS
270
+ anvil export docs/prd.md --to aps
271
+ # ✓ Export complete (6 functional requirements, 3 non-functional requirements)
272
+
273
+ # Roundtrip verification
274
+ # Parse → Serialize → Parse preserves document structure
275
+ ```
276
+
277
+ #### APS Mapping
278
+
279
+ - **Functional Requirements (FR-XX)** → `proposed_changes[]` with type
280
+ `file_create` or `file_update`
281
+ - **Non-Functional Requirements (NFR-XX)** → `proposed_changes[]` with type
282
+ `config_update`
283
+ - **User Stories (US-XX)** → `proposed_changes[]` with acceptance criteria in
284
+ description
285
+ - **YAML Front-matter** → `provenance` (author, date, version)
286
+ - **Document Title/Summary** → `intent.description`
287
+ - **Change Log** → `metadata.changeLog[]`
288
+
289
+ #### Implementation Details
290
+
291
+ **Files**:
292
+
293
+ - `format-adapter.ts` - Main FormatAdapter implementation
294
+ - `parser.ts` - BMAD → APS conversion
295
+ - `serializer.ts` - APS → BMAD generation
296
+ - `types.ts` - BMAD-specific TypeScript types
297
+ - `utils.ts` - Helper functions (metadata extraction, requirement parsing)
298
+
299
+ **Registry Integration**:
300
+
301
+ - Auto-registered with `AdapterRegistry` on module import
302
+ - Discoverable by CLI's `FormatDetectionService`
303
+
304
+ **Validation**:
305
+
306
+ - Content validation without full parse
307
+ - Returns `ValidationIssue[]` with severity levels (error, warning, info)
308
+ - Checks format indicators and document structure
309
+
310
+ **Next Steps**:
311
+
312
+ - ✅ Comprehensive testing complete (86 tests, exceeding 50+ target)
313
+ - ✅ Test fixtures created (6 valid + invalid BMAD documents)
314
+ - ✅ Serves as reference implementation for FormatAdapter interface
315
+
316
+ ### Generic Markdown ✅ COMPLETE
317
+
318
+ Fallback adapter for generic planning documents that don't match SpecKit or BMAD
319
+ formats. Provides broad compatibility for PRDs, TODOs, RFCs, and ADRs.
320
+
321
+ - **Extensions**: `.md` (PRD, TODO, plan, spec, RFC, ADR formats)
322
+ - **Status**: ✅ Fully implemented (November 2025)
323
+ - **Version**: 1.0.0
324
+ - **Code**: ~198 lines
325
+ - **Tests**: 32 tests (all passing ✅)
326
+ - **Coverage**: >95%
327
+ - **Detection**: Fallback adapter (30-45% confidence)
328
+
329
+ #### Supported Document Types
330
+
331
+ - **PRD (Product Requirements Document)** - Generic product requirements
332
+ - **TODO** - Task lists and action items
333
+ - **Plan** - Implementation plans
334
+ - **Spec** - Technical specifications
335
+ - **RFC (Request for Comments)** - Design proposals
336
+ - **ADR (Architecture Decision Records)** - Architecture decisions
337
+
338
+ #### Format Detection
339
+
340
+ Generic adapter uses fallback detection with lower confidence (30-45%):
341
+
342
+ - Generic markdown structure: 15 points
343
+ - Common planning keywords: 10 points
344
+ - Section headers (Requirements, Tasks, etc.): 10 points
345
+ - **Detection threshold**: 30%
346
+ - **Typical confidence**: 30-45% (intentionally lower than specific formats)
347
+
348
+ #### Usage Example
349
+
350
+ ```typescript
351
+ import { GenericMarkdownAdapter } from '@eddacraft/anvil-adapters/generic';
352
+
353
+ const adapter = new GenericMarkdownAdapter();
354
+
355
+ // Detect generic markdown
356
+ const detection = adapter.detect(content);
357
+ console.log(`Confidence: ${detection.confidence}%`);
358
+
359
+ // Parse generic markdown to APS
360
+ const parseResult = await adapter.parse(content);
361
+ if (parseResult.success) {
362
+ // Extracted requirements, tasks, features, goals
363
+ console.log('Parsed plan:', parseResult.data);
364
+ }
365
+ ```
366
+
367
+ #### CLI Integration
368
+
369
+ ```bash
370
+ # Validate generic TODO document
371
+ anvil validate TODO.md
372
+ # ✓ Detected format: generic (45% confidence)
373
+
374
+ # Run gates on generic RFC
375
+ anvil gate docs/RFC-001.md
376
+ # ✓ Format: generic markdown
377
+
378
+ # Works as fallback for unknown formats
379
+ anvil validate docs/custom-plan.md
380
+ # ✓ Falling back to generic markdown adapter
381
+ ```
382
+
383
+ #### APS Mapping
384
+
385
+ - **Requirements sections** → `proposed_changes[]` with type `requirement`
386
+ - **Task lists** → `proposed_changes[]` with type `task`
387
+ - **Features** → `proposed_changes[]` with type `feature`
388
+ - **Goals/Objectives** → `intent.goals[]`
389
+ - **Document title** → `intent.description`
390
+
391
+ #### File Discovery Utility
392
+
393
+ Automatically finds planning documents in repositories:
394
+
395
+ ```typescript
396
+ import { findPlanningDocuments } from '@eddacraft/anvil-adapters/utils';
397
+
398
+ // Search for planning docs in current directory
399
+ const docs = await findPlanningDocuments();
400
+
401
+ // Returns sorted by confidence and recency
402
+ docs.forEach((doc) => {
403
+ console.log(`${doc.path} - ${doc.pattern} (confidence: ${doc.confidence}%)`);
404
+ });
405
+
406
+ // Example output:
407
+ // docs/prd.md - prd (high confidence)
408
+ // TODO.md - todo (medium confidence)
409
+ // docs/RFC-001.md - rfc (medium confidence)
410
+ ```
411
+
412
+ **Next Steps**:
413
+
414
+ - ✅ Generic adapter complete with full test coverage
415
+ - ✅ File discovery utility implemented
416
+ - ✅ Provides broad compatibility for any markdown planning document
417
+
418
+ ## Development
419
+
420
+ ### Running Tests
421
+
422
+ ```bash
423
+ pnpm test # Run all tests (232 tests)
424
+ pnpm test:watch # Watch mode
425
+ pnpm test:coverage # Run with coverage report
426
+ ```
427
+
428
+ **Current Test Status** (as of November 2025):
429
+
430
+ - **Total: 232 tests** ✅ All passing
431
+ - SpecKit: 114 tests (45 format adapter + 69 parsers)
432
+ - BMAD: 86 tests (exceeds 50+ target)
433
+ - Generic: 32 tests
434
+ - **Coverage**: >95% across all adapters
435
+
436
+ ### Type Checking
437
+
438
+ ```bash
439
+ pnpm typecheck
440
+ ```
441
+
442
+ ### Building
443
+
444
+ ```bash
445
+ npx nx build adapters
446
+ ```
447
+
448
+ ### Project Structure
449
+
450
+ ```
451
+ packages/adapters/
452
+ ├── src/
453
+ │ ├── base/ # Framework core (586 LOC)
454
+ │ │ ├── types.ts # FormatAdapter interface, base classes
455
+ │ │ ├── registry.ts # Adapter registry with detection
456
+ │ │ ├── utils.ts # Helper utilities
457
+ │ │ ├── testing.ts # Testing utilities
458
+ │ │ └── __tests__/
459
+ │ │ └── registry.test.ts # 22 tests (100% passing)
460
+ │ ├── common/ # Legacy adapter types (deprecated)
461
+ │ │ ├── types.ts # Old SpecToolAdapter interface
462
+ │ │ ├── registry.ts # Old registry implementation
463
+ │ │ └── index.ts
464
+ │ ├── speckit/ # SpecKit adapter (2,469 LOC)
465
+ │ │ ├── index.ts # Exports
466
+ │ │ ├── parser.ts # Core markdown parser (330 LOC)
467
+ │ │ ├── import.ts # V1 import adapter (284 LOC)
468
+ │ │ ├── import-v2.ts # V2 official format (424 LOC)
469
+ │ │ ├── export.ts # Export adapter (462 LOC)
470
+ │ │ └── parsers/ # Specialized parsers (966 LOC)
471
+ │ │ ├── spec-parser.ts # Spec.md parser (378 LOC)
472
+ │ │ ├── plan-parser.ts # Plan.md parser (342 LOC)
473
+ │ │ └── tasks-parser.ts # Tasks.md parser (246 LOC)
474
+ │ ├── __tests__/ # Test suite
475
+ │ │ ├── fixtures/ # Test fixtures
476
+ │ │ │ ├── speckit/ # Sample SpecKit documents
477
+ │ │ │ ├── speckit-official/ # Official spec-kit examples
478
+ │ │ │ └── aps/ # APS test fixtures
479
+ │ │ ├── speckit-import.test.ts # V1 import tests
480
+ │ │ ├── speckit-import-v2.test.ts # V2 import tests
481
+ │ │ ├── speckit-export.test.ts # Export tests
482
+ │ │ ├── speckit-parser.test.ts # Core parser tests
483
+ │ │ └── speckit-spec-parser.test.ts # Spec parser tests
484
+ │ └── index.ts # Main package exports
485
+ └── README.md # This file
486
+ ```
487
+
488
+ ## Design Principles
489
+
490
+ 1. **Format Agnostic**: Users work with their preferred format
491
+ 2. **APS Internal**: Validation and execution always use APS
492
+ 3. **Round-trip Fidelity**: Parse → Serialize → Parse preserves intent
493
+ 4. **Content Detection**: Auto-detect format from content
494
+ 5. **Extensible**: Easy to add new format adapters
495
+ 6. **Type Safe**: Full TypeScript support
496
+
497
+ ## Licence
498
+
499
+ Copyright (c) 2026 EddaCraft. All rights reserved. See [LICENSE](../../LICENSE)
500
+ for details.
@@ -0,0 +1,102 @@
1
+ /**
2
+ * APS Markdown Format Adapter
3
+ *
4
+ * FormatAdapter implementation for Anvil Plan Spec (APS) markdown format.
5
+ * Handles both leaf specs (.aps.md with Tasks section) and index files
6
+ * (.aps.md with Modules section).
7
+ */
8
+ import { type APSPlan, type ValidationResult } from '@eddacraft/anvil-core';
9
+ import { BaseFormatAdapter, type AdapterMetadata, type DetectionResult, type ParseResult, type SerializeResult, type ParseContext, type AdapterOptions } from '../base/types.js';
10
+ /**
11
+ * APS Markdown FormatAdapter implementation
12
+ *
13
+ * Converts between APS markdown documents and APS plans.
14
+ */
15
+ export declare class APSMarkdownAdapter extends BaseFormatAdapter {
16
+ readonly metadata: AdapterMetadata;
17
+ /**
18
+ * Detect if content is APS markdown format
19
+ *
20
+ * Uses confidence scoring based on multiple indicators:
21
+ * - Tasks section with SCOPE-NNN headings (30 points)
22
+ * - **Intent:** field in tasks (20 points)
23
+ * - Modules section (25 points)
24
+ * - .aps.md path links (20 points)
25
+ * - **Scope:** field (10 points)
26
+ * - **Confidence:** field (10 points)
27
+ * - **Owner:** field (5 points)
28
+ * - **Priority:** field (5 points)
29
+ *
30
+ * @param content - Document content to analyze
31
+ * @returns Detection result with confidence score
32
+ */
33
+ detect(content: string): DetectionResult;
34
+ /**
35
+ * Parse APS markdown content to APS plan
36
+ *
37
+ * Converts an APS markdown document (leaf spec) to an APSPlan execution schema.
38
+ * Each task in the document becomes a proposed change in the plan.
39
+ *
40
+ * @param content - APS markdown content
41
+ * @param context - Parse context for provenance
42
+ * @param _options - Adapter options
43
+ * @returns Parse result with APS plan
44
+ */
45
+ parse(content: string, context?: ParseContext, _options?: AdapterOptions): Promise<ParseResult>;
46
+ /**
47
+ * Convert a parsed document to an APSPlan
48
+ */
49
+ private convertToAPSPlan;
50
+ /**
51
+ * Convert a task to a change object
52
+ */
53
+ private taskToChange;
54
+ /**
55
+ * Infer the change type from task intent
56
+ */
57
+ private inferChangeType;
58
+ /**
59
+ * Serialize APS plan to APS markdown format
60
+ *
61
+ * NOTE: Not yet implemented - returns NOT_IMPLEMENTED error.
62
+ *
63
+ * @param _plan - APS plan to serialize
64
+ * @param _options - Adapter options
65
+ * @returns Serialize result with APS markdown
66
+ */
67
+ serialize(_plan: APSPlan, _options?: AdapterOptions): Promise<SerializeResult>;
68
+ /**
69
+ * Validate APS markdown content
70
+ *
71
+ * NOTE: Not yet implemented - returns NOT_IMPLEMENTED error.
72
+ *
73
+ * @param _content - APS markdown content to validate
74
+ * @param _options - Validation options
75
+ * @returns Validation result
76
+ */
77
+ validate(_content: string, _options?: AdapterOptions): Promise<ValidationResult>;
78
+ /**
79
+ * Override canImport to handle the compound extension .aps.md
80
+ */
81
+ canImport(format: string): boolean;
82
+ /**
83
+ * Analyze content for APS markdown indicators
84
+ */
85
+ private analyzeContent;
86
+ /**
87
+ * Calculate confidence score based on indicators
88
+ */
89
+ private calculateConfidence;
90
+ /**
91
+ * Build detection reason message
92
+ */
93
+ private buildDetectionReason;
94
+ }
95
+ /**
96
+ * Create a new APS markdown adapter instance
97
+ *
98
+ * @param options - Adapter options
99
+ * @returns APS markdown adapter instance
100
+ */
101
+ export declare function createAPSMarkdownAdapter(options?: AdapterOptions): APSMarkdownAdapter;
102
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/aps-markdown/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,gBAAgB,EAKtB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,iBAAiB,EACjB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AAmC1B;;;;GAIG;AACH,qBAAa,kBAAmB,SAAQ,iBAAiB;IACvD,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAOhC;IAEF;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe;IASxC;;;;;;;;;;OAUG;IACG,KAAK,CACT,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,YAAY,EACtB,QAAQ,CAAC,EAAE,cAAc,GACxB,OAAO,CAAC,WAAW,CAAC;IAevB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAkCxB;;OAEG;IACH,OAAO,CAAC,YAAY;IAsBpB;;OAEG;IACH,OAAO,CAAC,eAAe;IAmCvB;;;;;;;;OAQG;IACG,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IASpF;;;;;;;;OAQG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAetF;;OAEG;IACM,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAS3C;;OAEG;IACH,OAAO,CAAC,cAAc;IA0DtB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAyD3B;;OAEG;IACH,OAAO,CAAC,oBAAoB;CAoC7B;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,kBAAkB,CAErF"}