@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.
- package/AGENTS.md +180 -0
- package/BMAD_ADAPTER_SPEC.md +489 -0
- package/LICENSE +14 -0
- package/README.md +500 -0
- package/dist/aps-markdown/adapter.d.ts +102 -0
- package/dist/aps-markdown/adapter.d.ts.map +1 -0
- package/dist/aps-markdown/adapter.js +351 -0
- package/dist/aps-markdown/index.d.ts +8 -0
- package/dist/aps-markdown/index.d.ts.map +1 -0
- package/dist/aps-markdown/index.js +7 -0
- package/dist/base/file-discovery.d.ts +63 -0
- package/dist/base/file-discovery.d.ts.map +1 -0
- package/dist/base/file-discovery.js +246 -0
- package/dist/base/index.d.ts +10 -0
- package/dist/base/index.d.ts.map +1 -0
- package/dist/base/index.js +9 -0
- package/dist/base/registry.d.ts +155 -0
- package/dist/base/registry.d.ts.map +1 -0
- package/dist/base/registry.js +227 -0
- package/dist/base/testing.d.ts +102 -0
- package/dist/base/testing.d.ts.map +1 -0
- package/dist/base/testing.js +221 -0
- package/dist/base/types.d.ts +255 -0
- package/dist/base/types.d.ts.map +1 -0
- package/dist/base/types.js +78 -0
- package/dist/base/utils.d.ts +127 -0
- package/dist/base/utils.d.ts.map +1 -0
- package/dist/base/utils.js +254 -0
- package/dist/bmad/format-adapter.d.ts +76 -0
- package/dist/bmad/format-adapter.d.ts.map +1 -0
- package/dist/bmad/format-adapter.js +186 -0
- package/dist/bmad/index.d.ts +12 -0
- package/dist/bmad/index.d.ts.map +1 -0
- package/dist/bmad/index.js +10 -0
- package/dist/bmad/parser.d.ts +12 -0
- package/dist/bmad/parser.d.ts.map +1 -0
- package/dist/bmad/parser.js +181 -0
- package/dist/bmad/serializer.d.ts +16 -0
- package/dist/bmad/serializer.d.ts.map +1 -0
- package/dist/bmad/serializer.js +170 -0
- package/dist/bmad/types.d.ts +127 -0
- package/dist/bmad/types.d.ts.map +1 -0
- package/dist/bmad/types.js +47 -0
- package/dist/bmad/utils.d.ts +120 -0
- package/dist/bmad/utils.d.ts.map +1 -0
- package/dist/bmad/utils.js +480 -0
- package/dist/common/index.d.ts +3 -0
- package/dist/common/index.d.ts.map +1 -0
- package/dist/common/index.js +2 -0
- package/dist/common/registry.d.ts +18 -0
- package/dist/common/registry.d.ts.map +1 -0
- package/dist/common/registry.js +58 -0
- package/dist/common/types.d.ts +68 -0
- package/dist/common/types.d.ts.map +1 -0
- package/dist/common/types.js +12 -0
- package/dist/generic/format-adapter.d.ts +64 -0
- package/dist/generic/format-adapter.d.ts.map +1 -0
- package/dist/generic/format-adapter.js +159 -0
- package/dist/generic/index.d.ts +10 -0
- package/dist/generic/index.d.ts.map +1 -0
- package/dist/generic/index.js +9 -0
- package/dist/generic/parser.d.ts +11 -0
- package/dist/generic/parser.d.ts.map +1 -0
- package/dist/generic/parser.js +106 -0
- package/dist/generic/serializer.d.ts +11 -0
- package/dist/generic/serializer.d.ts.map +1 -0
- package/dist/generic/serializer.js +118 -0
- package/dist/generic/types.d.ts +52 -0
- package/dist/generic/types.d.ts.map +1 -0
- package/dist/generic/types.js +6 -0
- package/dist/generic/utils.d.ts +51 -0
- package/dist/generic/utils.d.ts.map +1 -0
- package/dist/generic/utils.js +232 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/speckit/export.d.ts +22 -0
- package/dist/speckit/export.d.ts.map +1 -0
- package/dist/speckit/export.js +384 -0
- package/dist/speckit/format-adapter.d.ts +104 -0
- package/dist/speckit/format-adapter.d.ts.map +1 -0
- package/dist/speckit/format-adapter.js +488 -0
- package/dist/speckit/import-v2.d.ts +33 -0
- package/dist/speckit/import-v2.d.ts.map +1 -0
- package/dist/speckit/import-v2.js +361 -0
- package/dist/speckit/import.d.ts +16 -0
- package/dist/speckit/import.d.ts.map +1 -0
- package/dist/speckit/import.js +247 -0
- package/dist/speckit/index.d.ts +5 -0
- package/dist/speckit/index.d.ts.map +1 -0
- package/dist/speckit/index.js +4 -0
- package/dist/speckit/parser.d.ts +28 -0
- package/dist/speckit/parser.d.ts.map +1 -0
- package/dist/speckit/parser.js +283 -0
- package/dist/speckit/parsers/plan-parser.d.ts +71 -0
- package/dist/speckit/parsers/plan-parser.d.ts.map +1 -0
- package/dist/speckit/parsers/plan-parser.js +216 -0
- package/dist/speckit/parsers/spec-parser.d.ts +67 -0
- package/dist/speckit/parsers/spec-parser.d.ts.map +1 -0
- package/dist/speckit/parsers/spec-parser.js +255 -0
- package/dist/speckit/parsers/tasks-parser.d.ts +57 -0
- package/dist/speckit/parsers/tasks-parser.d.ts.map +1 -0
- package/dist/speckit/parsers/tasks-parser.js +157 -0
- package/package.json +23 -0
- package/project.json +29 -0
- package/src/__tests__/adapter-edge-cases.test.ts +937 -0
- package/src/__tests__/bmad-format-adapter.test.ts +1470 -0
- package/src/__tests__/fixtures/aps/expected-output.json +83 -0
- package/src/__tests__/fixtures/bmad/invalid-malformed-yaml.md +16 -0
- package/src/__tests__/fixtures/bmad/invalid-no-requirements.md +23 -0
- package/src/__tests__/fixtures/bmad/invalid-only-yaml.md +16 -0
- package/src/__tests__/fixtures/bmad/invalid-too-short.md +3 -0
- package/src/__tests__/fixtures/bmad/invalid-wrong-format.md +40 -0
- package/src/__tests__/fixtures/bmad/valid-agent.md +27 -0
- package/src/__tests__/fixtures/bmad/valid-architecture.md +116 -0
- package/src/__tests__/fixtures/bmad/valid-complex-prd.md +161 -0
- package/src/__tests__/fixtures/bmad/valid-epic.md +73 -0
- package/src/__tests__/fixtures/bmad/valid-minimal-prd.md +19 -0
- package/src/__tests__/fixtures/bmad/valid-prd.md +107 -0
- package/src/__tests__/fixtures/bmad/valid-story.md +107 -0
- package/src/__tests__/fixtures/bmad/valid-task.md +79 -0
- package/src/__tests__/fixtures/bmad/valid-v6-prd.md +35 -0
- package/src/__tests__/fixtures/generic/plan-detailed.md +39 -0
- package/src/__tests__/fixtures/generic/prd-simple.md +27 -0
- package/src/__tests__/fixtures/generic/rfc-example.md +26 -0
- package/src/__tests__/fixtures/generic/todo-list.md +23 -0
- package/src/__tests__/fixtures/speckit/sample-plan.md +63 -0
- package/src/__tests__/fixtures/speckit/sample-spec-namespaced.md +50 -0
- package/src/__tests__/fixtures/speckit/sample-spec.md +105 -0
- package/src/__tests__/fixtures/speckit/sample-tasks.md +87 -0
- package/src/__tests__/fixtures/speckit-official/auth-feature/plan.md +272 -0
- package/src/__tests__/fixtures/speckit-official/auth-feature/spec.md +149 -0
- package/src/__tests__/fixtures/speckit-official/auth-feature/tasks.md +169 -0
- package/src/__tests__/generic-format-adapter.test.ts +398 -0
- package/src/__tests__/speckit-export.test.ts +233 -0
- package/src/__tests__/speckit-format-adapter.test.ts +832 -0
- package/src/__tests__/speckit-import-v2.test.ts +253 -0
- package/src/__tests__/speckit-import.test.ts +209 -0
- package/src/__tests__/speckit-parser.test.ts +219 -0
- package/src/__tests__/speckit-spec-parser.test.ts +120 -0
- package/src/aps-markdown/__tests__/__fixtures__/simple-leaf.aps.md +17 -0
- package/src/aps-markdown/__tests__/adapter.test.ts +393 -0
- package/src/aps-markdown/adapter.ts +455 -0
- package/src/aps-markdown/index.ts +8 -0
- package/src/base/__tests__/registry.test.ts +515 -0
- package/src/base/file-discovery.ts +305 -0
- package/src/base/index.ts +10 -0
- package/src/base/registry.ts +263 -0
- package/src/base/testing.ts +334 -0
- package/src/base/types.ts +342 -0
- package/src/base/utils.ts +306 -0
- package/src/bmad/format-adapter.ts +227 -0
- package/src/bmad/index.ts +21 -0
- package/src/bmad/parser.ts +224 -0
- package/src/bmad/serializer.ts +206 -0
- package/src/bmad/types.ts +135 -0
- package/src/bmad/utils.ts +575 -0
- package/src/common/index.ts +2 -0
- package/src/common/registry.ts +72 -0
- package/src/common/types.ts +84 -0
- package/src/generic/__tests__/serializer.test.ts +167 -0
- package/src/generic/format-adapter.ts +200 -0
- package/src/generic/index.ts +11 -0
- package/src/generic/parser.ts +129 -0
- package/src/generic/serializer.ts +134 -0
- package/src/generic/types.ts +53 -0
- package/src/generic/utils.ts +270 -0
- package/src/index.ts +48 -0
- package/src/speckit/export.ts +489 -0
- package/src/speckit/format-adapter.ts +595 -0
- package/src/speckit/import-v2.ts +445 -0
- package/src/speckit/import.ts +305 -0
- package/src/speckit/index.ts +4 -0
- package/src/speckit/parser.ts +351 -0
- package/src/speckit/parsers/plan-parser.ts +342 -0
- package/src/speckit/parsers/spec-parser.ts +379 -0
- package/src/speckit/parsers/tasks-parser.ts +246 -0
- package/tsconfig.json +26 -0
- package/tsconfig.lib.json +21 -0
- package/tsconfig.lib.tsbuildinfo +1 -0
- package/tsconfig.spec.json +9 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/vitest.config.ts +14 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BMAD Parser
|
|
3
|
+
*
|
|
4
|
+
* Parses BMAD format documents (PRD, Architecture, Epics, Stories) into APS plans.
|
|
5
|
+
*/
|
|
6
|
+
import { validateRelativePath } from '@eddacraft/anvil-core';
|
|
7
|
+
import { RequirementType } from './types.js';
|
|
8
|
+
import { extractFrontMatter, extractRequirements, extractUserStories, extractChangeLog, identifyDocumentType, extractTitle, extractIntent, } from './utils.js';
|
|
9
|
+
import { createError, createWarning, generateDeterministicPlanId } from '../base/utils.js';
|
|
10
|
+
/**
|
|
11
|
+
* Parse BMAD document into internal structure
|
|
12
|
+
*
|
|
13
|
+
* @param content - BMAD markdown content
|
|
14
|
+
* @returns Parsed document
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Validate and sanitize a file path to prevent path traversal attacks.
|
|
18
|
+
* Falls back to stripping special characters if validation fails.
|
|
19
|
+
*/
|
|
20
|
+
function safePath(raw) {
|
|
21
|
+
try {
|
|
22
|
+
return validateRelativePath(raw);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return raw.replace(/[^a-z0-9/._-]/gi, '').replace(/\.{2,}/g, '');
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** Maximum input size for BMAD parsing (2MB) */
|
|
29
|
+
const MAX_INPUT_SIZE = 2 * 1024 * 1024;
|
|
30
|
+
export function parseBMADDocument(content) {
|
|
31
|
+
if (content.length > MAX_INPUT_SIZE) {
|
|
32
|
+
throw new Error(`Input exceeds maximum size of ${MAX_INPUT_SIZE} bytes`);
|
|
33
|
+
}
|
|
34
|
+
const frontMatter = extractFrontMatter(content);
|
|
35
|
+
const docType = identifyDocumentType(content, frontMatter);
|
|
36
|
+
const requirements = extractRequirements(content);
|
|
37
|
+
const userStories = extractUserStories(content);
|
|
38
|
+
const changeLog = extractChangeLog(content);
|
|
39
|
+
const title = extractTitle(content);
|
|
40
|
+
const intent = extractIntent(content, docType);
|
|
41
|
+
return {
|
|
42
|
+
type: docType,
|
|
43
|
+
frontMatter: frontMatter || undefined,
|
|
44
|
+
title: title || undefined,
|
|
45
|
+
intent,
|
|
46
|
+
requirements,
|
|
47
|
+
userStories,
|
|
48
|
+
changeLog,
|
|
49
|
+
sections: new Map(),
|
|
50
|
+
raw: content,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Convert BMAD requirement to APS change
|
|
55
|
+
*
|
|
56
|
+
* @param requirement - BMAD requirement
|
|
57
|
+
* @returns APS change
|
|
58
|
+
*/
|
|
59
|
+
function requirementToChange(requirement) {
|
|
60
|
+
// Map requirement type to change type
|
|
61
|
+
switch (requirement.type) {
|
|
62
|
+
case RequirementType.FUNCTIONAL:
|
|
63
|
+
// FR typically means creating or updating files
|
|
64
|
+
return {
|
|
65
|
+
type: 'file_create',
|
|
66
|
+
path: safePath(`features/${requirement.id.toLowerCase()}.ts`),
|
|
67
|
+
description: `${requirement.id}: ${requirement.description}`,
|
|
68
|
+
};
|
|
69
|
+
case RequirementType.NON_FUNCTIONAL:
|
|
70
|
+
// NFR typically means configuration or validation
|
|
71
|
+
return {
|
|
72
|
+
type: 'config_update',
|
|
73
|
+
path: 'config/requirements.json',
|
|
74
|
+
description: `${requirement.id}: ${requirement.description}`,
|
|
75
|
+
};
|
|
76
|
+
case RequirementType.USER_STORY:
|
|
77
|
+
// US typically means creating feature files
|
|
78
|
+
return {
|
|
79
|
+
type: 'file_create',
|
|
80
|
+
path: safePath(`features/stories/${requirement.id.toLowerCase()}.ts`),
|
|
81
|
+
description: `${requirement.id}: ${requirement.description}`,
|
|
82
|
+
};
|
|
83
|
+
default:
|
|
84
|
+
return {
|
|
85
|
+
type: 'file_create',
|
|
86
|
+
path: safePath(`requirements/${requirement.id.toLowerCase()}.md`),
|
|
87
|
+
description: requirement.description,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Convert BMAD user story to APS change
|
|
93
|
+
*
|
|
94
|
+
* @param story - BMAD user story
|
|
95
|
+
* @returns APS change
|
|
96
|
+
*/
|
|
97
|
+
function userStoryToChange(story) {
|
|
98
|
+
let description = `${story.id}: ${story.title}`;
|
|
99
|
+
if (story.userType && story.action && story.benefit) {
|
|
100
|
+
description += ` (As a ${story.userType}, I want ${story.action}, so that ${story.benefit})`;
|
|
101
|
+
}
|
|
102
|
+
if (story.acceptanceCriteria && story.acceptanceCriteria.length > 0) {
|
|
103
|
+
description += ` - Acceptance criteria: ${story.acceptanceCriteria.join('; ')}`;
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
type: 'file_create',
|
|
107
|
+
path: safePath(`features/stories/${story.id.toLowerCase()}.ts`),
|
|
108
|
+
description,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
export function bmadToAPS(document, context, originalContent) {
|
|
112
|
+
const planId = context?.planId ??
|
|
113
|
+
(originalContent
|
|
114
|
+
? generateDeterministicPlanId(originalContent)
|
|
115
|
+
: `aps-${Date.now().toString(16).substring(0, 8)}`);
|
|
116
|
+
// Convert requirements and stories to changes
|
|
117
|
+
const changes = [];
|
|
118
|
+
const errors = [];
|
|
119
|
+
const warnings = [];
|
|
120
|
+
// Add requirements as changes
|
|
121
|
+
for (const requirement of document.requirements) {
|
|
122
|
+
try {
|
|
123
|
+
const change = requirementToChange(requirement);
|
|
124
|
+
changes.push(change);
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
errors.push(createError('REQUIREMENT_CONVERSION_ERROR', `Failed to convert requirement ${requirement.id}`, {
|
|
128
|
+
details: error,
|
|
129
|
+
}));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// Add user stories as changes
|
|
133
|
+
for (const story of document.userStories) {
|
|
134
|
+
try {
|
|
135
|
+
const change = userStoryToChange(story);
|
|
136
|
+
changes.push(change);
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
errors.push(createError('STORY_CONVERSION_ERROR', `Failed to convert story ${story.id}`, {
|
|
140
|
+
details: error,
|
|
141
|
+
}));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// If no changes found, add warning
|
|
145
|
+
if (changes.length === 0) {
|
|
146
|
+
warnings.push(createWarning('NO_CHANGES', 'No requirements or user stories found in document', {
|
|
147
|
+
details: { type: document.type },
|
|
148
|
+
}));
|
|
149
|
+
}
|
|
150
|
+
// Extract provenance from front-matter or context
|
|
151
|
+
const timestamp = document.frontMatter?.date || context?.timestamp || new Date().toISOString();
|
|
152
|
+
const author = document.frontMatter?.author || context?.author || 'unknown';
|
|
153
|
+
const version = document.frontMatter?.version || '1.0.0';
|
|
154
|
+
// Build APS plan
|
|
155
|
+
const plan = {
|
|
156
|
+
id: planId,
|
|
157
|
+
schema_version: '0.1.0',
|
|
158
|
+
intent: document.intent || 'BMAD document conversion',
|
|
159
|
+
proposed_changes: changes,
|
|
160
|
+
provenance: {
|
|
161
|
+
timestamp,
|
|
162
|
+
author,
|
|
163
|
+
source: 'cli',
|
|
164
|
+
version,
|
|
165
|
+
repository: context?.repositoryPath,
|
|
166
|
+
branch: context?.branch,
|
|
167
|
+
commit: context?.commit,
|
|
168
|
+
},
|
|
169
|
+
validations: {
|
|
170
|
+
required_checks: ['lint', 'test', 'coverage'],
|
|
171
|
+
skip_checks: [],
|
|
172
|
+
},
|
|
173
|
+
// Note: hash will be generated by the adapter after plan creation
|
|
174
|
+
hash: '0000000000000000000000000000000000000000000000000000000000000000',
|
|
175
|
+
};
|
|
176
|
+
return plan;
|
|
177
|
+
}
|
|
178
|
+
export function parseBMAD(content, context) {
|
|
179
|
+
const document = parseBMADDocument(content);
|
|
180
|
+
return bmadToAPS(document, context, content);
|
|
181
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BMAD Serializer
|
|
3
|
+
*
|
|
4
|
+
* Serializes APS plans to BMAD format documents.
|
|
5
|
+
*/
|
|
6
|
+
import type { APSPlan } from '@eddacraft/anvil-core';
|
|
7
|
+
/**
|
|
8
|
+
* Serialize APS plan to BMAD format
|
|
9
|
+
*
|
|
10
|
+
* Generates a BMAD PRD document from an APS plan.
|
|
11
|
+
*
|
|
12
|
+
* @param plan - APS plan to serialize
|
|
13
|
+
* @returns BMAD markdown content
|
|
14
|
+
*/
|
|
15
|
+
export declare function serializeToBMAD(plan: APSPlan): string;
|
|
16
|
+
//# sourceMappingURL=serializer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../../src/bmad/serializer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAU,MAAM,uBAAuB,CAAC;AAE7D;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CA6LrD"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BMAD Serializer
|
|
3
|
+
*
|
|
4
|
+
* Serializes APS plans to BMAD format documents.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Serialize APS plan to BMAD format
|
|
8
|
+
*
|
|
9
|
+
* Generates a BMAD PRD document from an APS plan.
|
|
10
|
+
*
|
|
11
|
+
* @param plan - APS plan to serialize
|
|
12
|
+
* @returns BMAD markdown content
|
|
13
|
+
*/
|
|
14
|
+
export function serializeToBMAD(plan) {
|
|
15
|
+
const lines = [];
|
|
16
|
+
// Generate YAML front-matter
|
|
17
|
+
lines.push('---');
|
|
18
|
+
lines.push('name: "Product Requirements Document"');
|
|
19
|
+
lines.push(`version: "${plan.provenance.version || '1.0.0'}"`);
|
|
20
|
+
lines.push(`date: "${plan.provenance.timestamp}"`);
|
|
21
|
+
lines.push(`author: "${plan.provenance.author || 'unknown'}"`);
|
|
22
|
+
lines.push('description: "Generated from Anvil Plan Specification"');
|
|
23
|
+
lines.push('---');
|
|
24
|
+
lines.push('');
|
|
25
|
+
// Generate document header
|
|
26
|
+
const projectName = plan.metadata?.['projectName'] || 'Project';
|
|
27
|
+
lines.push(`# ${projectName} - Product Requirements Document`);
|
|
28
|
+
lines.push('');
|
|
29
|
+
lines.push(`**Author:** ${plan.provenance.author || 'unknown'}`);
|
|
30
|
+
lines.push(`**Date:** ${plan.provenance.timestamp}`);
|
|
31
|
+
lines.push(`**Version:** ${plan.provenance.version || '1.0.0'}`);
|
|
32
|
+
lines.push('');
|
|
33
|
+
// Generate change log
|
|
34
|
+
lines.push('## Change Log');
|
|
35
|
+
lines.push('');
|
|
36
|
+
lines.push('| Date | Version | Description | Author |');
|
|
37
|
+
lines.push('| :--- | :------ | :---------- | :----- |');
|
|
38
|
+
const date = new Date(plan.provenance.timestamp).toISOString().split('T')[0];
|
|
39
|
+
const version = plan.provenance.version || '1.0.0';
|
|
40
|
+
const author = plan.provenance.author || 'unknown';
|
|
41
|
+
lines.push(`| ${date} | ${version} | Initial version | ${author} |`);
|
|
42
|
+
lines.push('');
|
|
43
|
+
// Generate overview/intent section
|
|
44
|
+
lines.push('## Overview');
|
|
45
|
+
lines.push('');
|
|
46
|
+
lines.push(plan.intent);
|
|
47
|
+
lines.push('');
|
|
48
|
+
// Categorize changes
|
|
49
|
+
const functionalRequirements = [];
|
|
50
|
+
const nonFunctionalRequirements = [];
|
|
51
|
+
const userStories = [];
|
|
52
|
+
for (const change of plan.proposed_changes) {
|
|
53
|
+
// Categorize based on change type and path
|
|
54
|
+
if (change.path.includes('stories/') || change.description.match(/^US-\d{2}/)) {
|
|
55
|
+
userStories.push(change);
|
|
56
|
+
}
|
|
57
|
+
else if (change.type === 'config_update' ||
|
|
58
|
+
change.type === 'dependency_add' ||
|
|
59
|
+
change.type === 'dependency_update' ||
|
|
60
|
+
change.description.match(/^NFR-\d{2}/)) {
|
|
61
|
+
nonFunctionalRequirements.push(change);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
functionalRequirements.push(change);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Generate Functional Requirements section
|
|
68
|
+
if (functionalRequirements.length > 0) {
|
|
69
|
+
lines.push('## Functional Requirements');
|
|
70
|
+
lines.push('');
|
|
71
|
+
functionalRequirements.forEach((change, index) => {
|
|
72
|
+
const reqNum = String(index + 1).padStart(2, '0');
|
|
73
|
+
const reqId = `FR-${reqNum}`;
|
|
74
|
+
// Extract description (remove existing FR-XX if present)
|
|
75
|
+
let description = change.description.replace(/^FR-\d{2}:\s*/, '');
|
|
76
|
+
// Add path context if not already in description
|
|
77
|
+
if (!description.includes(change.path)) {
|
|
78
|
+
description += ` (${change.path})`;
|
|
79
|
+
}
|
|
80
|
+
lines.push(`${reqId}: ${description}`);
|
|
81
|
+
});
|
|
82
|
+
lines.push('');
|
|
83
|
+
}
|
|
84
|
+
// Generate Non-Functional Requirements section
|
|
85
|
+
if (nonFunctionalRequirements.length > 0) {
|
|
86
|
+
lines.push('## Non-Functional Requirements');
|
|
87
|
+
lines.push('');
|
|
88
|
+
nonFunctionalRequirements.forEach((change, index) => {
|
|
89
|
+
const reqNum = String(index + 1).padStart(2, '0');
|
|
90
|
+
const reqId = `NFR-${reqNum}`;
|
|
91
|
+
// Extract description
|
|
92
|
+
const description = change.description.replace(/^NFR-\d{2}:\s*/, '');
|
|
93
|
+
lines.push(`${reqId}: ${description}`);
|
|
94
|
+
});
|
|
95
|
+
lines.push('');
|
|
96
|
+
}
|
|
97
|
+
// Add validation requirements as NFRs
|
|
98
|
+
if (plan.validations.required_checks.length > 0) {
|
|
99
|
+
if (nonFunctionalRequirements.length === 0) {
|
|
100
|
+
lines.push('## Non-Functional Requirements');
|
|
101
|
+
lines.push('');
|
|
102
|
+
}
|
|
103
|
+
const startIndex = nonFunctionalRequirements.length + 1;
|
|
104
|
+
plan.validations.required_checks.forEach((check, index) => {
|
|
105
|
+
const reqNum = String(startIndex + index).padStart(2, '0');
|
|
106
|
+
const reqId = `NFR-${reqNum}`;
|
|
107
|
+
lines.push(`${reqId}: Must pass ${check} validation`);
|
|
108
|
+
});
|
|
109
|
+
lines.push('');
|
|
110
|
+
}
|
|
111
|
+
// Generate User Stories section
|
|
112
|
+
if (userStories.length > 0) {
|
|
113
|
+
lines.push('## User Stories');
|
|
114
|
+
lines.push('');
|
|
115
|
+
userStories.forEach((story, index) => {
|
|
116
|
+
const storyNum = String(index + 1).padStart(2, '0');
|
|
117
|
+
const storyId = `US-${storyNum}`;
|
|
118
|
+
// Extract story title
|
|
119
|
+
let title = story.description.replace(/^US-\d{2}:\s*/, '');
|
|
120
|
+
// Check if description contains "As a... I want... so that..." pattern
|
|
121
|
+
const storyMatch = title.match(/\(As a (.+?), I want (.+?), so that (.+?)\)/);
|
|
122
|
+
if (storyMatch) {
|
|
123
|
+
const [, userType, action, benefit] = storyMatch;
|
|
124
|
+
title = title.replace(/\(As a .+?\)/, '').trim();
|
|
125
|
+
lines.push(`### ${storyId}: ${title}`);
|
|
126
|
+
lines.push('');
|
|
127
|
+
lines.push(`As a ${userType},`);
|
|
128
|
+
lines.push(`I want ${action},`);
|
|
129
|
+
lines.push(`so that ${benefit}.`);
|
|
130
|
+
lines.push('');
|
|
131
|
+
// Extract acceptance criteria if present
|
|
132
|
+
const criteriaMatch = title.match(/- Acceptance criteria: (.+)$/);
|
|
133
|
+
if (criteriaMatch) {
|
|
134
|
+
const criteria = criteriaMatch[1].split(';').map((c) => c.trim());
|
|
135
|
+
lines.push('**Acceptance Criteria:**');
|
|
136
|
+
lines.push('');
|
|
137
|
+
criteria.forEach((criterion, i) => {
|
|
138
|
+
lines.push(`${i + 1}. ${criterion}`);
|
|
139
|
+
});
|
|
140
|
+
lines.push('');
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
lines.push(`### ${storyId}: ${title}`);
|
|
145
|
+
lines.push('');
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
// Add repository information if available
|
|
150
|
+
if (plan.provenance.repository || plan.provenance.branch) {
|
|
151
|
+
lines.push('## Repository Information');
|
|
152
|
+
lines.push('');
|
|
153
|
+
if (plan.provenance.repository) {
|
|
154
|
+
lines.push(`**Repository:** ${plan.provenance.repository}`);
|
|
155
|
+
}
|
|
156
|
+
if (plan.provenance.branch) {
|
|
157
|
+
lines.push(`**Branch:** ${plan.provenance.branch}`);
|
|
158
|
+
}
|
|
159
|
+
if (plan.provenance.commit) {
|
|
160
|
+
lines.push(`**Commit:** ${plan.provenance.commit}`);
|
|
161
|
+
}
|
|
162
|
+
lines.push('');
|
|
163
|
+
}
|
|
164
|
+
// Add footer
|
|
165
|
+
lines.push('---');
|
|
166
|
+
lines.push('');
|
|
167
|
+
lines.push('*Generated by Anvil - https://github.com/EddaCraft/anvil-001*');
|
|
168
|
+
lines.push('');
|
|
169
|
+
return lines.join('\n');
|
|
170
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BMAD Format Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for BMAD (Breakthrough Method for Agile AI-Driven Development) format.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* BMAD v6 folder structure constants
|
|
8
|
+
*
|
|
9
|
+
* v6 changed `.bmad` → `_bmad` and `_cfg` → `_config`.
|
|
10
|
+
* We support both legacy and new paths for backward compatibility.
|
|
11
|
+
*/
|
|
12
|
+
export declare const BMAD_FOLDERS: {
|
|
13
|
+
/** New v6 project folder */
|
|
14
|
+
readonly PROJECT: "_bmad";
|
|
15
|
+
/** Legacy project folder */
|
|
16
|
+
readonly PROJECT_LEGACY: ".bmad";
|
|
17
|
+
/** New v6 config folder */
|
|
18
|
+
readonly CONFIG: "_config";
|
|
19
|
+
/** Legacy config folder */
|
|
20
|
+
readonly CONFIG_LEGACY: "_cfg";
|
|
21
|
+
/** Agent memory folder (v6) */
|
|
22
|
+
readonly MEMORY: "_memory";
|
|
23
|
+
/** Module config file (v6) */
|
|
24
|
+
readonly MODULE_CONFIG: "module.yaml";
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* YAML front-matter metadata
|
|
28
|
+
*/
|
|
29
|
+
export interface BMADFrontMatter {
|
|
30
|
+
name?: string;
|
|
31
|
+
version?: string;
|
|
32
|
+
description?: string;
|
|
33
|
+
output_file?: string;
|
|
34
|
+
variables?: Record<string, string>;
|
|
35
|
+
template?: string;
|
|
36
|
+
date?: string;
|
|
37
|
+
author?: string;
|
|
38
|
+
/** v6: Whether the agent document has a sidecar config */
|
|
39
|
+
hasSidecar?: boolean;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* BMAD document types
|
|
43
|
+
*/
|
|
44
|
+
export declare enum BMADDocumentType {
|
|
45
|
+
PRD = "prd",
|
|
46
|
+
ARCHITECTURE = "architecture",
|
|
47
|
+
EPIC = "epic",
|
|
48
|
+
STORY = "story",
|
|
49
|
+
/** v6: Agent persona/configuration document */
|
|
50
|
+
AGENT = "agent",
|
|
51
|
+
UNKNOWN = "unknown"
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Requirement types
|
|
55
|
+
*/
|
|
56
|
+
export declare enum RequirementType {
|
|
57
|
+
FUNCTIONAL = "FR",
|
|
58
|
+
NON_FUNCTIONAL = "NFR",
|
|
59
|
+
USER_STORY = "US"
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Parsed requirement
|
|
63
|
+
*/
|
|
64
|
+
export interface BMADRequirement {
|
|
65
|
+
type: RequirementType;
|
|
66
|
+
id: string;
|
|
67
|
+
number: number;
|
|
68
|
+
description: string;
|
|
69
|
+
line?: number;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* User story structure
|
|
73
|
+
*/
|
|
74
|
+
export interface BMADUserStory {
|
|
75
|
+
id: string;
|
|
76
|
+
title: string;
|
|
77
|
+
userType?: string;
|
|
78
|
+
action?: string;
|
|
79
|
+
benefit?: string;
|
|
80
|
+
acceptanceCriteria?: string[];
|
|
81
|
+
line?: number;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Change log entry
|
|
85
|
+
*/
|
|
86
|
+
export interface BMADChangeLogEntry {
|
|
87
|
+
date: string;
|
|
88
|
+
version: string;
|
|
89
|
+
description: string;
|
|
90
|
+
author: string;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Parsed BMAD document
|
|
94
|
+
*/
|
|
95
|
+
export interface BMADDocument {
|
|
96
|
+
type: BMADDocumentType;
|
|
97
|
+
frontMatter?: BMADFrontMatter;
|
|
98
|
+
title?: string;
|
|
99
|
+
intent?: string;
|
|
100
|
+
requirements: BMADRequirement[];
|
|
101
|
+
userStories: BMADUserStory[];
|
|
102
|
+
changeLog: BMADChangeLogEntry[];
|
|
103
|
+
sections: Map<string, string>;
|
|
104
|
+
raw: string;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Detection indicators for confidence scoring
|
|
108
|
+
*/
|
|
109
|
+
export interface DetectionIndicators {
|
|
110
|
+
hasYamlFrontMatter: boolean;
|
|
111
|
+
hasFunctionalRequirements: boolean;
|
|
112
|
+
hasNonFunctionalRequirements: boolean;
|
|
113
|
+
hasUserStories: boolean;
|
|
114
|
+
hasUserStoryFormat: boolean;
|
|
115
|
+
hasChangeLogTable: boolean;
|
|
116
|
+
hasDocumentTitle: boolean;
|
|
117
|
+
requirementCount: number;
|
|
118
|
+
/** v6: Path is inside a BMAD project folder */
|
|
119
|
+
hasBmadFolderPath: boolean;
|
|
120
|
+
/** v6: Path is inside a BMAD config folder */
|
|
121
|
+
hasBmadConfigPath: boolean;
|
|
122
|
+
/** v6: Document has hasSidecar field */
|
|
123
|
+
hasHasSidecar: boolean;
|
|
124
|
+
/** v6: Document uses hyphenated variable syntax */
|
|
125
|
+
hasHyphenatedVariables: boolean;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/bmad/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BMAD Format Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for BMAD (Breakthrough Method for Agile AI-Driven Development) format.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* BMAD v6 folder structure constants
|
|
8
|
+
*
|
|
9
|
+
* v6 changed `.bmad` → `_bmad` and `_cfg` → `_config`.
|
|
10
|
+
* We support both legacy and new paths for backward compatibility.
|
|
11
|
+
*/
|
|
12
|
+
export const BMAD_FOLDERS = {
|
|
13
|
+
/** New v6 project folder */
|
|
14
|
+
PROJECT: '_bmad',
|
|
15
|
+
/** Legacy project folder */
|
|
16
|
+
PROJECT_LEGACY: '.bmad',
|
|
17
|
+
/** New v6 config folder */
|
|
18
|
+
CONFIG: '_config',
|
|
19
|
+
/** Legacy config folder */
|
|
20
|
+
CONFIG_LEGACY: '_cfg',
|
|
21
|
+
/** Agent memory folder (v6) */
|
|
22
|
+
MEMORY: '_memory',
|
|
23
|
+
/** Module config file (v6) */
|
|
24
|
+
MODULE_CONFIG: 'module.yaml',
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* BMAD document types
|
|
28
|
+
*/
|
|
29
|
+
export var BMADDocumentType;
|
|
30
|
+
(function (BMADDocumentType) {
|
|
31
|
+
BMADDocumentType["PRD"] = "prd";
|
|
32
|
+
BMADDocumentType["ARCHITECTURE"] = "architecture";
|
|
33
|
+
BMADDocumentType["EPIC"] = "epic";
|
|
34
|
+
BMADDocumentType["STORY"] = "story";
|
|
35
|
+
/** v6: Agent persona/configuration document */
|
|
36
|
+
BMADDocumentType["AGENT"] = "agent";
|
|
37
|
+
BMADDocumentType["UNKNOWN"] = "unknown";
|
|
38
|
+
})(BMADDocumentType || (BMADDocumentType = {}));
|
|
39
|
+
/**
|
|
40
|
+
* Requirement types
|
|
41
|
+
*/
|
|
42
|
+
export var RequirementType;
|
|
43
|
+
(function (RequirementType) {
|
|
44
|
+
RequirementType["FUNCTIONAL"] = "FR";
|
|
45
|
+
RequirementType["NON_FUNCTIONAL"] = "NFR";
|
|
46
|
+
RequirementType["USER_STORY"] = "US";
|
|
47
|
+
})(RequirementType || (RequirementType = {}));
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BMAD Adapter Utilities
|
|
3
|
+
*
|
|
4
|
+
* Helper functions for BMAD format parsing and serialization.
|
|
5
|
+
*/
|
|
6
|
+
import { BMADFrontMatter, BMADRequirement, BMADUserStory, BMADChangeLogEntry, BMADDocumentType, DetectionIndicators } from './types.js';
|
|
7
|
+
import type { PathDetectionHint } from '../base/types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Analyze a file path for BMAD folder structure indicators
|
|
10
|
+
*
|
|
11
|
+
* Detects both v6 (`_bmad`, `_config`) and legacy (`.bmad`, `_cfg`) paths.
|
|
12
|
+
*
|
|
13
|
+
* @param hint - Path detection hint with file path and directory info
|
|
14
|
+
* @returns Object indicating which BMAD path patterns were found
|
|
15
|
+
*/
|
|
16
|
+
export declare function analyzePath(hint: PathDetectionHint): {
|
|
17
|
+
isBmadFolder: boolean;
|
|
18
|
+
isConfigFolder: boolean;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Expand BMAD template variables in content
|
|
22
|
+
*
|
|
23
|
+
* Supports both legacy underscore syntax `{project_root}` and
|
|
24
|
+
* v6 hyphenated syntax `{project-root}`.
|
|
25
|
+
*
|
|
26
|
+
* @param content - Content with variable placeholders
|
|
27
|
+
* @param variables - Variable values to substitute
|
|
28
|
+
* @returns Content with variables expanded
|
|
29
|
+
*/
|
|
30
|
+
export declare function expandVariables(content: string, variables: Record<string, string>): string;
|
|
31
|
+
/**
|
|
32
|
+
* Check if content contains hyphenated variable syntax (v6)
|
|
33
|
+
*
|
|
34
|
+
* @param content - Content to check
|
|
35
|
+
* @returns True if hyphenated variables are found
|
|
36
|
+
*/
|
|
37
|
+
export declare function hasHyphenatedVariables(content: string): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Parse a YAML boolean value
|
|
40
|
+
*
|
|
41
|
+
* Handles YAML 1.1 boolean forms: true/false, yes/no, on/off.
|
|
42
|
+
*
|
|
43
|
+
* @param value - String value from YAML
|
|
44
|
+
* @returns Boolean or undefined if not a boolean value
|
|
45
|
+
*/
|
|
46
|
+
export declare function parseYamlBoolean(value: string): boolean | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Extract YAML front-matter from markdown content
|
|
49
|
+
*
|
|
50
|
+
* @param content - Markdown content
|
|
51
|
+
* @returns Parsed front-matter or null
|
|
52
|
+
*/
|
|
53
|
+
export declare function extractFrontMatter(content: string): BMADFrontMatter | null;
|
|
54
|
+
/**
|
|
55
|
+
* Extract requirements from content
|
|
56
|
+
*
|
|
57
|
+
* @param content - Document content
|
|
58
|
+
* @returns Array of requirements
|
|
59
|
+
*/
|
|
60
|
+
export declare function extractRequirements(content: string): BMADRequirement[];
|
|
61
|
+
/**
|
|
62
|
+
* Extract user stories from content
|
|
63
|
+
*
|
|
64
|
+
* @param content - Document content
|
|
65
|
+
* @returns Array of user stories
|
|
66
|
+
*/
|
|
67
|
+
export declare function extractUserStories(content: string): BMADUserStory[];
|
|
68
|
+
/**
|
|
69
|
+
* Extract change log entries from content
|
|
70
|
+
*
|
|
71
|
+
* @param content - Document content
|
|
72
|
+
* @returns Array of change log entries
|
|
73
|
+
*/
|
|
74
|
+
export declare function extractChangeLog(content: string): BMADChangeLogEntry[];
|
|
75
|
+
/**
|
|
76
|
+
* Identify document type from content
|
|
77
|
+
*
|
|
78
|
+
* @param content - Document content
|
|
79
|
+
* @param frontMatter - Parsed front-matter
|
|
80
|
+
* @returns Document type
|
|
81
|
+
*/
|
|
82
|
+
export declare function identifyDocumentType(content: string, frontMatter?: BMADFrontMatter | null): BMADDocumentType;
|
|
83
|
+
/**
|
|
84
|
+
* Analyze content for detection indicators
|
|
85
|
+
*
|
|
86
|
+
* @param content - Document content
|
|
87
|
+
* @param hint - Optional path detection hint
|
|
88
|
+
* @returns Detection indicators
|
|
89
|
+
*/
|
|
90
|
+
export declare function analyzeContent(content: string, hint?: PathDetectionHint): DetectionIndicators;
|
|
91
|
+
/**
|
|
92
|
+
* Calculate detection confidence score
|
|
93
|
+
*
|
|
94
|
+
* @param indicators - Detection indicators
|
|
95
|
+
* @returns Confidence score (0-100)
|
|
96
|
+
*/
|
|
97
|
+
export declare function calculateConfidenceScore(indicators: DetectionIndicators): number;
|
|
98
|
+
/**
|
|
99
|
+
* Build detection reason message
|
|
100
|
+
*
|
|
101
|
+
* @param indicators - Detection indicators
|
|
102
|
+
* @returns Reason message
|
|
103
|
+
*/
|
|
104
|
+
export declare function buildDetectionReason(indicators: DetectionIndicators): string;
|
|
105
|
+
/**
|
|
106
|
+
* Extract document title from content
|
|
107
|
+
*
|
|
108
|
+
* @param content - Document content
|
|
109
|
+
* @returns Title or null
|
|
110
|
+
*/
|
|
111
|
+
export declare function extractTitle(content: string): string | null;
|
|
112
|
+
/**
|
|
113
|
+
* Extract intent/summary from document
|
|
114
|
+
*
|
|
115
|
+
* @param content - Document content
|
|
116
|
+
* @param docType - Document type
|
|
117
|
+
* @returns Intent description
|
|
118
|
+
*/
|
|
119
|
+
export declare function extractIntent(content: string, docType: BMADDocumentType): string;
|
|
120
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/bmad/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,eAAe,EACf,eAAe,EACf,aAAa,EACb,kBAAkB,EAElB,gBAAgB,EAChB,mBAAmB,EAEpB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,iBAAiB,GAAG;IACpD,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;CACzB,CAqBA;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAc1F;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE/D;AAMD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAKnE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CA2C1E;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,EAAE,CAuBtE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CAiEnE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAoCtE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,eAAe,GAAG,IAAI,GACnC,gBAAgB,CAkClB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,iBAAiB,GAAG,mBAAmB,CA0B7F;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,mBAAmB,GAAG,MAAM,CAqDhF;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,mBAAmB,GAAG,MAAM,CAoC5E;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAa3D;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAsDhF"}
|