specweave 0.22.11 → 0.22.13
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/CLAUDE.md +77 -0
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +42 -0
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/helpers/init/initial-increment-generator.d.ts +26 -0
- package/dist/src/cli/helpers/init/initial-increment-generator.d.ts.map +1 -0
- package/dist/src/cli/helpers/init/initial-increment-generator.js +240 -0
- package/dist/src/cli/helpers/init/initial-increment-generator.js.map +1 -0
- package/dist/src/generators/spec/spec-parser.d.ts +79 -0
- package/dist/src/generators/spec/spec-parser.d.ts.map +1 -0
- package/dist/src/generators/spec/spec-parser.js +185 -0
- package/dist/src/generators/spec/spec-parser.js.map +1 -0
- package/dist/src/generators/spec/task-parser.d.ts +95 -0
- package/dist/src/generators/spec/task-parser.d.ts.map +1 -0
- package/dist/src/generators/spec/task-parser.js +301 -0
- package/dist/src/generators/spec/task-parser.js.map +1 -0
- package/dist/src/validators/ac-coverage-validator.d.ts +106 -0
- package/dist/src/validators/ac-coverage-validator.d.ts.map +1 -0
- package/dist/src/validators/ac-coverage-validator.js +250 -0
- package/dist/src/validators/ac-coverage-validator.js.map +1 -0
- package/package.json +2 -2
- package/plugins/specweave/commands/specweave-done.md +58 -0
- package/plugins/specweave/commands/specweave-validate.md +36 -6
- package/plugins/specweave/lib/hooks/sync-living-docs.js +21 -0
- package/plugins/specweave/lib/hooks/sync-us-tasks.js +290 -0
- package/src/templates/AGENTS.md.template +16 -0
- package/src/templates/CLAUDE.md.template +18 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Initial Increment Generator
|
|
3
|
+
*
|
|
4
|
+
* Automatically creates increment 0001-project-setup during `specweave init`
|
|
5
|
+
* so users have a valid starting point to work from.
|
|
6
|
+
*
|
|
7
|
+
* Part of: Empty increments folder fix (2025-11-19)
|
|
8
|
+
*/
|
|
9
|
+
import fs from 'fs-extra';
|
|
10
|
+
import path from 'path';
|
|
11
|
+
import { IncrementStatus, IncrementType } from '../../../core/types/increment-metadata.js';
|
|
12
|
+
import { MetadataManager } from '../../../core/increment/metadata-manager.js';
|
|
13
|
+
/**
|
|
14
|
+
* Generate initial increment (0001-project-setup) during init
|
|
15
|
+
*
|
|
16
|
+
* Creates:
|
|
17
|
+
* - .specweave/increments/0001-project-setup/
|
|
18
|
+
* - spec.md (basic project setup requirements)
|
|
19
|
+
* - plan.md (placeholder for implementation plan)
|
|
20
|
+
* - tasks.md (initial setup tasks)
|
|
21
|
+
* - metadata.json (ACTIVE status)
|
|
22
|
+
*/
|
|
23
|
+
export async function generateInitialIncrement(options) {
|
|
24
|
+
const { projectPath, projectName, techStack, language = 'en' } = options;
|
|
25
|
+
const incrementId = '0001-project-setup';
|
|
26
|
+
const incrementPath = path.join(projectPath, '.specweave', 'increments', incrementId);
|
|
27
|
+
// Create increment directory
|
|
28
|
+
fs.ensureDirSync(incrementPath);
|
|
29
|
+
// Generate spec.md
|
|
30
|
+
const specContent = generateSpecMd(projectName, techStack);
|
|
31
|
+
fs.writeFileSync(path.join(incrementPath, 'spec.md'), specContent, 'utf-8');
|
|
32
|
+
// Generate plan.md
|
|
33
|
+
const planContent = generatePlanMd(projectName);
|
|
34
|
+
fs.writeFileSync(path.join(incrementPath, 'plan.md'), planContent, 'utf-8');
|
|
35
|
+
// Generate tasks.md
|
|
36
|
+
const tasksContent = generateTasksMd(projectName, techStack);
|
|
37
|
+
fs.writeFileSync(path.join(incrementPath, 'tasks.md'), tasksContent, 'utf-8');
|
|
38
|
+
// Generate metadata.json
|
|
39
|
+
const metadata = {
|
|
40
|
+
id: incrementId,
|
|
41
|
+
type: IncrementType.FEATURE,
|
|
42
|
+
status: IncrementStatus.ACTIVE,
|
|
43
|
+
created: new Date().toISOString().split('T')[0],
|
|
44
|
+
lastActivity: new Date().toISOString().split('T')[0],
|
|
45
|
+
testMode: 'test-after',
|
|
46
|
+
coverageTarget: 80
|
|
47
|
+
};
|
|
48
|
+
MetadataManager.write(incrementId, metadata);
|
|
49
|
+
return incrementId;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Generate spec.md content
|
|
53
|
+
*/
|
|
54
|
+
function generateSpecMd(projectName, techStack) {
|
|
55
|
+
const techStackSection = techStack
|
|
56
|
+
? `**Tech Stack**: ${techStack}\n`
|
|
57
|
+
: '';
|
|
58
|
+
return `---
|
|
59
|
+
increment: 0001-project-setup
|
|
60
|
+
title: "Project Setup"
|
|
61
|
+
type: feature
|
|
62
|
+
priority: P0
|
|
63
|
+
status: active
|
|
64
|
+
created: ${new Date().toISOString().split('T')[0]}
|
|
65
|
+
epic: SETUP-001
|
|
66
|
+
test_mode: test-after
|
|
67
|
+
coverage_target: 80
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
# Feature: Project Setup
|
|
71
|
+
|
|
72
|
+
## Overview
|
|
73
|
+
|
|
74
|
+
Initialize ${projectName} with SpecWeave framework and establish development workflow.
|
|
75
|
+
|
|
76
|
+
${techStackSection}
|
|
77
|
+
**Business Impact**: Foundation for spec-driven development process.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## User Stories
|
|
82
|
+
|
|
83
|
+
### US-001: Development Environment
|
|
84
|
+
|
|
85
|
+
**As a** developer
|
|
86
|
+
**I want** a properly configured development environment
|
|
87
|
+
**So that** I can start building features immediately
|
|
88
|
+
|
|
89
|
+
**Acceptance Criteria**:
|
|
90
|
+
- [ ] **AC-US1-01**: Project structure created with .specweave/ folder
|
|
91
|
+
- **Priority**: P0 (Critical)
|
|
92
|
+
- **Testable**: Yes
|
|
93
|
+
|
|
94
|
+
- [ ] **AC-US1-02**: Documentation framework initialized
|
|
95
|
+
- **Priority**: P0 (Critical)
|
|
96
|
+
- **Testable**: Yes
|
|
97
|
+
|
|
98
|
+
- [ ] **AC-US1-03**: SpecWeave commands available (/specweave:increment, /specweave:do, etc.)
|
|
99
|
+
- **Priority**: P0 (Critical)
|
|
100
|
+
- **Testable**: Yes
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Notes
|
|
105
|
+
|
|
106
|
+
**IMPORTANT**: This is your initial increment created by \`specweave init\`.
|
|
107
|
+
|
|
108
|
+
**Next steps**:
|
|
109
|
+
1. Review this spec and customize it for your project
|
|
110
|
+
2. Run \`/specweave:plan\` to generate implementation tasks
|
|
111
|
+
3. Run \`/specweave:do\` to start working on tasks
|
|
112
|
+
4. Create your first feature with \`/specweave:increment "your-feature"\`
|
|
113
|
+
|
|
114
|
+
You can also delete this increment if you prefer to start fresh:
|
|
115
|
+
- Delete \`.specweave/increments/0001-project-setup/\`
|
|
116
|
+
- Create your first real increment with \`/specweave:increment "my-feature"\`
|
|
117
|
+
`;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Generate plan.md content
|
|
121
|
+
*/
|
|
122
|
+
function generatePlanMd(projectName) {
|
|
123
|
+
return `---
|
|
124
|
+
increment: 0001-project-setup
|
|
125
|
+
generated: ${new Date().toISOString()}
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
# Implementation Plan: Project Setup
|
|
129
|
+
|
|
130
|
+
## Overview
|
|
131
|
+
|
|
132
|
+
Initial setup for ${projectName} with SpecWeave framework.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Implementation Steps
|
|
137
|
+
|
|
138
|
+
### Phase 1: Environment Setup ✅
|
|
139
|
+
|
|
140
|
+
**Status**: COMPLETED (via \`specweave init\`)
|
|
141
|
+
|
|
142
|
+
Steps completed:
|
|
143
|
+
1. ✅ Created .specweave/ directory structure
|
|
144
|
+
2. ✅ Initialized git repository
|
|
145
|
+
3. ✅ Created CLAUDE.md and AGENTS.md instruction files
|
|
146
|
+
4. ✅ Configured SpecWeave plugins (Claude Code)
|
|
147
|
+
|
|
148
|
+
### Phase 2: First Feature Planning
|
|
149
|
+
|
|
150
|
+
**Status**: PENDING (ready when you are!)
|
|
151
|
+
|
|
152
|
+
Next actions:
|
|
153
|
+
1. Customize this increment spec to match your project goals
|
|
154
|
+
2. OR delete this increment and create your first real feature:
|
|
155
|
+
\`\`\`
|
|
156
|
+
/specweave:increment "user-authentication"
|
|
157
|
+
/specweave:increment "api-endpoints"
|
|
158
|
+
/specweave:increment "database-schema"
|
|
159
|
+
\`\`\`
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Notes
|
|
164
|
+
|
|
165
|
+
This is a placeholder plan created by \`specweave init\`.
|
|
166
|
+
|
|
167
|
+
**Recommended**: Create a new increment for your first real feature instead of using this setup increment.
|
|
168
|
+
`;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Generate tasks.md content
|
|
172
|
+
*/
|
|
173
|
+
function generateTasksMd(projectName, techStack) {
|
|
174
|
+
const techStackNote = techStack
|
|
175
|
+
? `\n**Tech Stack**: ${techStack}`
|
|
176
|
+
: '';
|
|
177
|
+
return `---
|
|
178
|
+
increment: 0001-project-setup
|
|
179
|
+
total_tasks: 1
|
|
180
|
+
completed_tasks: 1
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
# Tasks: Project Setup${techStackNote}
|
|
184
|
+
|
|
185
|
+
## User Story: US-001 - Development Environment
|
|
186
|
+
|
|
187
|
+
**Linked ACs**: AC-US1-01, AC-US1-02, AC-US1-03
|
|
188
|
+
**Tasks**: 1 total, 1 completed
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
### T-001: Initialize SpecWeave Framework
|
|
193
|
+
|
|
194
|
+
**User Story**: US-001
|
|
195
|
+
**Satisfies ACs**: AC-US1-01, AC-US1-02, AC-US1-03
|
|
196
|
+
**Status**: [x] completed
|
|
197
|
+
**Priority**: P0 (Critical)
|
|
198
|
+
**Estimated Effort**: 0 hours (automated)
|
|
199
|
+
|
|
200
|
+
**Description**:
|
|
201
|
+
Ran \`specweave init\` to create project structure, install plugins, and configure framework.
|
|
202
|
+
|
|
203
|
+
**Implementation Steps**:
|
|
204
|
+
1. ✅ Created .specweave/ directory with increments, docs folders
|
|
205
|
+
2. ✅ Generated CLAUDE.md and AGENTS.md instruction files
|
|
206
|
+
3. ✅ Initialized git repository
|
|
207
|
+
4. ✅ Created this initial increment (0001-project-setup)
|
|
208
|
+
|
|
209
|
+
**Test Plan**:
|
|
210
|
+
- **Manual**: Verify \`/specweave:status\` shows active increment
|
|
211
|
+
- **Manual**: Verify SpecWeave commands available
|
|
212
|
+
|
|
213
|
+
**Files Affected**:
|
|
214
|
+
- \`.specweave/\` (entire structure)
|
|
215
|
+
- \`CLAUDE.md\`, \`AGENTS.md\`, \`README.md\`
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Next Steps
|
|
220
|
+
|
|
221
|
+
This initial increment is now **COMPLETE**. You have two options:
|
|
222
|
+
|
|
223
|
+
### Option 1: Start Fresh (Recommended)
|
|
224
|
+
Delete this increment and create your first real feature:
|
|
225
|
+
\`\`\`bash
|
|
226
|
+
rm -rf .specweave/increments/0001-project-setup
|
|
227
|
+
/specweave:increment "your-first-feature"
|
|
228
|
+
\`\`\`
|
|
229
|
+
|
|
230
|
+
### Option 2: Customize This Increment
|
|
231
|
+
Keep this increment and add your own tasks:
|
|
232
|
+
\`\`\`bash
|
|
233
|
+
/specweave:plan # Regenerate tasks based on updated spec.md
|
|
234
|
+
/specweave:do # Start working on tasks
|
|
235
|
+
\`\`\`
|
|
236
|
+
|
|
237
|
+
**Recommended**: Go with Option 1 and create meaningful increments for your project!
|
|
238
|
+
`;
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=initial-increment-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initial-increment-generator.js","sourceRoot":"","sources":["../../../../../src/cli/helpers/init/initial-increment-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spec Parser - Extract User Stories and Acceptance Criteria from spec.md
|
|
3
|
+
*
|
|
4
|
+
* Parses increment spec.md files to extract:
|
|
5
|
+
* - User Story IDs (US-001, US-002, etc.)
|
|
6
|
+
* - Acceptance Criteria IDs (AC-US1-01, AC-US1-02, etc.)
|
|
7
|
+
* - User Story titles and metadata
|
|
8
|
+
*
|
|
9
|
+
* Used by AC coverage validator to cross-reference tasks with requirements.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* User Story metadata
|
|
13
|
+
*/
|
|
14
|
+
export interface UserStory {
|
|
15
|
+
/** User Story ID (e.g., "US-001") */
|
|
16
|
+
id: string;
|
|
17
|
+
/** User Story title */
|
|
18
|
+
title: string;
|
|
19
|
+
/** Priority (P0, P1, P2, P3) */
|
|
20
|
+
priority?: string;
|
|
21
|
+
/** Acceptance Criteria IDs for this US */
|
|
22
|
+
acceptanceCriteria: string[];
|
|
23
|
+
/** Full text of the user story */
|
|
24
|
+
description?: string;
|
|
25
|
+
/** Line number in spec.md */
|
|
26
|
+
lineNumber?: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Spec metadata
|
|
30
|
+
*/
|
|
31
|
+
export interface SpecMetadata {
|
|
32
|
+
/** Increment ID */
|
|
33
|
+
incrementId: string;
|
|
34
|
+
/** Increment title */
|
|
35
|
+
title: string;
|
|
36
|
+
/** All User Stories */
|
|
37
|
+
userStories: UserStory[];
|
|
38
|
+
/** All AC-IDs (flattened from all user stories) */
|
|
39
|
+
allACIds: string[];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Parse spec.md to extract User Stories and Acceptance Criteria
|
|
43
|
+
*
|
|
44
|
+
* @param specPath - Path to spec.md file
|
|
45
|
+
* @returns Spec metadata with User Stories and AC-IDs
|
|
46
|
+
* @throws Error if spec.md cannot be read or is malformed
|
|
47
|
+
*/
|
|
48
|
+
export declare function parseSpecMd(specPath: string): SpecMetadata;
|
|
49
|
+
/**
|
|
50
|
+
* Get all User Story IDs from spec
|
|
51
|
+
*
|
|
52
|
+
* @param specPath - Path to spec.md
|
|
53
|
+
* @returns Array of US-IDs (e.g., ["US-001", "US-002"])
|
|
54
|
+
*/
|
|
55
|
+
export declare function getAllUSIds(specPath: string): string[];
|
|
56
|
+
/**
|
|
57
|
+
* Get all AC-IDs from spec
|
|
58
|
+
*
|
|
59
|
+
* @param specPath - Path to spec.md
|
|
60
|
+
* @returns Array of AC-IDs (e.g., ["AC-US1-01", "AC-US1-02"])
|
|
61
|
+
*/
|
|
62
|
+
export declare function getAllACIds(specPath: string): string[];
|
|
63
|
+
/**
|
|
64
|
+
* Get AC-IDs for a specific User Story
|
|
65
|
+
*
|
|
66
|
+
* @param specPath - Path to spec.md
|
|
67
|
+
* @param usId - User Story ID (e.g., "US-001")
|
|
68
|
+
* @returns Array of AC-IDs for that US
|
|
69
|
+
*/
|
|
70
|
+
export declare function getACsForUS(specPath: string, usId: string): string[];
|
|
71
|
+
/**
|
|
72
|
+
* Validate that an AC-ID belongs to the correct User Story
|
|
73
|
+
*
|
|
74
|
+
* @param acId - AC-ID to validate (e.g., "AC-US1-01")
|
|
75
|
+
* @param usId - Expected User Story ID (e.g., "US-001")
|
|
76
|
+
* @returns True if AC belongs to US, false otherwise
|
|
77
|
+
*/
|
|
78
|
+
export declare function validateACBelongsToUS(acId: string, usId: string): boolean;
|
|
79
|
+
//# sourceMappingURL=spec-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-parser.d.ts","sourceRoot":"","sources":["../../../../src/generators/spec/spec-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,qCAAqC;IACrC,EAAE,EAAE,MAAM,CAAC;IAEX,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;IAEd,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,0CAA0C;IAC1C,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAE7B,kCAAkC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,6BAA6B;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAC;IAEpB,sBAAsB;IACtB,KAAK,EAAE,MAAM,CAAC;IAEd,uBAAuB;IACvB,WAAW,EAAE,SAAS,EAAE,CAAC;IAEzB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CAuB1D;AA8GD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAGtD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAGtD;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAIpE;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAczE"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spec Parser - Extract User Stories and Acceptance Criteria from spec.md
|
|
3
|
+
*
|
|
4
|
+
* Parses increment spec.md files to extract:
|
|
5
|
+
* - User Story IDs (US-001, US-002, etc.)
|
|
6
|
+
* - Acceptance Criteria IDs (AC-US1-01, AC-US1-02, etc.)
|
|
7
|
+
* - User Story titles and metadata
|
|
8
|
+
*
|
|
9
|
+
* Used by AC coverage validator to cross-reference tasks with requirements.
|
|
10
|
+
*/
|
|
11
|
+
import { readFileSync } from 'fs';
|
|
12
|
+
/**
|
|
13
|
+
* Parse spec.md to extract User Stories and Acceptance Criteria
|
|
14
|
+
*
|
|
15
|
+
* @param specPath - Path to spec.md file
|
|
16
|
+
* @returns Spec metadata with User Stories and AC-IDs
|
|
17
|
+
* @throws Error if spec.md cannot be read or is malformed
|
|
18
|
+
*/
|
|
19
|
+
export function parseSpecMd(specPath) {
|
|
20
|
+
try {
|
|
21
|
+
const content = readFileSync(specPath, 'utf-8');
|
|
22
|
+
const lines = content.split('\n');
|
|
23
|
+
// Extract increment ID and title from frontmatter
|
|
24
|
+
const { incrementId, title } = parseFrontmatter(lines);
|
|
25
|
+
// Extract User Stories
|
|
26
|
+
const userStories = extractUserStories(lines);
|
|
27
|
+
// Flatten all AC-IDs
|
|
28
|
+
const allACIds = userStories.flatMap(us => us.acceptanceCriteria);
|
|
29
|
+
return {
|
|
30
|
+
incrementId,
|
|
31
|
+
title,
|
|
32
|
+
userStories,
|
|
33
|
+
allACIds
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
throw new Error(`Failed to parse spec.md at ${specPath}: ${error}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Parse YAML frontmatter to extract increment ID and title
|
|
42
|
+
*/
|
|
43
|
+
function parseFrontmatter(lines) {
|
|
44
|
+
let incrementId = '';
|
|
45
|
+
let title = '';
|
|
46
|
+
let inFrontmatter = false;
|
|
47
|
+
for (const line of lines) {
|
|
48
|
+
if (line.trim() === '---') {
|
|
49
|
+
if (!inFrontmatter) {
|
|
50
|
+
inFrontmatter = true;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
break; // End of frontmatter
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (inFrontmatter) {
|
|
58
|
+
const incrementMatch = line.match(/^increment:\s*(.+)$/);
|
|
59
|
+
if (incrementMatch) {
|
|
60
|
+
incrementId = incrementMatch[1].trim();
|
|
61
|
+
}
|
|
62
|
+
const titleMatch = line.match(/^title:\s*["']?(.+?)["']?$/);
|
|
63
|
+
if (titleMatch) {
|
|
64
|
+
title = titleMatch[1].trim();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return { incrementId, title };
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Extract User Stories and their Acceptance Criteria
|
|
72
|
+
*/
|
|
73
|
+
function extractUserStories(lines) {
|
|
74
|
+
const userStories = [];
|
|
75
|
+
let currentUS = null;
|
|
76
|
+
let inACSection = false;
|
|
77
|
+
// Regex patterns
|
|
78
|
+
const usHeaderRegex = /^###?\s+(US-\d{3}):\s*(.+)$/; // ### US-001: Title or ## US-001: Title
|
|
79
|
+
const acRegex = /^-\s*\[[x ]\]\s*\*\*(AC-US\d+-\d{2})\*\*/; // - [ ] **AC-US1-01**
|
|
80
|
+
const priorityRegex = /\*\*Priority\*\*:\s*(P[0-3])/;
|
|
81
|
+
for (let i = 0; i < lines.length; i++) {
|
|
82
|
+
const line = lines[i];
|
|
83
|
+
const lineNumber = i + 1;
|
|
84
|
+
// Check for User Story header
|
|
85
|
+
const usMatch = line.match(usHeaderRegex);
|
|
86
|
+
if (usMatch) {
|
|
87
|
+
// Save previous US if exists
|
|
88
|
+
if (currentUS) {
|
|
89
|
+
userStories.push(currentUS);
|
|
90
|
+
}
|
|
91
|
+
// Start new US
|
|
92
|
+
currentUS = {
|
|
93
|
+
id: usMatch[1],
|
|
94
|
+
title: usMatch[2],
|
|
95
|
+
acceptanceCriteria: [],
|
|
96
|
+
lineNumber
|
|
97
|
+
};
|
|
98
|
+
inACSection = false;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
// Skip if no current US
|
|
102
|
+
if (!currentUS)
|
|
103
|
+
continue;
|
|
104
|
+
// Check for Acceptance Criteria section
|
|
105
|
+
if (line.includes('**Acceptance Criteria**:') || line.includes('Acceptance Criteria')) {
|
|
106
|
+
inACSection = true;
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
// Check for end of AC section (next major section)
|
|
110
|
+
if (line.startsWith('##') && !line.match(usHeaderRegex)) {
|
|
111
|
+
inACSection = false;
|
|
112
|
+
}
|
|
113
|
+
// Extract AC-IDs if in AC section
|
|
114
|
+
if (inACSection) {
|
|
115
|
+
const acMatch = line.match(acRegex);
|
|
116
|
+
if (acMatch) {
|
|
117
|
+
const acId = acMatch[1];
|
|
118
|
+
currentUS.acceptanceCriteria.push(acId);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Extract priority if present
|
|
122
|
+
const priorityMatch = line.match(priorityRegex);
|
|
123
|
+
if (priorityMatch && !currentUS.priority) {
|
|
124
|
+
currentUS.priority = priorityMatch[1];
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Save last US
|
|
128
|
+
if (currentUS) {
|
|
129
|
+
userStories.push(currentUS);
|
|
130
|
+
}
|
|
131
|
+
return userStories;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Get all User Story IDs from spec
|
|
135
|
+
*
|
|
136
|
+
* @param specPath - Path to spec.md
|
|
137
|
+
* @returns Array of US-IDs (e.g., ["US-001", "US-002"])
|
|
138
|
+
*/
|
|
139
|
+
export function getAllUSIds(specPath) {
|
|
140
|
+
const spec = parseSpecMd(specPath);
|
|
141
|
+
return spec.userStories.map(us => us.id);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Get all AC-IDs from spec
|
|
145
|
+
*
|
|
146
|
+
* @param specPath - Path to spec.md
|
|
147
|
+
* @returns Array of AC-IDs (e.g., ["AC-US1-01", "AC-US1-02"])
|
|
148
|
+
*/
|
|
149
|
+
export function getAllACIds(specPath) {
|
|
150
|
+
const spec = parseSpecMd(specPath);
|
|
151
|
+
return spec.allACIds;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Get AC-IDs for a specific User Story
|
|
155
|
+
*
|
|
156
|
+
* @param specPath - Path to spec.md
|
|
157
|
+
* @param usId - User Story ID (e.g., "US-001")
|
|
158
|
+
* @returns Array of AC-IDs for that US
|
|
159
|
+
*/
|
|
160
|
+
export function getACsForUS(specPath, usId) {
|
|
161
|
+
const spec = parseSpecMd(specPath);
|
|
162
|
+
const us = spec.userStories.find(story => story.id === usId);
|
|
163
|
+
return us ? us.acceptanceCriteria : [];
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Validate that an AC-ID belongs to the correct User Story
|
|
167
|
+
*
|
|
168
|
+
* @param acId - AC-ID to validate (e.g., "AC-US1-01")
|
|
169
|
+
* @param usId - Expected User Story ID (e.g., "US-001")
|
|
170
|
+
* @returns True if AC belongs to US, false otherwise
|
|
171
|
+
*/
|
|
172
|
+
export function validateACBelongsToUS(acId, usId) {
|
|
173
|
+
// Extract US number from AC-ID: AC-US1-01 → 1
|
|
174
|
+
const acMatch = acId.match(/^AC-US(\d+)-\d{2}$/);
|
|
175
|
+
if (!acMatch)
|
|
176
|
+
return false;
|
|
177
|
+
const acUSNumber = parseInt(acMatch[1], 10);
|
|
178
|
+
// Extract US number from US-ID: US-001 → 1
|
|
179
|
+
const usMatch = usId.match(/^US-(\d{3})$/);
|
|
180
|
+
if (!usMatch)
|
|
181
|
+
return false;
|
|
182
|
+
const usNumber = parseInt(usMatch[1], 10);
|
|
183
|
+
return acUSNumber === usNumber;
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=spec-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-parser.js","sourceRoot":"","sources":["../../../../src/generators/spec/spec-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AA2ClC;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAElC,kDAAkD;QAClD,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAEvD,uBAAuB;QACvB,MAAM,WAAW,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;QAE9C,qBAAqB;QACrB,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC;QAElE,OAAO;YACL,WAAW;YACX,KAAK;YACL,WAAW;YACX,QAAQ;SACT,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,8BAA8B,QAAQ,KAAK,KAAK,EAAE,CAAC,CAAC;IACtE,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,KAAe;IACvC,IAAI,WAAW,GAAG,EAAE,CAAC;IACrB,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,IAAI,aAAa,GAAG,KAAK,CAAC;IAE1B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,KAAK,EAAE,CAAC;YAC1B,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnB,aAAa,GAAG,IAAI,CAAC;gBACrB,SAAS;YACX,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,qBAAqB;YAC9B,CAAC;QACH,CAAC;QAED,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;YACzD,IAAI,cAAc,EAAE,CAAC;gBACnB,WAAW,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACzC,CAAC;YAED,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;YAC5D,IAAI,UAAU,EAAE,CAAC;gBACf,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;AAChC,CAAC;AAED;;GAEG;AACH,SAAS,kBAAkB,CAAC,KAAe;IACzC,MAAM,WAAW,GAAgB,EAAE,CAAC;IACpC,IAAI,SAAS,GAAqB,IAAI,CAAC;IACvC,IAAI,WAAW,GAAG,KAAK,CAAC;IAExB,iBAAiB;IACjB,MAAM,aAAa,GAAG,6BAA6B,CAAC,CAAE,wCAAwC;IAC9F,MAAM,OAAO,GAAG,0CAA0C,CAAC,CAAE,sBAAsB;IACnF,MAAM,aAAa,GAAG,8BAA8B,CAAC;IAErD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,CAAC;QAEzB,8BAA8B;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAC1C,IAAI,OAAO,EAAE,CAAC;YACZ,6BAA6B;YAC7B,IAAI,SAAS,EAAE,CAAC;gBACd,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC9B,CAAC;YAED,eAAe;YACf,SAAS,GAAG;gBACV,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;gBACd,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;gBACjB,kBAAkB,EAAE,EAAE;gBACtB,UAAU;aACX,CAAC;YACF,WAAW,GAAG,KAAK,CAAC;YACpB,SAAS;QACX,CAAC;QAED,wBAAwB;QACxB,IAAI,CAAC,SAAS;YAAE,SAAS;QAEzB,wCAAwC;QACxC,IAAI,IAAI,CAAC,QAAQ,CAAC,0BAA0B,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC;YACtF,WAAW,GAAG,IAAI,CAAC;YACnB,SAAS;QACX,CAAC;QAED,mDAAmD;QACnD,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC;YACxD,WAAW,GAAG,KAAK,CAAC;QACtB,CAAC;QAED,kCAAkC;QAClC,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACpC,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;gBACxB,SAAS,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;QAED,8BAA8B;QAC9B,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAChD,IAAI,aAAa,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;YACzC,SAAS,CAAC,QAAQ,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED,eAAe;IACf,IAAI,SAAS,EAAE,CAAC;QACd,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,MAAM,IAAI,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IACnC,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,MAAM,IAAI,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IACnC,OAAO,IAAI,CAAC,QAAQ,CAAC;AACvB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,QAAgB,EAAE,IAAY;IACxD,MAAM,IAAI,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC;IAC7D,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;AACzC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY,EAAE,IAAY;IAC9D,8CAA8C;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACjD,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAE3B,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAE5C,2CAA2C;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC3C,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAE3B,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAE1C,OAAO,UAAU,KAAK,QAAQ,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task Parser with US-Task Linkage Support
|
|
3
|
+
*
|
|
4
|
+
* Parses tasks.md files to extract task metadata including new US linkage fields:
|
|
5
|
+
* - userStory: US-ID this task implements (e.g., "US-001")
|
|
6
|
+
* - satisfiesACs: List of AC-IDs this task satisfies (e.g., ["AC-US1-01", "AC-US1-02"])
|
|
7
|
+
*
|
|
8
|
+
* Supports hierarchical task structure grouped by User Story.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Task metadata extracted from tasks.md
|
|
12
|
+
*/
|
|
13
|
+
export interface Task {
|
|
14
|
+
/** Task ID (e.g., "T-001") */
|
|
15
|
+
id: string;
|
|
16
|
+
/** Task title */
|
|
17
|
+
title: string;
|
|
18
|
+
/** User Story this task implements (optional for backward compatibility) */
|
|
19
|
+
userStory?: string;
|
|
20
|
+
/** Acceptance Criteria IDs this task satisfies (optional) */
|
|
21
|
+
satisfiesACs?: string[];
|
|
22
|
+
/** Task completion status */
|
|
23
|
+
status: TaskStatus;
|
|
24
|
+
/** Priority level (P0, P1, P2, P3) */
|
|
25
|
+
priority?: string;
|
|
26
|
+
/** Estimated effort (e.g., "4 hours", "2 days") */
|
|
27
|
+
estimatedEffort?: string;
|
|
28
|
+
/** Task dependencies (task IDs this depends on) */
|
|
29
|
+
dependencies?: string[];
|
|
30
|
+
/** Full task description */
|
|
31
|
+
description?: string;
|
|
32
|
+
/** Files affected by this task */
|
|
33
|
+
filesAffected?: string[];
|
|
34
|
+
/** Line number in tasks.md (for error reporting) */
|
|
35
|
+
lineNumber?: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Task completion status
|
|
39
|
+
*/
|
|
40
|
+
export type TaskStatus = 'pending' | 'in_progress' | 'completed' | 'transferred' | 'canceled';
|
|
41
|
+
/**
|
|
42
|
+
* Tasks grouped by User Story
|
|
43
|
+
*/
|
|
44
|
+
export interface TasksByUserStory {
|
|
45
|
+
[usId: string]: Task[];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Validation error for task linkage
|
|
49
|
+
*/
|
|
50
|
+
export interface TaskLinkageError {
|
|
51
|
+
taskId: string;
|
|
52
|
+
field: 'userStory' | 'satisfiesACs';
|
|
53
|
+
value: string;
|
|
54
|
+
message: string;
|
|
55
|
+
suggestedFix?: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Parse tasks.md and extract all tasks with US linkage
|
|
59
|
+
*
|
|
60
|
+
* @param tasksPath - Path to tasks.md file
|
|
61
|
+
* @returns Map of User Story ID → Tasks
|
|
62
|
+
* @throws Error if tasks.md cannot be read or is malformed
|
|
63
|
+
*/
|
|
64
|
+
export declare function parseTasksWithUSLinks(tasksPath: string): TasksByUserStory;
|
|
65
|
+
/**
|
|
66
|
+
* Validate task US and AC linkage
|
|
67
|
+
*
|
|
68
|
+
* @param task - Task to validate
|
|
69
|
+
* @param validUSIds - List of valid US-IDs from spec.md
|
|
70
|
+
* @param validACIds - List of valid AC-IDs from spec.md
|
|
71
|
+
* @returns Array of validation errors (empty if valid)
|
|
72
|
+
*/
|
|
73
|
+
export declare function validateTaskLinkage(task: Task, validUSIds: string[], validACIds: string[]): TaskLinkageError[];
|
|
74
|
+
/**
|
|
75
|
+
* Get all tasks (flattened, not grouped by US)
|
|
76
|
+
*
|
|
77
|
+
* @param tasksByUS - Tasks grouped by User Story
|
|
78
|
+
* @returns Array of all tasks
|
|
79
|
+
*/
|
|
80
|
+
export declare function getAllTasks(tasksByUS: TasksByUserStory): Task[];
|
|
81
|
+
/**
|
|
82
|
+
* Count tasks by status
|
|
83
|
+
*
|
|
84
|
+
* @param tasksByUS - Tasks grouped by User Story
|
|
85
|
+
* @returns Map of status → count
|
|
86
|
+
*/
|
|
87
|
+
export declare function countTasksByStatus(tasksByUS: TasksByUserStory): Record<TaskStatus, number>;
|
|
88
|
+
/**
|
|
89
|
+
* Calculate completion percentage
|
|
90
|
+
*
|
|
91
|
+
* @param tasksByUS - Tasks grouped by User Story
|
|
92
|
+
* @returns Completion percentage (0-100)
|
|
93
|
+
*/
|
|
94
|
+
export declare function calculateCompletionPercentage(tasksByUS: TasksByUserStory): number;
|
|
95
|
+
//# sourceMappingURL=task-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-parser.d.ts","sourceRoot":"","sources":["../../../../src/generators/spec/task-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH;;GAEG;AACH,MAAM,WAAW,IAAI;IACnB,8BAA8B;IAC9B,EAAE,EAAE,MAAM,CAAC;IAEX,iBAAiB;IACjB,KAAK,EAAE,MAAM,CAAC;IAEd,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAExB,6BAA6B;IAC7B,MAAM,EAAE,UAAU,CAAC;IAEnB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,mDAAmD;IACnD,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,mDAAmD;IACnD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAExB,4BAA4B;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,kCAAkC;IAClC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAEzB,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,GAAG,aAAa,GAAG,UAAU,CAAC;AAE9F;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,WAAW,GAAG,cAAc,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAoJzE;AAoBD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,MAAM,EAAE,EACpB,UAAU,EAAE,MAAM,EAAE,GACnB,gBAAgB,EAAE,CAyEpB;AAkBD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,gBAAgB,GAAG,IAAI,EAAE,CAE/D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,gBAAgB,GAAG,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAe1F;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,gBAAgB,GAAG,MAAM,CAMjF"}
|