gsd-pi 2.35.0-dev.30eec3f → 2.35.0-dev.39eee32
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/resources/extensions/gsd/milestone-ids.js +3 -2
- package/dist/resources/extensions/gsd/state.js +2 -1
- package/package.json +1 -1
- package/src/resources/extensions/gsd/milestone-ids.ts +3 -2
- package/src/resources/extensions/gsd/state.ts +2 -1
- package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +5 -0
|
@@ -67,8 +67,9 @@ export function findMilestoneIds(basePath) {
|
|
|
67
67
|
.filter((d) => d.isDirectory())
|
|
68
68
|
.map((d) => {
|
|
69
69
|
const match = d.name.match(/^(M\d+(?:-[a-z0-9]{6})?)/);
|
|
70
|
-
return match ? match[1] :
|
|
71
|
-
})
|
|
70
|
+
return match ? match[1] : null;
|
|
71
|
+
})
|
|
72
|
+
.filter((id) => id !== null);
|
|
72
73
|
// Apply custom queue order if available, else fall back to numeric sort
|
|
73
74
|
const customOrder = loadQueueOrder(basePath);
|
|
74
75
|
return sortByQueueOrder(ids, customOrder);
|
|
@@ -33,11 +33,12 @@ export function isValidationTerminal(validationContent) {
|
|
|
33
33
|
const verdict = match[1].match(/verdict:\s*(\S+)/);
|
|
34
34
|
if (!verdict)
|
|
35
35
|
return false;
|
|
36
|
+
const v = verdict[1] === 'passed' ? 'pass' : verdict[1];
|
|
36
37
|
// 'pass' and 'needs-attention' are always terminal.
|
|
37
38
|
// 'needs-remediation' is treated as terminal to prevent infinite loops
|
|
38
39
|
// when no remediation slices exist in the roadmap (#832). The validation
|
|
39
40
|
// report is preserved on disk for manual review.
|
|
40
|
-
return
|
|
41
|
+
return v === 'pass' || v === 'needs-attention' || v === 'needs-remediation';
|
|
41
42
|
}
|
|
42
43
|
const CACHE_TTL_MS = 100;
|
|
43
44
|
let _stateCache = null;
|
package/package.json
CHANGED
|
@@ -80,8 +80,9 @@ export function findMilestoneIds(basePath: string): string[] {
|
|
|
80
80
|
.filter((d) => d.isDirectory())
|
|
81
81
|
.map((d) => {
|
|
82
82
|
const match = d.name.match(/^(M\d+(?:-[a-z0-9]{6})?)/);
|
|
83
|
-
return match ? match[1] :
|
|
84
|
-
})
|
|
83
|
+
return match ? match[1] : null;
|
|
84
|
+
})
|
|
85
|
+
.filter((id): id is string => id !== null);
|
|
85
86
|
|
|
86
87
|
// Apply custom queue order if available, else fall back to numeric sort
|
|
87
88
|
const customOrder = loadQueueOrder(basePath);
|
|
@@ -64,11 +64,12 @@ export function isValidationTerminal(validationContent: string): boolean {
|
|
|
64
64
|
if (!match) return false;
|
|
65
65
|
const verdict = match[1].match(/verdict:\s*(\S+)/);
|
|
66
66
|
if (!verdict) return false;
|
|
67
|
+
const v = verdict[1] === 'passed' ? 'pass' : verdict[1];
|
|
67
68
|
// 'pass' and 'needs-attention' are always terminal.
|
|
68
69
|
// 'needs-remediation' is treated as terminal to prevent infinite loops
|
|
69
70
|
// when no remediation slices exist in the roadmap (#832). The validation
|
|
70
71
|
// report is preserved on disk for manual review.
|
|
71
|
-
return
|
|
72
|
+
return v === 'pass' || v === 'needs-attention' || v === 'needs-remediation';
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
// ─── State Derivation ──────────────────────────────────────────────────────
|
|
@@ -244,6 +244,32 @@ console.log('\n=== E2E: backward compat without QUEUE-ORDER.json ===');
|
|
|
244
244
|
}
|
|
245
245
|
}
|
|
246
246
|
|
|
247
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
248
|
+
// Test: non-milestone directories are filtered out (#1494)
|
|
249
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
250
|
+
|
|
251
|
+
console.log('\n=== E2E: non-milestone directories filtered from findMilestoneIds (#1494) ===');
|
|
252
|
+
{
|
|
253
|
+
const base = createFixtureBase();
|
|
254
|
+
try {
|
|
255
|
+
writeContext(base, 'M001', '', 'First');
|
|
256
|
+
writeContext(base, 'M002', '', 'Second');
|
|
257
|
+
// Create a rogue non-milestone directory
|
|
258
|
+
mkdirSync(join(base, '.gsd', 'milestones', 'slices'), { recursive: true });
|
|
259
|
+
mkdirSync(join(base, '.gsd', 'milestones', 'temp-backup'), { recursive: true });
|
|
260
|
+
|
|
261
|
+
invalidateStateCache();
|
|
262
|
+
const ids = findMilestoneIds(base);
|
|
263
|
+
assertEq(ids.length, 2, 'only M001 and M002 returned');
|
|
264
|
+
assertTrue(!ids.includes('slices'), 'slices directory excluded');
|
|
265
|
+
assertTrue(!ids.includes('temp-backup'), 'temp-backup directory excluded');
|
|
266
|
+
assertTrue(ids.includes('M001'), 'M001 included');
|
|
267
|
+
assertTrue(ids.includes('M002'), 'M002 included');
|
|
268
|
+
} finally {
|
|
269
|
+
cleanup(base);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
247
273
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
248
274
|
// Test: depends_on inline array format removal
|
|
249
275
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -104,6 +104,11 @@ test("isValidationTerminal returns true for verdict: needs-remediation (#832)",
|
|
|
104
104
|
assert.equal(isValidationTerminal(content), true);
|
|
105
105
|
});
|
|
106
106
|
|
|
107
|
+
test("isValidationTerminal returns true for verdict: passed (#1429)", () => {
|
|
108
|
+
const content = "---\nverdict: passed\nremediation_round: 0\n---\n\n# Validation";
|
|
109
|
+
assert.equal(isValidationTerminal(content), true);
|
|
110
|
+
});
|
|
111
|
+
|
|
107
112
|
test("isValidationTerminal returns false for missing frontmatter", () => {
|
|
108
113
|
const content = "# Validation\nNo frontmatter here.";
|
|
109
114
|
assert.equal(isValidationTerminal(content), false);
|