gsd-pi 2.44.0-dev.62b5d6c → 2.44.0-dev.a5271fc
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/README.md +30 -12
- package/dist/resources/extensions/gsd/auto-start.js +10 -0
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +46 -12
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +5 -0
- package/dist/resources/extensions/gsd/preferences.js +9 -1
- package/dist/resources/extensions/gsd/state.js +19 -2
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +19 -19
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +19 -19
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js +6 -8
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +24 -26
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/fs-utils.test.js +29 -48
- package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +34 -44
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.test.js +30 -34
- package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +10 -12
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +43 -47
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
- package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
- package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
- package/packages/pi-coding-agent/src/core/fs-utils.test.ts +31 -43
- package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +40 -45
- package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
- package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
- package/src/resources/extensions/gsd/auto-start.ts +14 -0
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +48 -11
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +8 -0
- package/src/resources/extensions/gsd/preferences.ts +11 -1
- package/src/resources/extensions/gsd/state.ts +19 -1
- package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
- package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +14 -16
- package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +43 -57
- package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +11 -13
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +465 -523
- package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +73 -75
- package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +34 -56
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +533 -656
- package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +165 -143
- package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +29 -52
- package/src/resources/extensions/gsd/tests/captures.test.ts +148 -176
- package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +32 -33
- package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +141 -143
- package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +25 -25
- package/src/resources/extensions/gsd/tests/commands-logs.test.ts +81 -81
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +38 -59
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +228 -263
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +250 -302
- package/src/resources/extensions/gsd/tests/context-store.test.ts +354 -367
- package/src/resources/extensions/gsd/tests/continue-here.test.ts +68 -72
- package/src/resources/extensions/gsd/tests/cost-projection.test.ts +92 -106
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +27 -35
- package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +220 -237
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +390 -420
- package/src/resources/extensions/gsd/tests/definition-loader.test.ts +76 -92
- package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +68 -83
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +183 -181
- package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +78 -101
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +192 -227
- package/src/resources/extensions/gsd/tests/detection.test.ts +232 -278
- package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +30 -34
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +164 -180
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +43 -49
- package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +28 -32
- package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +27 -29
- package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +34 -38
- package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +54 -75
- package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +21 -32
- package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +72 -97
- package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +38 -44
- package/src/resources/extensions/gsd/tests/doctor-git.test.ts +104 -145
- package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +84 -106
- package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +54 -60
- package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +72 -93
- package/src/resources/extensions/gsd/tests/doctor.test.ts +104 -134
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +123 -131
- package/src/resources/extensions/gsd/tests/exit-command.test.ts +20 -24
- package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +48 -57
- package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +5 -7
- package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +30 -42
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +198 -206
- package/src/resources/extensions/gsd/tests/git-locale.test.ts +13 -27
- package/src/resources/extensions/gsd/tests/git-service.test.ts +285 -388
- package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +31 -39
- package/src/resources/extensions/gsd/tests/graph-operations.test.ts +63 -69
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +255 -264
- package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +108 -119
- package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +81 -103
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +229 -262
- package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +29 -37
- package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +81 -102
- package/src/resources/extensions/gsd/tests/init-wizard.test.ts +16 -18
- package/src/resources/extensions/gsd/tests/integration-edge.test.ts +41 -46
- package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +42 -53
- package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +75 -91
- package/src/resources/extensions/gsd/tests/integration-proof.test.ts +18 -18
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +150 -194
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +101 -125
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +45 -54
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +80 -93
- package/src/resources/extensions/gsd/tests/migrate-command.test.ts +57 -66
- package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +83 -93
- package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +161 -170
- package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +125 -141
- package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +107 -131
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +87 -96
- package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +125 -164
- package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +81 -94
- package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +35 -36
- package/src/resources/extensions/gsd/tests/overrides.test.ts +99 -106
- package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +40 -47
- package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +25 -28
- package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +66 -83
- package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +54 -77
- package/src/resources/extensions/gsd/tests/park-milestone.test.ts +68 -115
- package/src/resources/extensions/gsd/tests/parsers.test.ts +546 -611
- package/src/resources/extensions/gsd/tests/paths.test.ts +72 -87
- package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +77 -117
- package/src/resources/extensions/gsd/tests/preferences.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
- package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +93 -119
- package/src/resources/extensions/gsd/tests/queue-order.test.ts +70 -82
- package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +42 -55
- package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +100 -0
- package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +45 -73
- package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +28 -38
- package/src/resources/extensions/gsd/tests/replan-slice.test.ts +73 -80
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +71 -74
- package/src/resources/extensions/gsd/tests/requirements.test.ts +70 -75
- package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +44 -66
- package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +114 -181
- package/src/resources/extensions/gsd/tests/rule-registry.test.ts +63 -65
- package/src/resources/extensions/gsd/tests/run-uat.test.ts +66 -128
- package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +18 -25
- package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +37 -44
- package/src/resources/extensions/gsd/tests/shared-wal.test.ts +19 -26
- package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +6 -8
- package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +22 -28
- package/src/resources/extensions/gsd/tests/token-savings.test.ts +54 -56
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +23 -25
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +9 -11
- package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +66 -82
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +46 -47
- package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -22
- package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -86
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +41 -43
- package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +94 -96
- package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +11 -13
- package/src/resources/extensions/gsd/tests/worker-registry.test.ts +27 -29
- package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +50 -52
- package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +10 -13
- package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +14 -18
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +38 -39
- package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +17 -21
- package/src/resources/extensions/gsd/tests/worktree-health.test.ts +25 -30
- package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +30 -37
- package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +15 -22
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +59 -66
- package/src/resources/extensions/gsd/tests/worktree.test.ts +44 -50
- /package/dist/web/standalone/.next/static/{fOnWQBjWXMKUs4bqTg530 → JyimLR2pZuvKEzv26gI3w}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{fOnWQBjWXMKUs4bqTg530 → JyimLR2pZuvKEzv26gI3w}/_ssgManifest.js +0 -0
|
@@ -15,9 +15,9 @@ import {
|
|
|
15
15
|
parseOldState,
|
|
16
16
|
parseOldConfig,
|
|
17
17
|
} from '../migrate/parsers.ts';
|
|
18
|
-
import {
|
|
18
|
+
import { describe, test, beforeEach, afterEach } from 'node:test';
|
|
19
|
+
import assert from 'node:assert/strict';
|
|
19
20
|
|
|
20
|
-
const { assertEq, assertTrue, report } = createTestContext();
|
|
21
21
|
function createFixtureBase(): string {
|
|
22
22
|
return mkdtempSync(join(tmpdir(), 'gsd-migrate-t02-'));
|
|
23
23
|
}
|
|
@@ -173,55 +173,49 @@ const SAMPLE_STATE = `# State
|
|
|
173
173
|
**Status:** in-progress
|
|
174
174
|
`;
|
|
175
175
|
|
|
176
|
-
async function main(): Promise<void> {
|
|
177
|
-
|
|
178
176
|
// ═══════════════════════════════════════════════════════════════════════
|
|
179
177
|
// Validator Tests
|
|
180
178
|
// ═══════════════════════════════════════════════════════════════════════
|
|
181
179
|
|
|
182
|
-
|
|
183
|
-
{
|
|
180
|
+
test('Validator: missing directory → fatal', async () => {
|
|
184
181
|
const base = createFixtureBase();
|
|
185
182
|
try {
|
|
186
183
|
const result = await validatePlanningDirectory(join(base, 'nonexistent'));
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
184
|
+
assert.deepStrictEqual(result.valid, false, 'missing dir: validation fails');
|
|
185
|
+
assert.ok(result.issues.length > 0, 'missing dir: has issues');
|
|
186
|
+
assert.ok(result.issues.some(i => i.severity === 'fatal'), 'missing dir: has fatal issue');
|
|
190
187
|
} finally {
|
|
191
188
|
cleanup(base);
|
|
192
189
|
}
|
|
193
|
-
|
|
190
|
+
});
|
|
194
191
|
|
|
195
|
-
|
|
196
|
-
{
|
|
192
|
+
test('Validator: missing ROADMAP.md → warning (not fatal)', async () => {
|
|
197
193
|
const base = createFixtureBase();
|
|
198
194
|
try {
|
|
199
195
|
const planning = createPlanningDir(base);
|
|
200
196
|
writeFileSync(join(planning, 'PROJECT.md'), SAMPLE_PROJECT);
|
|
201
197
|
const result = await validatePlanningDirectory(planning);
|
|
202
|
-
|
|
203
|
-
|
|
198
|
+
assert.deepStrictEqual(result.valid, true, 'no roadmap: validation still passes');
|
|
199
|
+
assert.ok(result.issues.some(i => i.severity === 'warning' && i.file.includes('ROADMAP')), 'no roadmap: warning issue mentions ROADMAP');
|
|
204
200
|
} finally {
|
|
205
201
|
cleanup(base);
|
|
206
202
|
}
|
|
207
|
-
|
|
203
|
+
});
|
|
208
204
|
|
|
209
|
-
|
|
210
|
-
{
|
|
205
|
+
test('Validator: missing PROJECT.md → warning', async () => {
|
|
211
206
|
const base = createFixtureBase();
|
|
212
207
|
try {
|
|
213
208
|
const planning = createPlanningDir(base);
|
|
214
209
|
writeFileSync(join(planning, 'ROADMAP.md'), SAMPLE_ROADMAP);
|
|
215
210
|
const result = await validatePlanningDirectory(planning);
|
|
216
|
-
|
|
217
|
-
|
|
211
|
+
assert.deepStrictEqual(result.valid, true, 'no project: validation passes (warning only)');
|
|
212
|
+
assert.ok(result.issues.some(i => i.severity === 'warning' && i.file.includes('PROJECT')), 'no project: warning issue mentions PROJECT');
|
|
218
213
|
} finally {
|
|
219
214
|
cleanup(base);
|
|
220
215
|
}
|
|
221
|
-
|
|
216
|
+
});
|
|
222
217
|
|
|
223
|
-
|
|
224
|
-
{
|
|
218
|
+
test('Validator: complete directory → valid with no issues', async () => {
|
|
225
219
|
const base = createFixtureBase();
|
|
226
220
|
try {
|
|
227
221
|
const planning = createPlanningDir(base);
|
|
@@ -231,78 +225,74 @@ async function main(): Promise<void> {
|
|
|
231
225
|
writeFileSync(join(planning, 'STATE.md'), SAMPLE_STATE);
|
|
232
226
|
mkdirSync(join(planning, 'phases'), { recursive: true });
|
|
233
227
|
const result = await validatePlanningDirectory(planning);
|
|
234
|
-
|
|
235
|
-
|
|
228
|
+
assert.deepStrictEqual(result.valid, true, 'complete dir: validation passes');
|
|
229
|
+
assert.deepStrictEqual(result.issues.length, 0, 'complete dir: no issues');
|
|
236
230
|
} finally {
|
|
237
231
|
cleanup(base);
|
|
238
232
|
}
|
|
239
|
-
|
|
233
|
+
});
|
|
240
234
|
|
|
241
235
|
// ═══════════════════════════════════════════════════════════════════════
|
|
242
236
|
// Roadmap Parser Tests
|
|
243
237
|
// ═══════════════════════════════════════════════════════════════════════
|
|
244
238
|
|
|
245
|
-
|
|
246
|
-
{
|
|
239
|
+
test('parseOldRoadmap: flat format', () => {
|
|
247
240
|
const roadmap = parseOldRoadmap(SAMPLE_ROADMAP);
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
{
|
|
241
|
+
assert.deepStrictEqual(roadmap.milestones.length, 0, 'flat roadmap: no milestone sections');
|
|
242
|
+
assert.deepStrictEqual(roadmap.phases.length, 3, 'flat roadmap: 3 phases');
|
|
243
|
+
assert.deepStrictEqual(roadmap.phases[0].number, 29, 'flat roadmap: first phase number');
|
|
244
|
+
assert.deepStrictEqual(roadmap.phases[0].title, 'Auth System', 'flat roadmap: first phase title');
|
|
245
|
+
assert.deepStrictEqual(roadmap.phases[0].done, true, 'flat roadmap: first phase done');
|
|
246
|
+
assert.deepStrictEqual(roadmap.phases[1].done, false, 'flat roadmap: second phase not done');
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
test('parseOldRoadmap: milestone-sectioned with <details>', () => {
|
|
258
250
|
const roadmap = parseOldRoadmap(SAMPLE_MILESTONE_SECTIONED_ROADMAP);
|
|
259
|
-
|
|
251
|
+
assert.ok(roadmap.milestones.length >= 2, 'ms roadmap: has milestone sections');
|
|
260
252
|
|
|
261
253
|
const v20 = roadmap.milestones.find(m => m.id.includes('2.0'));
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
254
|
+
assert.ok(v20 !== undefined, 'ms roadmap: v2.0 found');
|
|
255
|
+
assert.deepStrictEqual(v20?.collapsed, true, 'ms roadmap: v2.0 collapsed');
|
|
256
|
+
assert.ok((v20?.phases.length ?? 0) >= 2, 'ms roadmap: v2.0 has phases');
|
|
257
|
+
assert.ok(v20?.phases.every(p => p.done) ?? false, 'ms roadmap: v2.0 all done');
|
|
266
258
|
|
|
267
259
|
const v25 = roadmap.milestones.find(m => m.id.includes('2.5'));
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
260
|
+
assert.ok(v25 !== undefined, 'ms roadmap: v2.5 found');
|
|
261
|
+
assert.deepStrictEqual(v25?.collapsed, false, 'ms roadmap: v2.5 not collapsed');
|
|
262
|
+
assert.ok((v25?.phases.length ?? 0) >= 3, 'ms roadmap: v2.5 has 3 phases');
|
|
271
263
|
|
|
272
264
|
const p29 = v25?.phases.find(p => p.number === 29);
|
|
273
|
-
|
|
265
|
+
assert.deepStrictEqual(p29?.done, true, 'ms roadmap: phase 29 done');
|
|
274
266
|
const p30 = v25?.phases.find(p => p.number === 30);
|
|
275
|
-
|
|
276
|
-
|
|
267
|
+
assert.deepStrictEqual(p30?.done, false, 'ms roadmap: phase 30 not done');
|
|
268
|
+
});
|
|
277
269
|
|
|
278
270
|
// ═══════════════════════════════════════════════════════════════════════
|
|
279
271
|
// Plan Parser Tests
|
|
280
272
|
// ═══════════════════════════════════════════════════════════════════════
|
|
281
273
|
|
|
282
|
-
|
|
283
|
-
{
|
|
274
|
+
test('parseOldPlan: XML-in-markdown', () => {
|
|
284
275
|
const plan = parseOldPlan(SAMPLE_PLAN_XML, '29-01-PLAN.md', '01');
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
276
|
+
assert.ok(plan.objective.includes('authentication'), 'plan: objective extracted');
|
|
277
|
+
assert.deepStrictEqual(plan.tasks.length, 3, 'plan: 3 tasks');
|
|
278
|
+
assert.ok(plan.tasks[0].includes('auth middleware'), 'plan: first task content');
|
|
279
|
+
assert.ok(plan.context.includes('JWT'), 'plan: context extracted');
|
|
280
|
+
assert.ok(plan.verification.includes('Login returns'), 'plan: verification extracted');
|
|
281
|
+
assert.ok(plan.successCriteria.includes('endpoints respond'), 'plan: success criteria extracted');
|
|
291
282
|
|
|
292
283
|
// Frontmatter
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
{
|
|
284
|
+
assert.deepStrictEqual(plan.frontmatter.phase, '29-auth-system', 'plan fm: phase');
|
|
285
|
+
assert.deepStrictEqual(plan.frontmatter.plan, '01', 'plan fm: plan');
|
|
286
|
+
assert.deepStrictEqual(plan.frontmatter.type, 'implementation', 'plan fm: type');
|
|
287
|
+
assert.deepStrictEqual(plan.frontmatter.wave, 1, 'plan fm: wave');
|
|
288
|
+
assert.deepStrictEqual(plan.frontmatter.autonomous, true, 'plan fm: autonomous');
|
|
289
|
+
assert.ok(plan.frontmatter.files_modified.length >= 2, 'plan fm: files_modified');
|
|
290
|
+
assert.ok(plan.frontmatter.must_haves !== null, 'plan fm: must_haves parsed');
|
|
291
|
+
assert.ok((plan.frontmatter.must_haves?.truths.length ?? 0) >= 1, 'plan fm: must_haves truths');
|
|
292
|
+
assert.ok((plan.frontmatter.must_haves?.artifacts.length ?? 0) >= 1, 'plan fm: must_haves artifacts');
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
test('parseOldPlan: plain markdown (no XML tags)', () => {
|
|
306
296
|
const plainPlan = `# 001: Fix Login Bug
|
|
307
297
|
|
|
308
298
|
## Description
|
|
@@ -315,100 +305,86 @@ Fix the login button not responding on mobile.
|
|
|
315
305
|
2. Fix event propagation
|
|
316
306
|
`;
|
|
317
307
|
const plan = parseOldPlan(plainPlan, '001-PLAN.md', '001');
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
308
|
+
assert.deepStrictEqual(plan.objective, '', 'plain plan: no objective (no XML)');
|
|
309
|
+
assert.deepStrictEqual(plan.tasks.length, 0, 'plain plan: no tasks (no XML)');
|
|
310
|
+
assert.deepStrictEqual(plan.frontmatter.phase, '', 'plain plan: no frontmatter phase');
|
|
311
|
+
});
|
|
322
312
|
|
|
323
313
|
// ═══════════════════════════════════════════════════════════════════════
|
|
324
314
|
// Summary Parser Tests
|
|
325
315
|
// ═══════════════════════════════════════════════════════════════════════
|
|
326
316
|
|
|
327
|
-
|
|
328
|
-
{
|
|
317
|
+
test('parseOldSummary: YAML frontmatter', () => {
|
|
329
318
|
const summary = parseOldSummary(SAMPLE_SUMMARY, '29-01-SUMMARY.md', '01');
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
319
|
+
assert.deepStrictEqual(summary.frontmatter.phase, '29-auth-system', 'summary fm: phase');
|
|
320
|
+
assert.deepStrictEqual(summary.frontmatter.plan, '01', 'summary fm: plan');
|
|
321
|
+
assert.deepStrictEqual(summary.frontmatter.subsystem, 'auth', 'summary fm: subsystem');
|
|
322
|
+
assert.deepStrictEqual(summary.frontmatter.tags, ['authentication', 'security'], 'summary fm: tags');
|
|
323
|
+
assert.deepStrictEqual(summary.frontmatter.provides, ['auth-middleware', 'jwt-validation'], 'summary fm: provides');
|
|
324
|
+
assert.deepStrictEqual(summary.frontmatter.affects, ['api-routes'], 'summary fm: affects');
|
|
325
|
+
assert.deepStrictEqual(summary.frontmatter['tech-stack'], ['jsonwebtoken', 'express'], 'summary fm: tech-stack');
|
|
326
|
+
assert.deepStrictEqual(summary.frontmatter['key-files'], ['src/auth.ts', 'src/middleware/auth.ts'], 'summary fm: key-files');
|
|
327
|
+
assert.deepStrictEqual(summary.frontmatter['key-decisions'], ['Use RS256 for JWT signing', 'Store refresh tokens in DB'], 'summary fm: key-decisions');
|
|
328
|
+
assert.deepStrictEqual(summary.frontmatter['patterns-established'], ['Middleware-based auth'], 'summary fm: patterns-established');
|
|
329
|
+
assert.deepStrictEqual(summary.frontmatter.duration, '2h', 'summary fm: duration');
|
|
330
|
+
assert.deepStrictEqual(summary.frontmatter.completed, '2026-01-15', 'summary fm: completed');
|
|
331
|
+
assert.ok(summary.body.includes('Auth Implementation Summary'), 'summary: body content present');
|
|
332
|
+
});
|
|
344
333
|
|
|
345
334
|
// ═══════════════════════════════════════════════════════════════════════
|
|
346
335
|
// Requirements Parser Tests
|
|
347
336
|
// ═══════════════════════════════════════════════════════════════════════
|
|
348
337
|
|
|
349
|
-
|
|
350
|
-
{
|
|
338
|
+
test('parseOldRequirements', () => {
|
|
351
339
|
const reqs = parseOldRequirements(SAMPLE_REQUIREMENTS);
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
340
|
+
assert.deepStrictEqual(reqs.length, 4, 'requirements: 4 entries');
|
|
341
|
+
assert.deepStrictEqual(reqs[0].id, 'R001', 'req 0: id');
|
|
342
|
+
assert.deepStrictEqual(reqs[0].title, 'User Authentication', 'req 0: title');
|
|
343
|
+
assert.deepStrictEqual(reqs[0].status, 'active', 'req 0: status');
|
|
344
|
+
assert.ok(reqs[0].description.includes('log in'), 'req 0: description');
|
|
345
|
+
assert.deepStrictEqual(reqs[2].id, 'R003', 'req 2: id');
|
|
346
|
+
assert.deepStrictEqual(reqs[2].status, 'validated', 'req 2: status');
|
|
347
|
+
assert.deepStrictEqual(reqs[3].id, 'R004', 'req 3: id');
|
|
348
|
+
assert.deepStrictEqual(reqs[3].status, 'deferred', 'req 3: status');
|
|
349
|
+
});
|
|
362
350
|
|
|
363
351
|
// ═══════════════════════════════════════════════════════════════════════
|
|
364
352
|
// State Parser Tests
|
|
365
353
|
// ═══════════════════════════════════════════════════════════════════════
|
|
366
354
|
|
|
367
|
-
|
|
368
|
-
{
|
|
355
|
+
test('parseOldState', () => {
|
|
369
356
|
const state = parseOldState(SAMPLE_STATE);
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
357
|
+
assert.ok(state.currentPhase?.includes('30') ?? false, 'state: current phase includes 30');
|
|
358
|
+
assert.deepStrictEqual(state.status, 'in-progress', 'state: status');
|
|
359
|
+
assert.ok(state.raw === SAMPLE_STATE, 'state: raw preserved');
|
|
360
|
+
});
|
|
374
361
|
|
|
375
362
|
// ═══════════════════════════════════════════════════════════════════════
|
|
376
363
|
// Config Parser Tests
|
|
377
364
|
// ═══════════════════════════════════════════════════════════════════════
|
|
378
365
|
|
|
379
|
-
|
|
380
|
-
{
|
|
366
|
+
test('parseOldConfig: valid JSON', () => {
|
|
381
367
|
const config = parseOldConfig('{"projectName":"test","version":"1.0"}');
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
368
|
+
assert.ok(config !== null, 'config: parsed');
|
|
369
|
+
assert.deepStrictEqual(config?.projectName, 'test', 'config: projectName');
|
|
370
|
+
});
|
|
385
371
|
|
|
386
|
-
|
|
387
|
-
{
|
|
372
|
+
test('parseOldConfig: invalid JSON → null', () => {
|
|
388
373
|
const config = parseOldConfig('not json at all {{{');
|
|
389
|
-
|
|
390
|
-
|
|
374
|
+
assert.deepStrictEqual(config, null, 'config: invalid JSON returns null');
|
|
375
|
+
});
|
|
391
376
|
|
|
392
|
-
|
|
393
|
-
{
|
|
377
|
+
test('parseOldConfig: non-object JSON → null', () => {
|
|
394
378
|
const config = parseOldConfig('"just a string"');
|
|
395
|
-
|
|
396
|
-
|
|
379
|
+
assert.deepStrictEqual(config, null, 'config: non-object returns null');
|
|
380
|
+
});
|
|
397
381
|
|
|
398
382
|
// ═══════════════════════════════════════════════════════════════════════
|
|
399
383
|
// Project Parser Tests
|
|
400
384
|
// ═══════════════════════════════════════════════════════════════════════
|
|
401
385
|
|
|
402
|
-
|
|
403
|
-
{
|
|
386
|
+
test('parseOldProject', () => {
|
|
404
387
|
const project = parseOldProject(SAMPLE_PROJECT);
|
|
405
|
-
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
report();
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
main().catch((error) => {
|
|
412
|
-
console.error(error);
|
|
413
|
-
process.exit(1);
|
|
388
|
+
assert.deepStrictEqual(project, SAMPLE_PROJECT, 'project: returns raw content');
|
|
414
389
|
});
|
|
390
|
+
|