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.
Files changed (27) hide show
  1. package/CLAUDE.md +77 -0
  2. package/dist/src/cli/commands/init.d.ts.map +1 -1
  3. package/dist/src/cli/commands/init.js +42 -0
  4. package/dist/src/cli/commands/init.js.map +1 -1
  5. package/dist/src/cli/helpers/init/initial-increment-generator.d.ts +26 -0
  6. package/dist/src/cli/helpers/init/initial-increment-generator.d.ts.map +1 -0
  7. package/dist/src/cli/helpers/init/initial-increment-generator.js +240 -0
  8. package/dist/src/cli/helpers/init/initial-increment-generator.js.map +1 -0
  9. package/dist/src/generators/spec/spec-parser.d.ts +79 -0
  10. package/dist/src/generators/spec/spec-parser.d.ts.map +1 -0
  11. package/dist/src/generators/spec/spec-parser.js +185 -0
  12. package/dist/src/generators/spec/spec-parser.js.map +1 -0
  13. package/dist/src/generators/spec/task-parser.d.ts +95 -0
  14. package/dist/src/generators/spec/task-parser.d.ts.map +1 -0
  15. package/dist/src/generators/spec/task-parser.js +301 -0
  16. package/dist/src/generators/spec/task-parser.js.map +1 -0
  17. package/dist/src/validators/ac-coverage-validator.d.ts +106 -0
  18. package/dist/src/validators/ac-coverage-validator.d.ts.map +1 -0
  19. package/dist/src/validators/ac-coverage-validator.js +250 -0
  20. package/dist/src/validators/ac-coverage-validator.js.map +1 -0
  21. package/package.json +2 -2
  22. package/plugins/specweave/commands/specweave-done.md +58 -0
  23. package/plugins/specweave/commands/specweave-validate.md +36 -6
  24. package/plugins/specweave/lib/hooks/sync-living-docs.js +21 -0
  25. package/plugins/specweave/lib/hooks/sync-us-tasks.js +290 -0
  26. package/src/templates/AGENTS.md.template +16 -0
  27. 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":"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"}
@@ -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"}