specweave 0.28.17 → 0.28.19
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/dist/plugins/specweave-ado/lib/ado-board-resolver.d.ts +94 -0
- package/dist/plugins/specweave-ado/lib/ado-board-resolver.d.ts.map +1 -0
- package/dist/plugins/specweave-ado/lib/ado-board-resolver.js +219 -0
- package/dist/plugins/specweave-ado/lib/ado-board-resolver.js.map +1 -0
- package/dist/plugins/specweave-github/lib/github-feature-sync.d.ts +6 -11
- package/dist/plugins/specweave-github/lib/github-feature-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-feature-sync.js +6 -11
- package/dist/plugins/specweave-github/lib/github-feature-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-increment-sync-cli.d.ts +19 -0
- package/dist/plugins/specweave-github/lib/github-increment-sync-cli.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/github-increment-sync-cli.js +380 -0
- package/dist/plugins/specweave-github/lib/github-increment-sync-cli.js.map +1 -0
- package/dist/plugins/specweave-github/lib/increment-issue-builder.d.ts +92 -0
- package/dist/plugins/specweave-github/lib/increment-issue-builder.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/increment-issue-builder.js +349 -0
- package/dist/plugins/specweave-github/lib/increment-issue-builder.js.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-board-resolver.d.ts +50 -0
- package/dist/plugins/specweave-jira/lib/jira-board-resolver.d.ts.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-board-resolver.js +84 -0
- package/dist/plugins/specweave-jira/lib/jira-board-resolver.js.map +1 -0
- package/dist/src/cli/commands/import-external.d.ts.map +1 -1
- package/dist/src/cli/commands/import-external.js +12 -7
- package/dist/src/cli/commands/import-external.js.map +1 -1
- package/dist/src/cli/helpers/init/external-import.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/external-import.js +122 -17
- package/dist/src/cli/helpers/init/external-import.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/ado-area-selection.d.ts +65 -0
- package/dist/src/cli/helpers/issue-tracker/ado-area-selection.d.ts.map +1 -0
- package/dist/src/cli/helpers/issue-tracker/ado-area-selection.js +278 -0
- package/dist/src/cli/helpers/issue-tracker/ado-area-selection.js.map +1 -0
- package/dist/src/cli/helpers/issue-tracker/jira-board-selection.d.ts +64 -0
- package/dist/src/cli/helpers/issue-tracker/jira-board-selection.d.ts.map +1 -0
- package/dist/src/cli/helpers/issue-tracker/jira-board-selection.js +251 -0
- package/dist/src/cli/helpers/issue-tracker/jira-board-selection.js.map +1 -0
- package/dist/src/core/ac-test-validator-cli.js +4 -1
- package/dist/src/core/ac-test-validator-cli.js.map +1 -1
- package/dist/src/core/ac-test-validator.d.ts.map +1 -1
- package/dist/src/core/ac-test-validator.js +4 -1
- package/dist/src/core/ac-test-validator.js.map +1 -1
- package/dist/src/core/types/increment-metadata.d.ts +75 -0
- package/dist/src/core/types/increment-metadata.d.ts.map +1 -1
- package/dist/src/core/types/sync-profile.d.ts +137 -5
- package/dist/src/core/types/sync-profile.d.ts.map +1 -1
- package/dist/src/core/types/sync-profile.js +63 -0
- package/dist/src/core/types/sync-profile.js.map +1 -1
- package/dist/src/importers/external-importer.d.ts +25 -0
- package/dist/src/importers/external-importer.d.ts.map +1 -1
- package/dist/src/importers/github-importer.d.ts.map +1 -1
- package/dist/src/importers/github-importer.js +5 -3
- package/dist/src/importers/github-importer.js.map +1 -1
- package/dist/src/importers/item-converter.d.ts +51 -0
- package/dist/src/importers/item-converter.d.ts.map +1 -1
- package/dist/src/importers/item-converter.js +39 -12
- package/dist/src/importers/item-converter.js.map +1 -1
- package/dist/src/init/repo/types.d.ts +1 -1
- package/dist/src/living-docs/fs-id-allocator.d.ts +72 -3
- package/dist/src/living-docs/fs-id-allocator.d.ts.map +1 -1
- package/dist/src/living-docs/fs-id-allocator.js +142 -16
- package/dist/src/living-docs/fs-id-allocator.js.map +1 -1
- package/dist/src/locales/de/cli.json +14 -0
- package/dist/src/locales/es/cli.json +14 -0
- package/dist/src/locales/fr/cli.json +14 -0
- package/dist/src/locales/ja/cli.json +14 -0
- package/dist/src/locales/ko/cli.json +14 -0
- package/dist/src/locales/pt/cli.json +14 -0
- package/dist/src/locales/ru/cli.json +14 -0
- package/dist/src/locales/zh/cli.json +14 -0
- package/dist/src/utils/chalk-fallback.d.ts +38 -0
- package/dist/src/utils/chalk-fallback.d.ts.map +1 -0
- package/dist/src/utils/chalk-fallback.js +118 -0
- package/dist/src/utils/chalk-fallback.js.map +1 -0
- package/dist/src/utils/project-id-generator.d.ts +127 -0
- package/dist/src/utils/project-id-generator.d.ts.map +1 -0
- package/dist/src/utils/project-id-generator.js +228 -0
- package/dist/src/utils/project-id-generator.js.map +1 -0
- package/package.json +1 -1
- package/plugins/specweave/agents/pm/AGENT.md +202 -0
- package/plugins/specweave/commands/specweave-import-external.md +5 -3
- package/plugins/specweave/commands/specweave-sync-docs.md +6 -2
- package/plugins/specweave/hooks/pre-task-completion.sh +35 -17
- package/plugins/specweave/lib/vendor/core/ac-test-validator-cli.d.ts +16 -0
- package/plugins/specweave/lib/vendor/core/ac-test-validator-cli.js +121 -0
- package/plugins/specweave/lib/vendor/core/ac-test-validator-cli.js.map +1 -0
- package/plugins/specweave/lib/vendor/core/ac-test-validator.d.ts +111 -0
- package/plugins/specweave/lib/vendor/core/ac-test-validator.js +295 -0
- package/plugins/specweave/lib/vendor/core/ac-test-validator.js.map +1 -0
- package/plugins/specweave/lib/vendor/core/types/increment-metadata.d.ts +75 -0
- package/plugins/specweave/lib/vendor/utils/chalk-fallback.d.ts +38 -0
- package/plugins/specweave/lib/vendor/utils/chalk-fallback.js +118 -0
- package/plugins/specweave/lib/vendor/utils/chalk-fallback.js.map +1 -0
- package/plugins/specweave/lib/vendor/utils/fs-native.d.ts +179 -0
- package/plugins/specweave/lib/vendor/utils/fs-native.js +319 -0
- package/plugins/specweave/lib/vendor/utils/fs-native.js.map +1 -0
- package/plugins/specweave/skills/code-reviewer/SKILL.md +1 -1
- package/plugins/specweave/skills/docs-updater/SKILL.md +61 -0
- package/plugins/specweave/skills/increment-planner/SKILL.md +10 -335
- package/plugins/specweave/skills/increment-planner/templates/metadata.json +13 -0
- package/plugins/specweave/skills/increment-planner/templates/plan.md +50 -0
- package/plugins/specweave/skills/increment-planner/templates/spec-multi-project.md +86 -0
- package/plugins/specweave/skills/increment-planner/templates/spec-single-project.md +50 -0
- package/plugins/specweave/skills/increment-planner/templates/tasks-multi-project.md +86 -0
- package/plugins/specweave/skills/increment-planner/templates/tasks-single-project.md +48 -0
- package/plugins/specweave-ado/commands/specweave-ado-import-areas.md +358 -0
- package/plugins/specweave-alternatives/skills/architecture-alternatives/SKILL.md +1 -0
- package/plugins/specweave-alternatives/skills/bmad-method/SKILL.md +1 -0
- package/plugins/specweave-core/skills/code-quality/SKILL.md +1 -0
- package/plugins/specweave-core/skills/design-patterns/SKILL.md +1 -0
- package/plugins/specweave-core/skills/software-architecture/SKILL.md +1 -0
- package/plugins/specweave-github/commands/specweave-github-cleanup-duplicates.md +14 -10
- package/plugins/specweave-github/commands/specweave-github-sync.md +57 -0
- package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +68 -0
- package/plugins/specweave-github/lib/github-feature-sync.ts +6 -11
- package/plugins/specweave-github/lib/github-increment-sync-cli.js +343 -0
- package/plugins/specweave-github/lib/github-increment-sync-cli.ts +484 -0
- package/plugins/specweave-github/lib/increment-issue-builder.js +368 -0
- package/plugins/specweave-github/lib/increment-issue-builder.ts +471 -0
- package/plugins/specweave-github/skills/github-issue-standard/SKILL.md +19 -24
- package/plugins/specweave-infrastructure/agents/observability-engineer/AGENT.md +15 -23
- package/plugins/specweave-jira/commands/specweave-jira-import-boards.md +331 -0
- package/plugins/specweave-ml/agents/data-scientist/AGENT.md +16 -20
- package/plugins/specweave-ml/agents/ml-engineer/AGENT.md +18 -19
- package/plugins/specweave-ml/skills/{ml-pipeline-workflow → mlops-dag-builder}/SKILL.md +18 -14
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +102 -0
- package/plugins/specweave-ui/skills/browser-automation/SKILL.md +1 -1
- package/plugins/specweave-ui/skills/ui-testing/SKILL.md +10 -122
- package/dist/plugins/specweave-github/lib/epic-content-builder.d.ts +0 -70
- package/dist/plugins/specweave-github/lib/epic-content-builder.d.ts.map +0 -1
- package/dist/plugins/specweave-github/lib/epic-content-builder.js +0 -258
- package/dist/plugins/specweave-github/lib/epic-content-builder.js.map +0 -1
- package/dist/plugins/specweave-github/lib/github-epic-sync.d.ts +0 -83
- package/dist/plugins/specweave-github/lib/github-epic-sync.d.ts.map +0 -1
- package/dist/plugins/specweave-github/lib/github-epic-sync.js +0 -466
- package/dist/plugins/specweave-github/lib/github-epic-sync.js.map +0 -1
- package/plugins/specweave-github/lib/epic-content-builder.js +0 -265
- package/plugins/specweave-github/lib/epic-content-builder.ts +0 -376
- package/plugins/specweave-github/lib/github-epic-sync.js +0 -488
- package/plugins/specweave-github/lib/github-epic-sync.ts +0 -715
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AC Test Validator
|
|
3
|
+
*
|
|
4
|
+
* Validates that all Acceptance Criteria linked to a task have passing tests
|
|
5
|
+
* before allowing the task to be marked complete.
|
|
6
|
+
*
|
|
7
|
+
* **CRITICAL QUALITY GATE**: This is the enforcement point that prevents
|
|
8
|
+
* tasks from being marked complete without validated ACs.
|
|
9
|
+
*
|
|
10
|
+
* Workflow:
|
|
11
|
+
* 1. Task completion requested via TodoWrite
|
|
12
|
+
* 2. Validator extracts task's satisfiesACs field
|
|
13
|
+
* 3. Validator finds corresponding test files from Test Plan section
|
|
14
|
+
* 4. Validator runs tests using configured test runner (vitest/jest)
|
|
15
|
+
* 5. If ALL tests pass → Allow completion, auto-check ACs in spec.md
|
|
16
|
+
* 6. If ANY test fails → Block completion, show detailed error
|
|
17
|
+
*/
|
|
18
|
+
import { exec } from 'child_process';
|
|
19
|
+
import { promisify } from 'util';
|
|
20
|
+
import path from 'path';
|
|
21
|
+
import * as fs from '../utils/fs-native.js';
|
|
22
|
+
import chalkFallback, { getChalk } from '../utils/chalk-fallback.js';
|
|
23
|
+
// Use chalk if available, otherwise fallback to ANSI codes
|
|
24
|
+
let chalk = chalkFallback;
|
|
25
|
+
getChalk().then(c => { chalk = c; }).catch(() => { });
|
|
26
|
+
const execAsync = promisify(exec);
|
|
27
|
+
/**
|
|
28
|
+
* AC Test Validator - Core validation engine
|
|
29
|
+
*/
|
|
30
|
+
export class ACTestValidator {
|
|
31
|
+
constructor(config) {
|
|
32
|
+
this.config = {
|
|
33
|
+
timeout: 30000, // 30 second default timeout
|
|
34
|
+
...config
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Validate all ACs for a task have passing tests
|
|
39
|
+
*
|
|
40
|
+
* @param task - Task to validate (must have satisfiesACs field)
|
|
41
|
+
* @param projectRoot - Project root directory
|
|
42
|
+
* @returns Validation result
|
|
43
|
+
*/
|
|
44
|
+
async validateTask(task, projectRoot) {
|
|
45
|
+
const startTime = Date.now();
|
|
46
|
+
// Initialize result
|
|
47
|
+
const result = {
|
|
48
|
+
passed: false,
|
|
49
|
+
taskId: task.id,
|
|
50
|
+
acIds: task.satisfiesACs || [],
|
|
51
|
+
testResults: new Map(),
|
|
52
|
+
summary: {
|
|
53
|
+
totalACs: 0,
|
|
54
|
+
acsTested: 0,
|
|
55
|
+
acsUntested: 0,
|
|
56
|
+
testsPassed: 0,
|
|
57
|
+
testsFailed: 0
|
|
58
|
+
},
|
|
59
|
+
errors: []
|
|
60
|
+
};
|
|
61
|
+
// Check if task has ACs to validate
|
|
62
|
+
if (!task.satisfiesACs || task.satisfiesACs.length === 0) {
|
|
63
|
+
result.errors.push(`Task ${task.id} has no Acceptance Criteria linked (satisfiesACs field missing or empty)`);
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
result.summary.totalACs = task.satisfiesACs.length;
|
|
67
|
+
// Extract test file from task's Test Plan section
|
|
68
|
+
const testFile = this.extractTestFile(task);
|
|
69
|
+
if (!testFile) {
|
|
70
|
+
result.errors.push(`Task ${task.id} has no Test Plan section or test file specified`);
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
// Check test file exists
|
|
74
|
+
const testFilePath = path.join(projectRoot, testFile);
|
|
75
|
+
if (!await fs.pathExists(testFilePath)) {
|
|
76
|
+
result.errors.push(`Test file not found: ${testFile}`);
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
// Run tests for each AC
|
|
80
|
+
for (const acId of task.satisfiesACs) {
|
|
81
|
+
const acTestResult = await this.validateAC(acId, testFile, projectRoot);
|
|
82
|
+
result.testResults.set(acId, acTestResult);
|
|
83
|
+
if (acTestResult.passed) {
|
|
84
|
+
result.summary.acsTested++;
|
|
85
|
+
result.summary.testsPassed++;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
result.summary.acsUntested++;
|
|
89
|
+
result.summary.testsFailed++;
|
|
90
|
+
result.errors.push(`AC ${acId} tests failed: ${acTestResult.error || 'Unknown error'}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Overall pass/fail
|
|
94
|
+
result.passed = result.summary.testsFailed === 0 && result.summary.acsTested === result.summary.totalACs;
|
|
95
|
+
const duration = Date.now() - startTime;
|
|
96
|
+
console.log(`\n${chalk.blue('[AC Test Validator]')} Validated task ${task.id} in ${duration}ms`);
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Validate a single AC has passing tests
|
|
101
|
+
*/
|
|
102
|
+
async validateAC(acId, testFile, projectRoot) {
|
|
103
|
+
const startTime = Date.now();
|
|
104
|
+
const result = {
|
|
105
|
+
acId,
|
|
106
|
+
testFile,
|
|
107
|
+
testCases: [],
|
|
108
|
+
passed: false,
|
|
109
|
+
duration: 0
|
|
110
|
+
};
|
|
111
|
+
try {
|
|
112
|
+
// Run test file with filter for AC-ID
|
|
113
|
+
// Most test runners support filtering: vitest -t "AC-US1-01", jest --testNamePattern="AC-US1-01"
|
|
114
|
+
const command = this.buildTestCommand(testFile, acId);
|
|
115
|
+
console.log(` ${chalk.gray('Running:')} ${command}`);
|
|
116
|
+
const { stdout, stderr } = await execAsync(command, {
|
|
117
|
+
cwd: this.config.cwd,
|
|
118
|
+
env: { ...process.env, ...this.config.env },
|
|
119
|
+
timeout: this.config.timeout
|
|
120
|
+
});
|
|
121
|
+
// Parse test output (basic implementation - can be enhanced)
|
|
122
|
+
const output = stdout + stderr;
|
|
123
|
+
result.testCases = this.extractTestCases(output, acId);
|
|
124
|
+
// Check for test failures
|
|
125
|
+
const hasFailures = output.includes('FAIL') ||
|
|
126
|
+
output.includes('failed') ||
|
|
127
|
+
output.includes('✗') ||
|
|
128
|
+
output.includes('0 passed');
|
|
129
|
+
result.passed = !hasFailures && result.testCases.length > 0;
|
|
130
|
+
if (!result.passed) {
|
|
131
|
+
result.error = this.extractFailureMessage(output);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
result.passed = false;
|
|
136
|
+
result.error = error.message || 'Test execution failed';
|
|
137
|
+
// Check if it's a timeout
|
|
138
|
+
if (error.killed && error.signal === 'SIGTERM') {
|
|
139
|
+
result.error = `Test timeout (exceeded ${this.config.timeout}ms)`;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
result.duration = Date.now() - startTime;
|
|
143
|
+
return result;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Build test command with AC-ID filter
|
|
147
|
+
*/
|
|
148
|
+
buildTestCommand(testFile, acId) {
|
|
149
|
+
// Detect test runner from config command
|
|
150
|
+
const command = this.config.command.toLowerCase();
|
|
151
|
+
if (command.includes('vitest')) {
|
|
152
|
+
// Vitest: vitest run <file> -t "AC-US1-01"
|
|
153
|
+
return `${this.config.command} ${testFile} -t "${acId}"`;
|
|
154
|
+
}
|
|
155
|
+
else if (command.includes('jest')) {
|
|
156
|
+
// Jest: jest <file> --testNamePattern="AC-US1-01"
|
|
157
|
+
return `${this.config.command} ${testFile} --testNamePattern="${acId}"`;
|
|
158
|
+
}
|
|
159
|
+
else if (command.includes('npm test')) {
|
|
160
|
+
// NPM script - try to pass args
|
|
161
|
+
return `${this.config.command} -- ${testFile} -t "${acId}"`;
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
// Default: assume vitest-style
|
|
165
|
+
return `${this.config.command} ${testFile} -t "${acId}"`;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Extract test case names from test output
|
|
170
|
+
*/
|
|
171
|
+
extractTestCases(output, acId) {
|
|
172
|
+
const testCases = [];
|
|
173
|
+
// Look for lines containing the AC-ID and test indicators
|
|
174
|
+
const lines = output.split('\n');
|
|
175
|
+
for (const line of lines) {
|
|
176
|
+
if (line.includes(acId) && (line.includes('✓') || line.includes('PASS') || line.includes('√'))) {
|
|
177
|
+
// Extract test name (basic heuristic)
|
|
178
|
+
const match = line.match(/✓\s+(.+)/) || line.match(/PASS\s+(.+)/);
|
|
179
|
+
if (match) {
|
|
180
|
+
testCases.push(match[1].trim());
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return testCases;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Extract failure message from test output
|
|
188
|
+
*/
|
|
189
|
+
extractFailureMessage(output) {
|
|
190
|
+
const lines = output.split('\n');
|
|
191
|
+
// Find first error/failure message
|
|
192
|
+
for (let i = 0; i < lines.length; i++) {
|
|
193
|
+
const line = lines[i];
|
|
194
|
+
if (line.includes('FAIL') || line.includes('✗') || line.includes('Error:')) {
|
|
195
|
+
// Collect next few lines for context
|
|
196
|
+
const errorLines = lines.slice(i, i + 5).join('\n');
|
|
197
|
+
return errorLines.substring(0, 200); // Truncate long messages
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
// Fallback: return last few lines
|
|
201
|
+
return lines.slice(-5).join('\n');
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Extract test file path from task description (Test Plan section)
|
|
205
|
+
*/
|
|
206
|
+
extractTestFile(task) {
|
|
207
|
+
if (!task.description)
|
|
208
|
+
return null;
|
|
209
|
+
// Look for Test Plan section with file path
|
|
210
|
+
// Format: **Test Plan**:
|
|
211
|
+
// - **File**: `tests/unit/component.test.ts`
|
|
212
|
+
const testFileRegex = /\*\*File\*\*:\s*`([^`]+)`/;
|
|
213
|
+
const match = task.description.match(testFileRegex);
|
|
214
|
+
return match ? match[1] : null;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Format validation result for display
|
|
218
|
+
*/
|
|
219
|
+
formatResult(result) {
|
|
220
|
+
const lines = [];
|
|
221
|
+
lines.push(chalk.bold(`\nAC Test Validation: ${result.taskId}`));
|
|
222
|
+
lines.push(chalk.gray('─'.repeat(60)));
|
|
223
|
+
// Summary
|
|
224
|
+
lines.push(chalk.bold('Summary:'));
|
|
225
|
+
lines.push(` Total ACs: ${result.summary.totalACs}`);
|
|
226
|
+
lines.push(` ACs Tested: ${chalk.green(result.summary.acsTested)}`);
|
|
227
|
+
lines.push(` ACs Untested: ${chalk.red(result.summary.acsUntested)}`);
|
|
228
|
+
lines.push(` Tests Passed: ${chalk.green(result.summary.testsPassed)}`);
|
|
229
|
+
lines.push(` Tests Failed: ${chalk.red(result.summary.testsFailed)}`);
|
|
230
|
+
// Overall status
|
|
231
|
+
lines.push('');
|
|
232
|
+
if (result.passed) {
|
|
233
|
+
lines.push(chalk.green.bold('✓ VALIDATION PASSED'));
|
|
234
|
+
lines.push(chalk.green('All Acceptance Criteria have passing tests. Task can be marked complete.'));
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
lines.push(chalk.red.bold('✗ VALIDATION FAILED'));
|
|
238
|
+
lines.push(chalk.red('Task cannot be marked complete until all AC tests pass.'));
|
|
239
|
+
}
|
|
240
|
+
// Errors
|
|
241
|
+
if (result.errors.length > 0) {
|
|
242
|
+
lines.push('');
|
|
243
|
+
lines.push(chalk.bold('Errors:'));
|
|
244
|
+
result.errors.forEach(error => {
|
|
245
|
+
lines.push(chalk.red(` • ${error}`));
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
// Test details
|
|
249
|
+
if (result.testResults.size > 0) {
|
|
250
|
+
lines.push('');
|
|
251
|
+
lines.push(chalk.bold('Test Results:'));
|
|
252
|
+
result.testResults.forEach((acResult, acId) => {
|
|
253
|
+
const icon = acResult.passed ? chalk.green('✓') : chalk.red('✗');
|
|
254
|
+
const status = acResult.passed ? chalk.green('PASSED') : chalk.red('FAILED');
|
|
255
|
+
lines.push(` ${icon} ${acId}: ${status} (${acResult.duration}ms)`);
|
|
256
|
+
if (acResult.testCases.length > 0) {
|
|
257
|
+
acResult.testCases.forEach(testCase => {
|
|
258
|
+
lines.push(chalk.gray(` - ${testCase}`));
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
if (acResult.error) {
|
|
262
|
+
lines.push(chalk.red(` Error: ${acResult.error}`));
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
lines.push(chalk.gray('─'.repeat(60)));
|
|
267
|
+
return lines.join('\n');
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Create AC test validator from project config
|
|
272
|
+
*/
|
|
273
|
+
export async function createACTestValidator(projectRoot) {
|
|
274
|
+
// Read test configuration from package.json or specweave config
|
|
275
|
+
const packageJsonPath = path.join(projectRoot, 'package.json');
|
|
276
|
+
let testCommand = 'npm test';
|
|
277
|
+
if (await fs.pathExists(packageJsonPath)) {
|
|
278
|
+
const packageJson = await fs.readJson(packageJsonPath);
|
|
279
|
+
// Detect test runner
|
|
280
|
+
if (packageJson.devDependencies?.vitest || packageJson.dependencies?.vitest) {
|
|
281
|
+
testCommand = 'npx vitest run';
|
|
282
|
+
}
|
|
283
|
+
else if (packageJson.devDependencies?.jest || packageJson.dependencies?.jest) {
|
|
284
|
+
testCommand = 'npx jest';
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
const config = {
|
|
288
|
+
command: testCommand,
|
|
289
|
+
pattern: 'tests/**/*.test.ts',
|
|
290
|
+
cwd: projectRoot,
|
|
291
|
+
timeout: 30000
|
|
292
|
+
};
|
|
293
|
+
return new ACTestValidator(config);
|
|
294
|
+
}
|
|
295
|
+
//# sourceMappingURL=ac-test-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ac-test-validator.js","sourceRoot":"","sources":["../../../src/core/ac-test-validator.ts"],"names":[],"mappings":"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"}
|
|
@@ -154,4 +154,79 @@ export declare function countsTowardWipLimit(status: IncrementStatus): boolean;
|
|
|
154
154
|
* @throws Error if transition is invalid
|
|
155
155
|
*/
|
|
156
156
|
export declare function validateTransition(from: IncrementStatus, to: IncrementStatus): void;
|
|
157
|
+
/**
|
|
158
|
+
* Project scope for a multi-project user story
|
|
159
|
+
* Defines what portion of the work belongs to each project
|
|
160
|
+
*/
|
|
161
|
+
export interface MultiProjectScope {
|
|
162
|
+
/** SpecWeave project ID (e.g., "FE", "BE", "Shared") */
|
|
163
|
+
id: string;
|
|
164
|
+
/** Description of work scope for this project */
|
|
165
|
+
scope: string;
|
|
166
|
+
/** Keywords for this project's portion (for auto-classification) */
|
|
167
|
+
keywords?: string[];
|
|
168
|
+
/** Estimated effort percentage (0-100) */
|
|
169
|
+
effortPercentage?: number;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Cross-project dependency
|
|
173
|
+
* Defines dependencies between projects within a user story
|
|
174
|
+
*/
|
|
175
|
+
export interface CrossProjectDependency {
|
|
176
|
+
/** Project that depends on another */
|
|
177
|
+
from: string;
|
|
178
|
+
/** Project being depended upon */
|
|
179
|
+
to: string;
|
|
180
|
+
/** Description of the dependency */
|
|
181
|
+
reason: string;
|
|
182
|
+
/** Type of dependency */
|
|
183
|
+
type?: 'blocking' | 'soft' | 'interface';
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Multi-project user story configuration
|
|
187
|
+
* Used when a single user story spans multiple SpecWeave projects
|
|
188
|
+
*/
|
|
189
|
+
export interface MultiProjectUserStory {
|
|
190
|
+
/** List of projects this user story touches */
|
|
191
|
+
projects: MultiProjectScope[];
|
|
192
|
+
/** Dependencies between projects (optional) */
|
|
193
|
+
dependencies?: CrossProjectDependency[];
|
|
194
|
+
/** Primary project (receives the main spec, others get derived specs) */
|
|
195
|
+
primaryProject?: string;
|
|
196
|
+
/** How to handle sync - create linked issues in each project's external tool */
|
|
197
|
+
syncStrategy?: 'linked' | 'primary-only' | 'all';
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* External container context for 2-level directory structure
|
|
201
|
+
* Used for JIRA boards / ADO area paths mapping
|
|
202
|
+
*/
|
|
203
|
+
export interface ExternalContainerContext {
|
|
204
|
+
/** Container type (e.g., "jira-project", "ado-project") */
|
|
205
|
+
type: 'jira-project' | 'ado-project' | 'github-org';
|
|
206
|
+
/** External container ID (e.g., "CORE" for JIRA, "MyProduct" for ADO) */
|
|
207
|
+
containerId: string;
|
|
208
|
+
/** Display name */
|
|
209
|
+
containerName: string;
|
|
210
|
+
/** Board ID (JIRA only) */
|
|
211
|
+
boardId?: number;
|
|
212
|
+
/** Board name (JIRA only) */
|
|
213
|
+
boardName?: string;
|
|
214
|
+
/** Area path (ADO only) */
|
|
215
|
+
areaPath?: string;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Extended increment metadata with multi-project support (v0.29.0+)
|
|
219
|
+
*/
|
|
220
|
+
export interface IncrementMetadataV2 extends IncrementMetadata {
|
|
221
|
+
/** Single project ID (backward compatible) */
|
|
222
|
+
projectId?: string;
|
|
223
|
+
/** Multi-project configuration (v0.29.0+, overrides projectId if set) */
|
|
224
|
+
multiProject?: MultiProjectUserStory;
|
|
225
|
+
/** External container context for 2-level directory structure */
|
|
226
|
+
externalContainer?: ExternalContainerContext;
|
|
227
|
+
/** Feature ID this increment belongs to */
|
|
228
|
+
featureId?: string;
|
|
229
|
+
/** Epic ID if part of an epic */
|
|
230
|
+
epicId?: string;
|
|
231
|
+
}
|
|
157
232
|
//# sourceMappingURL=increment-metadata.d.ts.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chalk Fallback Utility
|
|
3
|
+
*
|
|
4
|
+
* Provides chalk-like API for colored console output with graceful fallback
|
|
5
|
+
* to plain text when chalk is not available (e.g., in marketplace plugins).
|
|
6
|
+
*
|
|
7
|
+
* This enables AC test validator to work in both:
|
|
8
|
+
* 1. Full npm-installed environments (uses real chalk)
|
|
9
|
+
* 2. Marketplace plugin environments (uses ANSI codes or plain text)
|
|
10
|
+
*/
|
|
11
|
+
type ChalkInput = string | number;
|
|
12
|
+
interface ChalkFn {
|
|
13
|
+
(text: ChalkInput): string;
|
|
14
|
+
bold: ChalkFn;
|
|
15
|
+
}
|
|
16
|
+
interface ChalkInstance {
|
|
17
|
+
red: ChalkFn;
|
|
18
|
+
green: ChalkFn;
|
|
19
|
+
yellow: ChalkFn;
|
|
20
|
+
blue: ChalkFn;
|
|
21
|
+
gray: ChalkFn;
|
|
22
|
+
bold: ChalkFn & {
|
|
23
|
+
(text: string): string;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Chalk-compatible API using ANSI codes
|
|
28
|
+
* Falls back to plain text if terminal doesn't support colors
|
|
29
|
+
*/
|
|
30
|
+
export declare const chalkFallback: ChalkInstance;
|
|
31
|
+
export declare function getChalk(): Promise<ChalkInstance>;
|
|
32
|
+
/**
|
|
33
|
+
* Synchronous chalk getter - uses fallback if chalk wasn't pre-loaded
|
|
34
|
+
* Call getChalk() at module init to try loading real chalk first
|
|
35
|
+
*/
|
|
36
|
+
export declare function getChalkSync(): ChalkInstance;
|
|
37
|
+
export default chalkFallback;
|
|
38
|
+
//# sourceMappingURL=chalk-fallback.d.ts.map
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chalk Fallback Utility
|
|
3
|
+
*
|
|
4
|
+
* Provides chalk-like API for colored console output with graceful fallback
|
|
5
|
+
* to plain text when chalk is not available (e.g., in marketplace plugins).
|
|
6
|
+
*
|
|
7
|
+
* This enables AC test validator to work in both:
|
|
8
|
+
* 1. Full npm-installed environments (uses real chalk)
|
|
9
|
+
* 2. Marketplace plugin environments (uses ANSI codes or plain text)
|
|
10
|
+
*/
|
|
11
|
+
// Simple ANSI color codes for terminal output
|
|
12
|
+
const ANSI = {
|
|
13
|
+
reset: '\x1b[0m',
|
|
14
|
+
bold: '\x1b[1m',
|
|
15
|
+
red: '\x1b[31m',
|
|
16
|
+
green: '\x1b[32m',
|
|
17
|
+
yellow: '\x1b[33m',
|
|
18
|
+
blue: '\x1b[34m',
|
|
19
|
+
gray: '\x1b[90m',
|
|
20
|
+
};
|
|
21
|
+
// Check if we're in a TTY that supports colors
|
|
22
|
+
const supportsColor = process.stdout?.isTTY ?? false;
|
|
23
|
+
/**
|
|
24
|
+
* Creates a chalk-like color function
|
|
25
|
+
*/
|
|
26
|
+
function createColorFn(colorCode) {
|
|
27
|
+
const fn = ((text) => {
|
|
28
|
+
const str = String(text);
|
|
29
|
+
if (!supportsColor)
|
|
30
|
+
return str;
|
|
31
|
+
return `${colorCode}${str}${ANSI.reset}`;
|
|
32
|
+
});
|
|
33
|
+
// Add chainable modifiers
|
|
34
|
+
fn.bold = ((text) => {
|
|
35
|
+
const str = String(text);
|
|
36
|
+
if (!supportsColor)
|
|
37
|
+
return str;
|
|
38
|
+
return `${ANSI.bold}${colorCode}${str}${ANSI.reset}`;
|
|
39
|
+
});
|
|
40
|
+
return fn;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Creates a bold color function
|
|
44
|
+
*/
|
|
45
|
+
function createBoldColorFn(colorCode) {
|
|
46
|
+
const fn = ((text) => {
|
|
47
|
+
const str = String(text);
|
|
48
|
+
if (!supportsColor)
|
|
49
|
+
return str;
|
|
50
|
+
return `${ANSI.bold}${colorCode}${str}${ANSI.reset}`;
|
|
51
|
+
});
|
|
52
|
+
fn.bold = fn;
|
|
53
|
+
return fn;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Chalk-compatible API using ANSI codes
|
|
57
|
+
* Falls back to plain text if terminal doesn't support colors
|
|
58
|
+
*/
|
|
59
|
+
export const chalkFallback = {
|
|
60
|
+
red: createColorFn(ANSI.red),
|
|
61
|
+
green: createColorFn(ANSI.green),
|
|
62
|
+
yellow: createColorFn(ANSI.yellow),
|
|
63
|
+
blue: createColorFn(ANSI.blue),
|
|
64
|
+
gray: createColorFn(ANSI.gray),
|
|
65
|
+
bold: Object.assign(((text) => {
|
|
66
|
+
const str = String(text);
|
|
67
|
+
if (!supportsColor)
|
|
68
|
+
return str;
|
|
69
|
+
return `${ANSI.bold}${str}${ANSI.reset}`;
|
|
70
|
+
}), {
|
|
71
|
+
bold: ((text) => {
|
|
72
|
+
const str = String(text);
|
|
73
|
+
if (!supportsColor)
|
|
74
|
+
return str;
|
|
75
|
+
return `${ANSI.bold}${str}${ANSI.reset}`;
|
|
76
|
+
}),
|
|
77
|
+
}),
|
|
78
|
+
};
|
|
79
|
+
// Add nested color methods to bold
|
|
80
|
+
chalkFallback.bold.red = createBoldColorFn(ANSI.red);
|
|
81
|
+
chalkFallback.bold.green = createBoldColorFn(ANSI.green);
|
|
82
|
+
chalkFallback.bold.yellow = createBoldColorFn(ANSI.yellow);
|
|
83
|
+
chalkFallback.bold.blue = createBoldColorFn(ANSI.blue);
|
|
84
|
+
chalkFallback.bold.gray = createBoldColorFn(ANSI.gray);
|
|
85
|
+
// Add bold method to color functions for chaining like chalk.green.bold()
|
|
86
|
+
chalkFallback.red.bold = createBoldColorFn(ANSI.red);
|
|
87
|
+
chalkFallback.green.bold = createBoldColorFn(ANSI.green);
|
|
88
|
+
chalkFallback.yellow.bold = createBoldColorFn(ANSI.yellow);
|
|
89
|
+
chalkFallback.blue.bold = createBoldColorFn(ANSI.blue);
|
|
90
|
+
chalkFallback.gray.bold = createBoldColorFn(ANSI.gray);
|
|
91
|
+
/**
|
|
92
|
+
* Try to import chalk, fall back to ANSI implementation
|
|
93
|
+
*/
|
|
94
|
+
let resolvedChalk = null;
|
|
95
|
+
export async function getChalk() {
|
|
96
|
+
if (resolvedChalk)
|
|
97
|
+
return resolvedChalk;
|
|
98
|
+
try {
|
|
99
|
+
// Try to dynamically import chalk
|
|
100
|
+
const chalkModule = await import('chalk');
|
|
101
|
+
resolvedChalk = chalkModule.default;
|
|
102
|
+
return resolvedChalk;
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// Chalk not available, use fallback
|
|
106
|
+
resolvedChalk = chalkFallback;
|
|
107
|
+
return resolvedChalk;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Synchronous chalk getter - uses fallback if chalk wasn't pre-loaded
|
|
112
|
+
* Call getChalk() at module init to try loading real chalk first
|
|
113
|
+
*/
|
|
114
|
+
export function getChalkSync() {
|
|
115
|
+
return resolvedChalk ?? chalkFallback;
|
|
116
|
+
}
|
|
117
|
+
export default chalkFallback;
|
|
118
|
+
//# sourceMappingURL=chalk-fallback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chalk-fallback.js","sourceRoot":"","sources":["../../../src/utils/chalk-fallback.ts"],"names":[],"mappings":"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"}
|