gsd-pi 2.44.0-dev.62b5d6c → 2.44.0-dev.848dd4c
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/commands/handlers/workflow.js +5 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +18 -18
- 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 +18 -18
- 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/commands/handlers/workflow.ts +8 -0
- 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 +152 -183
- 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/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/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 → -zps1Q9mQmioAKLcQiCr8}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{fOnWQBjWXMKUs4bqTg530 → -zps1Q9mQmioAKLcQiCr8}/_ssgManifest.js +0 -0
|
@@ -36,176 +36,156 @@ function makeTempDir(prefix: string): string {
|
|
|
36
36
|
|
|
37
37
|
// ─── appendCapture ────────────────────────────────────────────────────────────
|
|
38
38
|
|
|
39
|
-
test("captures: appendCapture creates CAPTURES.md on first call", () => {
|
|
39
|
+
test("captures: appendCapture creates CAPTURES.md on first call", (t) => {
|
|
40
40
|
const tmp = makeTempDir("cap-create");
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
rmSync(tmp, { recursive: true, force: true });
|
|
61
|
-
}
|
|
41
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
42
|
+
|
|
43
|
+
const id = appendCapture(tmp, "first thought");
|
|
44
|
+
assert.ok(id.startsWith("CAP-"), "ID should start with CAP-");
|
|
45
|
+
assert.ok(
|
|
46
|
+
existsSync(join(tmp, ".gsd", "CAPTURES.md")),
|
|
47
|
+
"CAPTURES.md should exist",
|
|
48
|
+
);
|
|
49
|
+
const content = readFileSync(join(tmp, ".gsd", "CAPTURES.md"), "utf-8");
|
|
50
|
+
assert.ok(content.includes("# Captures"), "should have header");
|
|
51
|
+
assert.ok(content.includes(`### ${id}`), "should have entry heading");
|
|
52
|
+
assert.ok(
|
|
53
|
+
content.includes("**Text:** first thought"),
|
|
54
|
+
"should have text field",
|
|
55
|
+
);
|
|
56
|
+
assert.ok(
|
|
57
|
+
content.includes("**Status:** pending"),
|
|
58
|
+
"should have pending status",
|
|
59
|
+
);
|
|
62
60
|
});
|
|
63
61
|
|
|
64
|
-
test("captures: appendCapture appends to existing file", () => {
|
|
62
|
+
test("captures: appendCapture appends to existing file", (t) => {
|
|
65
63
|
const tmp = makeTempDir("cap-append");
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
rmSync(tmp, { recursive: true, force: true });
|
|
84
|
-
}
|
|
64
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
65
|
+
|
|
66
|
+
const id1 = appendCapture(tmp, "thought one");
|
|
67
|
+
const id2 = appendCapture(tmp, "thought two");
|
|
68
|
+
assert.notStrictEqual(id1, id2, "IDs should be unique");
|
|
69
|
+
|
|
70
|
+
const content = readFileSync(join(tmp, ".gsd", "CAPTURES.md"), "utf-8");
|
|
71
|
+
assert.ok(content.includes(`### ${id1}`), "should have first entry");
|
|
72
|
+
assert.ok(content.includes(`### ${id2}`), "should have second entry");
|
|
73
|
+
assert.ok(
|
|
74
|
+
content.includes("**Text:** thought one"),
|
|
75
|
+
"should have first text",
|
|
76
|
+
);
|
|
77
|
+
assert.ok(
|
|
78
|
+
content.includes("**Text:** thought two"),
|
|
79
|
+
"should have second text",
|
|
80
|
+
);
|
|
85
81
|
});
|
|
86
82
|
|
|
87
83
|
// ─── loadAllCaptures / loadPendingCaptures ────────────────────────────────────
|
|
88
84
|
|
|
89
|
-
test("captures: loadAllCaptures parses entries correctly", () => {
|
|
85
|
+
test("captures: loadAllCaptures parses entries correctly", (t) => {
|
|
90
86
|
const tmp = makeTempDir("cap-load");
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
rmSync(tmp, { recursive: true, force: true });
|
|
103
|
-
}
|
|
87
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
88
|
+
|
|
89
|
+
appendCapture(tmp, "alpha");
|
|
90
|
+
appendCapture(tmp, "beta");
|
|
91
|
+
|
|
92
|
+
const all = loadAllCaptures(tmp);
|
|
93
|
+
assert.strictEqual(all.length, 2, "should have 2 entries");
|
|
94
|
+
assert.strictEqual(all[0].text, "alpha");
|
|
95
|
+
assert.strictEqual(all[1].text, "beta");
|
|
96
|
+
assert.strictEqual(all[0].status, "pending");
|
|
97
|
+
assert.strictEqual(all[1].status, "pending");
|
|
104
98
|
});
|
|
105
99
|
|
|
106
|
-
test("captures: loadAllCaptures returns empty array when no file", () => {
|
|
100
|
+
test("captures: loadAllCaptures returns empty array when no file", (t) => {
|
|
107
101
|
const tmp = makeTempDir("cap-nofile");
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
rmSync(tmp, { recursive: true, force: true });
|
|
113
|
-
}
|
|
102
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
103
|
+
|
|
104
|
+
const all = loadAllCaptures(tmp);
|
|
105
|
+
assert.strictEqual(all.length, 0);
|
|
114
106
|
});
|
|
115
107
|
|
|
116
|
-
test("captures: loadPendingCaptures filters resolved entries", () => {
|
|
108
|
+
test("captures: loadPendingCaptures filters resolved entries", (t) => {
|
|
117
109
|
const tmp = makeTempDir("cap-pending");
|
|
118
|
-
|
|
119
|
-
const id1 = appendCapture(tmp, "pending one");
|
|
120
|
-
appendCapture(tmp, "pending two");
|
|
110
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
121
111
|
|
|
122
|
-
|
|
112
|
+
const id1 = appendCapture(tmp, "pending one");
|
|
113
|
+
appendCapture(tmp, "pending two");
|
|
123
114
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
115
|
+
markCaptureResolved(tmp, id1, "note", "acknowledged", "just a note");
|
|
116
|
+
|
|
117
|
+
const pending = loadPendingCaptures(tmp);
|
|
118
|
+
assert.strictEqual(pending.length, 1, "should have 1 pending");
|
|
119
|
+
assert.strictEqual(pending[0].text, "pending two");
|
|
130
120
|
});
|
|
131
121
|
|
|
132
|
-
test("captures: loadAllCaptures preserves resolved entries", () => {
|
|
122
|
+
test("captures: loadAllCaptures preserves resolved entries", (t) => {
|
|
133
123
|
const tmp = makeTempDir("cap-all-resolved");
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
rmSync(tmp, { recursive: true, force: true });
|
|
146
|
-
}
|
|
124
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
125
|
+
|
|
126
|
+
const id1 = appendCapture(tmp, "pending one");
|
|
127
|
+
appendCapture(tmp, "pending two");
|
|
128
|
+
|
|
129
|
+
markCaptureResolved(tmp, id1, "note", "acknowledged", "just a note");
|
|
130
|
+
|
|
131
|
+
const all = loadAllCaptures(tmp);
|
|
132
|
+
assert.strictEqual(all.length, 2, "all should still have 2");
|
|
133
|
+
assert.strictEqual(all[0].status, "resolved");
|
|
134
|
+
assert.strictEqual(all[1].status, "pending");
|
|
147
135
|
});
|
|
148
136
|
|
|
149
137
|
// ─── hasPendingCaptures ───────────────────────────────────────────────────────
|
|
150
138
|
|
|
151
|
-
test("captures: hasPendingCaptures returns false when no file", () => {
|
|
139
|
+
test("captures: hasPendingCaptures returns false when no file", (t) => {
|
|
152
140
|
const tmp = makeTempDir("cap-has-nofile");
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
rmSync(tmp, { recursive: true, force: true });
|
|
157
|
-
}
|
|
141
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
142
|
+
|
|
143
|
+
assert.strictEqual(hasPendingCaptures(tmp), false);
|
|
158
144
|
});
|
|
159
145
|
|
|
160
|
-
test("captures: hasPendingCaptures returns true with pending entries", () => {
|
|
146
|
+
test("captures: hasPendingCaptures returns true with pending entries", (t) => {
|
|
161
147
|
const tmp = makeTempDir("cap-has-true");
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
rmSync(tmp, { recursive: true, force: true });
|
|
167
|
-
}
|
|
148
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
149
|
+
|
|
150
|
+
appendCapture(tmp, "something");
|
|
151
|
+
assert.strictEqual(hasPendingCaptures(tmp), true);
|
|
168
152
|
});
|
|
169
153
|
|
|
170
|
-
test("captures: hasPendingCaptures returns false when all resolved", () => {
|
|
154
|
+
test("captures: hasPendingCaptures returns false when all resolved", (t) => {
|
|
171
155
|
const tmp = makeTempDir("cap-has-false");
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
rmSync(tmp, { recursive: true, force: true });
|
|
178
|
-
}
|
|
156
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
157
|
+
|
|
158
|
+
const id = appendCapture(tmp, "will resolve");
|
|
159
|
+
markCaptureResolved(tmp, id, "note", "done", "resolved it");
|
|
160
|
+
assert.strictEqual(hasPendingCaptures(tmp), false);
|
|
179
161
|
});
|
|
180
162
|
|
|
181
163
|
// ─── markCaptureResolved ──────────────────────────────────────────────────────
|
|
182
164
|
|
|
183
|
-
test("captures: markCaptureResolved updates entry in place", () => {
|
|
165
|
+
test("captures: markCaptureResolved updates entry in place", (t) => {
|
|
184
166
|
const tmp = makeTempDir("cap-resolve");
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
rmSync(tmp, { recursive: true, force: true });
|
|
208
|
-
}
|
|
167
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
168
|
+
|
|
169
|
+
const id1 = appendCapture(tmp, "keep pending");
|
|
170
|
+
const id2 = appendCapture(tmp, "will resolve");
|
|
171
|
+
appendCapture(tmp, "also pending");
|
|
172
|
+
|
|
173
|
+
markCaptureResolved(tmp, id2, "quick-task", "executed inline", "small fix");
|
|
174
|
+
|
|
175
|
+
const all = loadAllCaptures(tmp);
|
|
176
|
+
assert.strictEqual(all.length, 3, "should still have 3 entries");
|
|
177
|
+
|
|
178
|
+
const resolved = all.find((c) => c.id === id2)!;
|
|
179
|
+
assert.strictEqual(resolved.status, "resolved");
|
|
180
|
+
assert.strictEqual(resolved.classification, "quick-task");
|
|
181
|
+
assert.strictEqual(resolved.resolution, "executed inline");
|
|
182
|
+
assert.strictEqual(resolved.rationale, "small fix");
|
|
183
|
+
assert.ok(resolved.resolvedAt, "should have resolved timestamp");
|
|
184
|
+
|
|
185
|
+
// Others should be unaffected
|
|
186
|
+
const kept = all.find((c) => c.id === id1)!;
|
|
187
|
+
assert.strictEqual(kept.status, "pending");
|
|
188
|
+
assert.strictEqual(kept.classification, undefined);
|
|
209
189
|
});
|
|
210
190
|
|
|
211
191
|
// ─── resolveCapturesPath ──────────────────────────────────────────────────────
|
|
@@ -371,58 +351,50 @@ test("triage: parseTriageOutput handles all five classification types", () => {
|
|
|
371
351
|
|
|
372
352
|
// ─── Edge Cases ───────────────────────────────────────────────────────────────
|
|
373
353
|
|
|
374
|
-
test("captures: appendCapture handles special characters in text", () => {
|
|
354
|
+
test("captures: appendCapture handles special characters in text", (t) => {
|
|
375
355
|
const tmp = makeTempDir("cap-special");
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
rmSync(tmp, { recursive: true, force: true });
|
|
384
|
-
}
|
|
356
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
357
|
+
|
|
358
|
+
const id = appendCapture(tmp, 'text with "quotes" and **bold** and `code`');
|
|
359
|
+
const all = loadAllCaptures(tmp);
|
|
360
|
+
assert.strictEqual(all.length, 1);
|
|
361
|
+
assert.ok(all[0].text.includes('"quotes"'), "should preserve quotes");
|
|
362
|
+
assert.ok(all[0].text.includes("**bold**"), "should preserve bold");
|
|
385
363
|
});
|
|
386
364
|
|
|
387
|
-
test("captures: markCaptureResolved is no-op for non-existent ID", () => {
|
|
365
|
+
test("captures: markCaptureResolved is no-op for non-existent ID", (t) => {
|
|
388
366
|
const tmp = makeTempDir("cap-noop");
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
rmSync(tmp, { recursive: true, force: true });
|
|
398
|
-
}
|
|
367
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
368
|
+
|
|
369
|
+
appendCapture(tmp, "real capture");
|
|
370
|
+
// Should not throw
|
|
371
|
+
markCaptureResolved(tmp, "CAP-nonexistent", "note", "test", "test");
|
|
372
|
+
const all = loadAllCaptures(tmp);
|
|
373
|
+
assert.strictEqual(all.length, 1);
|
|
374
|
+
assert.strictEqual(all[0].status, "pending", "original should be unchanged");
|
|
399
375
|
});
|
|
400
376
|
|
|
401
|
-
test("captures: markCaptureResolved is no-op when no file exists", () => {
|
|
377
|
+
test("captures: markCaptureResolved is no-op when no file exists", (t) => {
|
|
402
378
|
const tmp = makeTempDir("cap-nofile-resolve");
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
rmSync(tmp, { recursive: true, force: true });
|
|
408
|
-
}
|
|
379
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
380
|
+
|
|
381
|
+
// Should not throw
|
|
382
|
+
markCaptureResolved(tmp, "CAP-abc", "note", "test", "test");
|
|
409
383
|
});
|
|
410
384
|
|
|
411
|
-
test("captures: re-resolving a capture overwrites previous resolution", () => {
|
|
385
|
+
test("captures: re-resolving a capture overwrites previous resolution", (t) => {
|
|
412
386
|
const tmp = makeTempDir("cap-reresolve");
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
rmSync(tmp, { recursive: true, force: true });
|
|
425
|
-
}
|
|
387
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
388
|
+
|
|
389
|
+
const id = appendCapture(tmp, "will re-resolve");
|
|
390
|
+
markCaptureResolved(tmp, id, "note", "first resolution", "first rationale");
|
|
391
|
+
markCaptureResolved(tmp, id, "inject", "second resolution", "second rationale");
|
|
392
|
+
|
|
393
|
+
const all = loadAllCaptures(tmp);
|
|
394
|
+
assert.strictEqual(all.length, 1);
|
|
395
|
+
assert.strictEqual(all[0].classification, "inject", "should have updated classification");
|
|
396
|
+
assert.strictEqual(all[0].resolution, "second resolution");
|
|
397
|
+
assert.strictEqual(all[0].rationale, "second rationale");
|
|
426
398
|
});
|
|
427
399
|
|
|
428
400
|
test("triage: parseTriageOutput preserves affectedFiles and targetSlice", () => {
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
* `/plugin marketplace add ...` source model.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
|
|
12
11
|
import { describe, it, before, after, mock } from 'node:test';
|
|
13
12
|
import assert from 'node:assert';
|
|
14
13
|
import { existsSync, mkdtempSync, rmSync, writeFileSync, readFileSync, mkdirSync } from 'node:fs';
|
|
@@ -306,45 +305,45 @@ describe(
|
|
|
306
305
|
});
|
|
307
306
|
});
|
|
308
307
|
|
|
309
|
-
it('should not persist marketplace agent directories into package sources', async () => {
|
|
308
|
+
it('should not persist marketplace agent directories into package sources', async (t) => {
|
|
310
309
|
const isolatedAgentDir = join(tempDir, '.gsd', 'agent');
|
|
311
310
|
const settingsPath = join(isolatedAgentDir, 'settings.json');
|
|
312
311
|
rmSync(isolatedAgentDir, { recursive: true, force: true });
|
|
313
312
|
process.env.GSD_CODING_AGENT_DIR = isolatedAgentDir;
|
|
314
313
|
|
|
315
|
-
|
|
316
|
-
mkdirSync(isolatedAgentDir, { recursive: true });
|
|
317
|
-
const tempSettings: Record<string, unknown> = { packages: [] };
|
|
318
|
-
writeFileSync(settingsPath, JSON.stringify(tempSettings, null, 2));
|
|
319
|
-
|
|
320
|
-
const { ctx } = createMockContext([
|
|
321
|
-
'Plugins only',
|
|
322
|
-
'Yes - discover plugins and select components',
|
|
323
|
-
'Import all components',
|
|
324
|
-
'Yes, continue',
|
|
325
|
-
]);
|
|
326
|
-
|
|
327
|
-
const readPrefs = () => ({ ...prefs });
|
|
328
|
-
const writePrefs = async (p: Record<string, unknown>) => {
|
|
329
|
-
Object.assign(prefs, p);
|
|
330
|
-
};
|
|
331
|
-
|
|
332
|
-
await runClaudeImportFlow(ctx, 'global', readPrefs, writePrefs);
|
|
333
|
-
|
|
334
|
-
const settings = JSON.parse(readFileSync(settingsPath, 'utf8')) as { packages?: unknown[] };
|
|
335
|
-
const packageEntries = Array.isArray(settings.packages) ? settings.packages : [];
|
|
336
|
-
const hasAgentsDirPackage = packageEntries.some((entry) => {
|
|
337
|
-
const source = typeof entry === 'string'
|
|
338
|
-
? entry
|
|
339
|
-
: (entry && typeof entry === 'object' ? (entry as { source?: unknown }).source : undefined);
|
|
340
|
-
return typeof source === 'string' && source.endsWith('/agents');
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
assert.strictEqual(hasAgentsDirPackage, false, 'Marketplace agent directories should not be persisted as package sources');
|
|
344
|
-
} finally {
|
|
314
|
+
t.after(() => {
|
|
345
315
|
delete process.env.GSD_CODING_AGENT_DIR;
|
|
346
316
|
rmSync(isolatedAgentDir, { recursive: true, force: true });
|
|
347
|
-
}
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
mkdirSync(isolatedAgentDir, { recursive: true });
|
|
320
|
+
const tempSettings: Record<string, unknown> = { packages: [] };
|
|
321
|
+
writeFileSync(settingsPath, JSON.stringify(tempSettings, null, 2));
|
|
322
|
+
|
|
323
|
+
const { ctx } = createMockContext([
|
|
324
|
+
'Plugins only',
|
|
325
|
+
'Yes - discover plugins and select components',
|
|
326
|
+
'Import all components',
|
|
327
|
+
'Yes, continue',
|
|
328
|
+
]);
|
|
329
|
+
|
|
330
|
+
const readPrefs = () => ({ ...prefs });
|
|
331
|
+
const writePrefs = async (p: Record<string, unknown>) => {
|
|
332
|
+
Object.assign(prefs, p);
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
await runClaudeImportFlow(ctx, 'global', readPrefs, writePrefs);
|
|
336
|
+
|
|
337
|
+
const settings = JSON.parse(readFileSync(settingsPath, 'utf8')) as { packages?: unknown[] };
|
|
338
|
+
const packageEntries = Array.isArray(settings.packages) ? settings.packages : [];
|
|
339
|
+
const hasAgentsDirPackage = packageEntries.some((entry) => {
|
|
340
|
+
const source = typeof entry === 'string'
|
|
341
|
+
? entry
|
|
342
|
+
: (entry && typeof entry === 'object' ? (entry as { source?: unknown }).source : undefined);
|
|
343
|
+
return typeof source === 'string' && source.endsWith('/agents');
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
assert.strictEqual(hasAgentsDirPackage, false, 'Marketplace agent directories should not be persisted as package sources');
|
|
348
347
|
});
|
|
349
348
|
});
|
|
350
349
|
}
|