gsd-pi 2.81.0-dev.72a81bdf3 → 2.82.0-dev.2841a1e44
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 +49 -30
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +3 -1
- package/dist/resources/extensions/browser-tools/tools/screenshot.js +1 -0
- package/dist/resources/extensions/browser-tools/tools/zoom.js +1 -0
- package/dist/resources/extensions/cmux/index.js +5 -0
- package/dist/resources/extensions/gsd/auto/orchestrator.js +113 -6
- package/dist/resources/extensions/gsd/auto/phases.js +9 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +169 -124
- package/dist/resources/extensions/gsd/auto-prompts.js +13 -5
- package/dist/resources/extensions/gsd/auto-verification.js +28 -22
- package/dist/resources/extensions/gsd/auto.js +128 -52
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +5 -0
- package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +16 -7
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +55 -12
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +3 -1
- package/dist/resources/extensions/gsd/clean-root-preflight.js +170 -8
- package/dist/resources/extensions/gsd/commands/catalog.js +4 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +22 -1
- package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +15 -2
- package/dist/resources/extensions/gsd/context-store.js +112 -0
- package/dist/resources/extensions/gsd/db-writer.js +150 -84
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/dist/resources/extensions/gsd/doctor-git-checks.js +41 -6
- package/dist/resources/extensions/gsd/knowledge-backfill.js +144 -0
- package/dist/resources/extensions/gsd/knowledge-capture.js +136 -0
- package/dist/resources/extensions/gsd/knowledge-parser.js +154 -0
- package/dist/resources/extensions/gsd/knowledge-projection.js +210 -0
- package/dist/resources/extensions/gsd/markdown-renderer.js +6 -1
- package/dist/resources/extensions/gsd/md-importer.js +1 -1
- package/dist/resources/extensions/gsd/memory-backfill.js +73 -17
- package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +222 -0
- package/dist/resources/extensions/gsd/migrate/command.js +5 -0
- package/dist/resources/extensions/gsd/migrate/preview.js +9 -0
- package/dist/resources/extensions/gsd/migrate/transformer.js +51 -4
- package/dist/resources/extensions/gsd/migrate/writer.js +11 -1
- package/dist/resources/extensions/gsd/prompts/system.md +2 -2
- package/dist/resources/extensions/gsd/provider-switch-observer.js +146 -0
- package/dist/resources/extensions/gsd/templates/knowledge.md +2 -2
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +119 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +25 -2
- package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +21 -2
- package/dist/resources/extensions/subagent/index.js +448 -78
- package/dist/resources/extensions/subagent/launch.js +77 -0
- package/dist/resources/extensions/subagent/run-store.js +148 -0
- package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
- package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
- package/dist/resources/extensions/visual-brief/index.js +5 -0
- package/dist/resources/extensions/visual-brief/page-contract.js +122 -0
- package/dist/resources/extensions/visual-brief/prompts.js +111 -0
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +15 -15
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- 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/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +2 -2
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +15 -15
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/2973.33f26573894b6153.js +2 -0
- package/dist/web/standalone/.next/static/chunks/{8359.e059d86b255fce1c.js → 8359.7eb3bb8f8ecf4c01.js} +2 -2
- package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-6a95bc41e0f7ec89.js} +1 -1
- package/dist/web/standalone/.next/static/css/0262768ec1b89d34.css +1 -0
- package/package.json +5 -4
- package/packages/contracts/dist/rpc.test.js +7 -0
- package/packages/contracts/dist/rpc.test.js.map +1 -1
- package/packages/contracts/dist/workflow.d.ts +21 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +24 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/src/rpc.test.ts +8 -0
- package/packages/contracts/src/workflow.ts +24 -0
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/README.md +14 -3
- package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +80 -0
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +2 -2
- package/packages/mcp-server/src/workflow-tools-parity.test.ts +244 -0
- package/packages/mcp-server/src/workflow-tools.test.ts +22 -0
- package/packages/mcp-server/src/workflow-tools.ts +168 -0
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/index.d.ts +2 -2
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +1 -1
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.d.ts +11 -0
- package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.js +20 -0
- package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/src/index.ts +7 -2
- package/packages/pi-ai/src/providers/transform-messages.ts +24 -0
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +4 -4
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js +17 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js.map +1 -0
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/system-prompt.ts +4 -4
- package/packages/pi-coding-agent/src/tests/system-prompt-file-safety.test.ts +22 -0
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +5 -0
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/pi-tui/src/tui.ts +6 -0
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/package.json +1 -1
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +3 -1
- package/src/resources/extensions/browser-tools/tools/screenshot.ts +1 -0
- package/src/resources/extensions/browser-tools/tools/zoom.ts +1 -0
- package/src/resources/extensions/cmux/index.ts +6 -0
- package/src/resources/extensions/gsd/auto/contracts.ts +46 -11
- package/src/resources/extensions/gsd/auto/orchestrator.ts +118 -6
- package/src/resources/extensions/gsd/auto/phases.ts +14 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +194 -137
- package/src/resources/extensions/gsd/auto-prompts.ts +13 -5
- package/src/resources/extensions/gsd/auto-verification.ts +36 -34
- package/src/resources/extensions/gsd/auto.ts +136 -51
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +6 -0
- package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +16 -6
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +58 -15
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +3 -2
- package/src/resources/extensions/gsd/clean-root-preflight.ts +174 -8
- package/src/resources/extensions/gsd/commands/catalog.ts +4 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +25 -1
- package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +19 -2
- package/src/resources/extensions/gsd/context-store.ts +120 -1
- package/src/resources/extensions/gsd/db-writer.ts +167 -84
- package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/src/resources/extensions/gsd/doctor-git-checks.ts +44 -6
- package/src/resources/extensions/gsd/doctor-types.ts +2 -0
- package/src/resources/extensions/gsd/knowledge-backfill.ts +164 -0
- package/src/resources/extensions/gsd/knowledge-capture.ts +160 -0
- package/src/resources/extensions/gsd/knowledge-parser.ts +174 -0
- package/src/resources/extensions/gsd/knowledge-projection.ts +241 -0
- package/src/resources/extensions/gsd/markdown-renderer.ts +6 -1
- package/src/resources/extensions/gsd/md-importer.ts +1 -1
- package/src/resources/extensions/gsd/memory-backfill.ts +89 -17
- package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +277 -0
- package/src/resources/extensions/gsd/migrate/command.ts +5 -0
- package/src/resources/extensions/gsd/migrate/preview.ts +10 -0
- package/src/resources/extensions/gsd/migrate/transformer.ts +58 -4
- package/src/resources/extensions/gsd/migrate/writer.ts +14 -1
- package/src/resources/extensions/gsd/prompts/system.md +2 -2
- package/src/resources/extensions/gsd/provider-switch-observer.ts +185 -0
- package/src/resources/extensions/gsd/templates/knowledge.md +2 -2
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +408 -4
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +6 -5
- package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/browser-tools-compatibility-declarations.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +107 -2
- package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/context-store-decisions-from-memories.test.ts +312 -0
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +13 -8
- package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +453 -0
- package/src/resources/extensions/gsd/tests/decisions-stop-table-writes.test.ts +348 -0
- package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +8 -4
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +11 -7
- package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/integration/integration-lifecycle.test.ts +13 -5
- package/src/resources/extensions/gsd/tests/integration/migrate-command.test.ts +48 -3
- package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +323 -0
- package/src/resources/extensions/gsd/tests/knowledge-capture.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -2
- package/src/resources/extensions/gsd/tests/load-knowledge-block-rules-only.test.ts +209 -0
- package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +316 -0
- package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +5 -1
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/plan-milestone-sketch-render.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/provider-switch-observer.test.ts +252 -0
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +16 -4
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +16 -0
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +135 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +35 -2
- package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +4 -0
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +20 -2
- package/src/resources/extensions/subagent/index.ts +567 -103
- package/src/resources/extensions/subagent/launch.ts +131 -0
- package/src/resources/extensions/subagent/run-store.ts +218 -0
- package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
- package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
- package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
- package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
- package/src/resources/extensions/visual-brief/index.ts +8 -0
- package/src/resources/extensions/visual-brief/page-contract.ts +134 -0
- package/src/resources/extensions/visual-brief/prompts.ts +147 -0
- package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +172 -0
- package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
- package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
- /package/dist/web/standalone/.next/static/{rIkMv4YSNlfSeqmGqWVns → Qgr2B_MRhPxC0z8fwv4vT}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{rIkMv4YSNlfSeqmGqWVns → Qgr2B_MRhPxC0z8fwv4vT}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// Project/App: GSD-2
|
|
2
|
+
// File Purpose: Tests for host-owned auto-mode verification verdict policy.
|
|
3
|
+
|
|
4
|
+
import test from "node:test";
|
|
5
|
+
import assert from "node:assert/strict";
|
|
6
|
+
|
|
7
|
+
import { decideVerificationVerdict } from "../verification-verdict.ts";
|
|
8
|
+
import type { VerificationResult } from "../types.ts";
|
|
9
|
+
|
|
10
|
+
function makeResult(overrides: Partial<VerificationResult> = {}): VerificationResult {
|
|
11
|
+
return {
|
|
12
|
+
passed: true,
|
|
13
|
+
checks: [],
|
|
14
|
+
discoverySource: "none",
|
|
15
|
+
timestamp: 1,
|
|
16
|
+
...overrides,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
test("execute-task fails closed when no host-owned checks are discovered", () => {
|
|
21
|
+
const verdict = decideVerificationVerdict("execute-task", makeResult());
|
|
22
|
+
|
|
23
|
+
assert.equal(verdict.passed, false);
|
|
24
|
+
assert.equal(verdict.reason, "no-host-checks");
|
|
25
|
+
assert.equal(verdict.retryable, false);
|
|
26
|
+
assert.match(verdict.failureContext, /No runnable host-owned verification command/);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test("non execute-task units preserve no-check pass semantics", () => {
|
|
30
|
+
const verdict = decideVerificationVerdict("plan-slice", makeResult());
|
|
31
|
+
|
|
32
|
+
assert.equal(verdict.passed, true);
|
|
33
|
+
assert.equal(verdict.reason, "passed");
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("execute-task command failure remains retryable verification failure", () => {
|
|
37
|
+
const verdict = decideVerificationVerdict(
|
|
38
|
+
"execute-task",
|
|
39
|
+
makeResult({
|
|
40
|
+
passed: false,
|
|
41
|
+
discoverySource: "package-json",
|
|
42
|
+
checks: [
|
|
43
|
+
{
|
|
44
|
+
command: "npm test",
|
|
45
|
+
exitCode: 1,
|
|
46
|
+
stdout: "",
|
|
47
|
+
stderr: "failed",
|
|
48
|
+
durationMs: 10,
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
}),
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
assert.equal(verdict.passed, false);
|
|
55
|
+
assert.equal(verdict.reason, "checks-failed");
|
|
56
|
+
assert.equal(verdict.retryable, true);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test("execute-task passes when a discovered host check succeeds", () => {
|
|
60
|
+
const verdict = decideVerificationVerdict(
|
|
61
|
+
"execute-task",
|
|
62
|
+
makeResult({
|
|
63
|
+
discoverySource: "preference",
|
|
64
|
+
checks: [
|
|
65
|
+
{
|
|
66
|
+
command: "npm test",
|
|
67
|
+
exitCode: 0,
|
|
68
|
+
stdout: "ok",
|
|
69
|
+
stderr: "",
|
|
70
|
+
durationMs: 10,
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
}),
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
assert.equal(verdict.passed, true);
|
|
77
|
+
assert.equal(verdict.reason, "passed");
|
|
78
|
+
});
|
|
@@ -538,6 +538,31 @@ test("restoreToProjectRoot is no-op when originalBasePath is empty", () => {
|
|
|
538
538
|
assert.equal(deps.calls.filter((c) => c.fn === "gitServiceFactory").length, 0);
|
|
539
539
|
});
|
|
540
540
|
|
|
541
|
+
test("restoreToProjectRoot completes session-state restore even when chdir fails (ADR-016 phase 3, #5693)", () => {
|
|
542
|
+
// The verb attempts process.chdir to s.basePath after restoring it. The
|
|
543
|
+
// chdir is best-effort; failure must not abort the session-state restore.
|
|
544
|
+
// We exercise that contract by pointing originalBasePath at a path that
|
|
545
|
+
// cannot be chdir'd into.
|
|
546
|
+
const s = makeSession();
|
|
547
|
+
s.originalBasePath = "/this/path/should/not/exist/in/any/test/env";
|
|
548
|
+
s.basePath = "/project/.gsd/worktrees/M001";
|
|
549
|
+
const deps = makeDeps();
|
|
550
|
+
const lifecycle = new WorktreeLifecycle(s, deps);
|
|
551
|
+
|
|
552
|
+
// Capture cwd so we can confirm we did NOT successfully chdir.
|
|
553
|
+
const cwdBefore = process.cwd();
|
|
554
|
+
lifecycle.restoreToProjectRoot();
|
|
555
|
+
|
|
556
|
+
// Session-state restore happened despite chdir failure.
|
|
557
|
+
assert.equal(s.basePath, "/this/path/should/not/exist/in/any/test/env");
|
|
558
|
+
assert.equal(
|
|
559
|
+
deps.calls.filter((c) => c.fn === "gitServiceFactory").length,
|
|
560
|
+
1,
|
|
561
|
+
);
|
|
562
|
+
// cwd is unchanged because chdir threw and was swallowed.
|
|
563
|
+
assert.equal(process.cwd(), cwdBefore);
|
|
564
|
+
});
|
|
565
|
+
|
|
541
566
|
// ─── adoptSessionRoot (ADR-016 phase 2 / B2, issue #5620) ─────────────────────
|
|
542
567
|
|
|
543
568
|
test("adoptSessionRoot sets basePath and seeds originalBasePath on a fresh session", () => {
|
|
@@ -172,6 +172,22 @@ test('planning-dispatch: extracts subagent classes from single, parallel, and ch
|
|
|
172
172
|
extractSubagentAgentClasses({ chain: [{ agent: 'reviewer' }, { agent: 'security' }] }),
|
|
173
173
|
['reviewer', 'security'],
|
|
174
174
|
);
|
|
175
|
+
assert.deepEqual(
|
|
176
|
+
extractSubagentAgentClasses({
|
|
177
|
+
chain: [
|
|
178
|
+
{ agent: 'scout' },
|
|
179
|
+
{ parallel: [{ agent: 'reviewer' }, { agent: ' security ' }] },
|
|
180
|
+
],
|
|
181
|
+
}),
|
|
182
|
+
['scout', 'reviewer', 'security'],
|
|
183
|
+
);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
test('planning-dispatch: extracts subagent classes without recursing through cycles', () => {
|
|
187
|
+
const input: { agent: string; parallel?: unknown[] } = { agent: 'scout' };
|
|
188
|
+
input.parallel = [input, { agent: 'reviewer' }];
|
|
189
|
+
|
|
190
|
+
assert.deepEqual(extractSubagentAgentClasses(input), ['scout', 'reviewer']);
|
|
175
191
|
});
|
|
176
192
|
|
|
177
193
|
test('planning-dispatch: blocks subagent dispatch when agentClasses is undefined (stale caller shim)', () => {
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// Project/App: GSD-2
|
|
2
|
+
// File Purpose: Adapts shared GSD workflow handlers for MCP executor calls.
|
|
3
|
+
|
|
1
4
|
import { ensureDbOpen } from "../bootstrap/dynamic-tools.js";
|
|
2
5
|
import { sanitizeCompleteMilestoneParams } from "../bootstrap/sanitize-complete-milestone.js";
|
|
3
6
|
import { loadWriteGateSnapshot, shouldBlockContextArtifactSaveInSnapshot, shouldBlockRootArtifactSaveInSnapshot } from "../bootstrap/write-gate.js";
|
|
@@ -25,6 +28,12 @@ import type { PlanSliceParams } from "./plan-slice.js";
|
|
|
25
28
|
import { handlePlanSlice } from "./plan-slice.js";
|
|
26
29
|
import type { ReplanSliceParams } from "./replan-slice.js";
|
|
27
30
|
import { handleReplanSlice } from "./replan-slice.js";
|
|
31
|
+
import type { ReopenMilestoneParams } from "./reopen-milestone.js";
|
|
32
|
+
import { handleReopenMilestone } from "./reopen-milestone.js";
|
|
33
|
+
import type { ReopenSliceParams } from "./reopen-slice.js";
|
|
34
|
+
import { handleReopenSlice } from "./reopen-slice.js";
|
|
35
|
+
import type { ReopenTaskParams } from "./reopen-task.js";
|
|
36
|
+
import { handleReopenTask } from "./reopen-task.js";
|
|
28
37
|
import type { ReassessRoadmapParams } from "./reassess-roadmap.js";
|
|
29
38
|
import { handleReassessRoadmap } from "./reassess-roadmap.js";
|
|
30
39
|
import type { ValidateMilestoneParams } from "./validate-milestone.js";
|
|
@@ -311,6 +320,9 @@ export type SliceCompleteExecutorParams = CompleteSliceParams;
|
|
|
311
320
|
export type PlanMilestoneExecutorParams = PlanMilestoneParams;
|
|
312
321
|
export type PlanSliceExecutorParams = PlanSliceParams;
|
|
313
322
|
export type ReplanSliceExecutorParams = ReplanSliceParams;
|
|
323
|
+
export type ReopenTaskExecutorParams = ReopenTaskParams;
|
|
324
|
+
export type ReopenSliceExecutorParams = ReopenSliceParams;
|
|
325
|
+
export type ReopenMilestoneExecutorParams = ReopenMilestoneParams;
|
|
314
326
|
export type ValidateMilestoneExecutorParams = ValidateMilestoneParams;
|
|
315
327
|
export type ReassessRoadmapExecutorParams = ReassessRoadmapParams;
|
|
316
328
|
|
|
@@ -371,6 +383,129 @@ export async function executeTaskComplete(
|
|
|
371
383
|
}
|
|
372
384
|
}
|
|
373
385
|
|
|
386
|
+
export async function executeTaskReopen(
|
|
387
|
+
params: ReopenTaskExecutorParams,
|
|
388
|
+
basePath: string = process.cwd(),
|
|
389
|
+
): Promise<ToolExecutionResult> {
|
|
390
|
+
const dbAvailable = await ensureDbOpen(basePath);
|
|
391
|
+
if (!dbAvailable) {
|
|
392
|
+
return {
|
|
393
|
+
content: [{ type: "text", text: "Error: GSD database is not available. Cannot reopen task." }],
|
|
394
|
+
details: { operation: "reopen_task", error: "db_unavailable" },
|
|
395
|
+
isError: true,
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
try {
|
|
399
|
+
const result = await handleReopenTask(params, basePath);
|
|
400
|
+
if ("error" in result) {
|
|
401
|
+
return {
|
|
402
|
+
content: [{ type: "text", text: `Error reopening task: ${result.error}` }],
|
|
403
|
+
details: { operation: "reopen_task", error: result.error },
|
|
404
|
+
isError: true,
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
return {
|
|
408
|
+
content: [{ type: "text", text: `Reopened task ${result.taskId} (${result.sliceId}/${result.milestoneId})` }],
|
|
409
|
+
details: {
|
|
410
|
+
operation: "reopen_task",
|
|
411
|
+
taskId: result.taskId,
|
|
412
|
+
sliceId: result.sliceId,
|
|
413
|
+
milestoneId: result.milestoneId,
|
|
414
|
+
},
|
|
415
|
+
};
|
|
416
|
+
} catch (err) {
|
|
417
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
418
|
+
logError("tool", `reopen_task tool failed: ${msg}`, { tool: "gsd_task_reopen", error: String(err) });
|
|
419
|
+
return {
|
|
420
|
+
content: [{ type: "text", text: `Error reopening task: ${msg}` }],
|
|
421
|
+
details: { operation: "reopen_task", error: msg },
|
|
422
|
+
isError: true,
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
export async function executeSliceReopen(
|
|
428
|
+
params: ReopenSliceExecutorParams,
|
|
429
|
+
basePath: string = process.cwd(),
|
|
430
|
+
): Promise<ToolExecutionResult> {
|
|
431
|
+
const dbAvailable = await ensureDbOpen(basePath);
|
|
432
|
+
if (!dbAvailable) {
|
|
433
|
+
return {
|
|
434
|
+
content: [{ type: "text", text: "Error: GSD database is not available. Cannot reopen slice." }],
|
|
435
|
+
details: { operation: "reopen_slice", error: "db_unavailable" },
|
|
436
|
+
isError: true,
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
try {
|
|
440
|
+
const result = await handleReopenSlice(params, basePath);
|
|
441
|
+
if ("error" in result) {
|
|
442
|
+
return {
|
|
443
|
+
content: [{ type: "text", text: `Error reopening slice: ${result.error}` }],
|
|
444
|
+
details: { operation: "reopen_slice", error: result.error },
|
|
445
|
+
isError: true,
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
return {
|
|
449
|
+
content: [{ type: "text", text: `Reopened slice ${result.sliceId} (${result.milestoneId})` }],
|
|
450
|
+
details: {
|
|
451
|
+
operation: "reopen_slice",
|
|
452
|
+
sliceId: result.sliceId,
|
|
453
|
+
milestoneId: result.milestoneId,
|
|
454
|
+
tasksReset: result.tasksReset,
|
|
455
|
+
},
|
|
456
|
+
};
|
|
457
|
+
} catch (err) {
|
|
458
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
459
|
+
logError("tool", `reopen_slice tool failed: ${msg}`, { tool: "gsd_slice_reopen", error: String(err) });
|
|
460
|
+
return {
|
|
461
|
+
content: [{ type: "text", text: `Error reopening slice: ${msg}` }],
|
|
462
|
+
details: { operation: "reopen_slice", error: msg },
|
|
463
|
+
isError: true,
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
export async function executeMilestoneReopen(
|
|
469
|
+
params: ReopenMilestoneExecutorParams,
|
|
470
|
+
basePath: string = process.cwd(),
|
|
471
|
+
): Promise<ToolExecutionResult> {
|
|
472
|
+
const dbAvailable = await ensureDbOpen(basePath);
|
|
473
|
+
if (!dbAvailable) {
|
|
474
|
+
return {
|
|
475
|
+
content: [{ type: "text", text: "Error: GSD database is not available. Cannot reopen milestone." }],
|
|
476
|
+
details: { operation: "reopen_milestone", error: "db_unavailable" },
|
|
477
|
+
isError: true,
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
try {
|
|
481
|
+
const result = await handleReopenMilestone(params, basePath);
|
|
482
|
+
if ("error" in result) {
|
|
483
|
+
return {
|
|
484
|
+
content: [{ type: "text", text: `Error reopening milestone: ${result.error}` }],
|
|
485
|
+
details: { operation: "reopen_milestone", error: result.error },
|
|
486
|
+
isError: true,
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
return {
|
|
490
|
+
content: [{ type: "text", text: `Reopened milestone ${result.milestoneId}` }],
|
|
491
|
+
details: {
|
|
492
|
+
operation: "reopen_milestone",
|
|
493
|
+
milestoneId: result.milestoneId,
|
|
494
|
+
slicesReset: result.slicesReset,
|
|
495
|
+
tasksReset: result.tasksReset,
|
|
496
|
+
},
|
|
497
|
+
};
|
|
498
|
+
} catch (err) {
|
|
499
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
500
|
+
logError("tool", `reopen_milestone tool failed: ${msg}`, { tool: "gsd_milestone_reopen", error: String(err) });
|
|
501
|
+
return {
|
|
502
|
+
content: [{ type: "text", text: `Error reopening milestone: ${msg}` }],
|
|
503
|
+
details: { operation: "reopen_milestone", error: msg },
|
|
504
|
+
isError: true,
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
374
509
|
export async function executeSliceComplete(
|
|
375
510
|
params: SliceCompleteExecutorParams,
|
|
376
511
|
basePath: string = process.cwd(),
|
|
@@ -447,7 +447,9 @@ export const UNIT_MANIFESTS: Record<UnitType, UnitContextManifest> = {
|
|
|
447
447
|
codebaseMap: true,
|
|
448
448
|
preferences: "active-only",
|
|
449
449
|
contextMode: "research",
|
|
450
|
-
|
|
450
|
+
// Multi-slice research dispatches use the research-slice unit contract to
|
|
451
|
+
// fan out scout subagents that write .gsd research artifacts.
|
|
452
|
+
tools: TOOLS_PLANNING_DISPATCH_RECON,
|
|
451
453
|
artifacts: {
|
|
452
454
|
inline: ["roadmap", "milestone-research", "dependency-summaries", "templates"],
|
|
453
455
|
excerpt: [],
|
|
@@ -606,7 +608,9 @@ export const UNIT_MANIFESTS: Record<UnitType, UnitContextManifest> = {
|
|
|
606
608
|
codebaseMap: false,
|
|
607
609
|
preferences: "active-only",
|
|
608
610
|
contextMode: "verification",
|
|
609
|
-
|
|
611
|
+
// Gate evaluation fans out tester-style subagents, which read the slice
|
|
612
|
+
// plan and report via the DB-backed gate-result tool.
|
|
613
|
+
tools: TOOLS_PLANNING_DISPATCH_REVIEW,
|
|
610
614
|
artifacts: {
|
|
611
615
|
inline: ["slice-plan", "prior-task-summaries"],
|
|
612
616
|
excerpt: [],
|
|
@@ -734,3 +738,32 @@ export const UNIT_MANIFESTS: Record<UnitType, UnitContextManifest> = {
|
|
|
734
738
|
export function resolveManifest(unitType: string): UnitContextManifest | null {
|
|
735
739
|
return (UNIT_MANIFESTS as Record<string, UnitContextManifest>)[unitType] ?? null;
|
|
736
740
|
}
|
|
741
|
+
|
|
742
|
+
export interface SubagentPermissionContract {
|
|
743
|
+
readonly allowed: boolean;
|
|
744
|
+
readonly allowedSubagents: readonly string[];
|
|
745
|
+
readonly toolsMode: ToolsPolicy["mode"] | "unknown";
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
export function compileSubagentPermissionContract(
|
|
749
|
+
policy: ToolsPolicy | null | undefined,
|
|
750
|
+
): SubagentPermissionContract {
|
|
751
|
+
if (!policy) {
|
|
752
|
+
return { allowed: false, allowedSubagents: [], toolsMode: "unknown" };
|
|
753
|
+
}
|
|
754
|
+
if (policy.mode === "all") {
|
|
755
|
+
return { allowed: true, allowedSubagents: ["*"], toolsMode: policy.mode };
|
|
756
|
+
}
|
|
757
|
+
if (policy.mode === "planning-dispatch") {
|
|
758
|
+
return {
|
|
759
|
+
allowed: true,
|
|
760
|
+
allowedSubagents: [...policy.allowedSubagents],
|
|
761
|
+
toolsMode: policy.mode,
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
return { allowed: false, allowedSubagents: [], toolsMode: policy.mode };
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
export function resolveSubagentPermissionContract(unitType: string): SubagentPermissionContract {
|
|
768
|
+
return compileSubagentPermissionContract(resolveManifest(unitType)?.tools);
|
|
769
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Project/App: GSD-2
|
|
2
|
+
// File Purpose: Host-owned verification verdict policy for auto-mode units.
|
|
3
|
+
|
|
4
|
+
import type { VerificationResult as VerificationGateResult } from "./types.js";
|
|
5
|
+
|
|
6
|
+
export type VerificationVerdictReason =
|
|
7
|
+
| "passed"
|
|
8
|
+
| "no-host-checks"
|
|
9
|
+
| "checks-failed";
|
|
10
|
+
|
|
11
|
+
export interface VerificationVerdict {
|
|
12
|
+
passed: boolean;
|
|
13
|
+
reason: VerificationVerdictReason;
|
|
14
|
+
retryable: boolean;
|
|
15
|
+
failureContext: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function decideVerificationVerdict(
|
|
19
|
+
unitType: string,
|
|
20
|
+
result: VerificationGateResult,
|
|
21
|
+
): VerificationVerdict {
|
|
22
|
+
if (unitType === "execute-task" && result.discoverySource === "none" && result.checks.length === 0) {
|
|
23
|
+
return {
|
|
24
|
+
passed: false,
|
|
25
|
+
reason: "no-host-checks",
|
|
26
|
+
retryable: false,
|
|
27
|
+
failureContext:
|
|
28
|
+
"No runnable host-owned verification command was discovered. Add project verification_commands or a runnable task-plan Verify command before completing this execute-task.",
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (!result.passed) {
|
|
33
|
+
return {
|
|
34
|
+
passed: false,
|
|
35
|
+
reason: "checks-failed",
|
|
36
|
+
retryable: true,
|
|
37
|
+
failureContext: "",
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
passed: true,
|
|
43
|
+
reason: "passed",
|
|
44
|
+
retryable: false,
|
|
45
|
+
failureContext: "",
|
|
46
|
+
};
|
|
47
|
+
}
|
|
@@ -65,6 +65,10 @@ export type LogComponent =
|
|
|
65
65
|
| "memory-embeddings" // Memory layer embedding generation
|
|
66
66
|
| "memory-ingest" // Memory layer ingestion pipeline
|
|
67
67
|
| "memory-backfill" // ADR-013: decisions->memories backfill
|
|
68
|
+
| "memory-consolidation" // ADR-013: legacy memory surface gap scanner
|
|
69
|
+
| "knowledge-backfill" // ADR-013: KNOWLEDGE.md->memories backfill
|
|
70
|
+
| "knowledge-projection" // ADR-013: KNOWLEDGE.md projection renderer
|
|
71
|
+
| "knowledge-capture" // ADR-013: KNOWLEDGE.md capture pipeline
|
|
68
72
|
| "memory-store" // Memory CRUD layer — surfaces SQLite/store-level faults (#4967)
|
|
69
73
|
| "context-mode" // Context-mode exec sandbox and compaction snapshot
|
|
70
74
|
| "preflight" // Clean-root preflight gate at milestone completion
|
|
@@ -1702,16 +1702,34 @@ export class WorktreeLifecycle {
|
|
|
1702
1702
|
}
|
|
1703
1703
|
|
|
1704
1704
|
/**
|
|
1705
|
-
* Restore `s.basePath` to `s.originalBasePath
|
|
1706
|
-
* No-op when `originalBasePath` is empty (fresh
|
|
1705
|
+
* Restore `s.basePath` to `s.originalBasePath`, chdir process cwd, and
|
|
1706
|
+
* rebuild `s.gitService`. No-op when `originalBasePath` is empty (fresh
|
|
1707
|
+
* sessions).
|
|
1707
1708
|
*
|
|
1708
1709
|
* Used by error/cleanup paths that need the session to behave as if the
|
|
1709
1710
|
* worktree was never entered. Does NOT teardown the worktree directory —
|
|
1710
1711
|
* callers that need teardown go through `exitMilestone({ merge: false })`.
|
|
1712
|
+
*
|
|
1713
|
+
* ADR-016 phase 3 (#5693): chdir lives inside the verb so callers do not
|
|
1714
|
+
* pair `restoreToProjectRoot()` with a redundant `process.chdir`. The
|
|
1715
|
+
* chdir runs BEFORE the throwable work (`rebuildGitService`, cache
|
|
1716
|
+
* invalidation) so that cleanup-path cwd is restored even if the
|
|
1717
|
+
* downstream rebuild throws. The chdir itself is best-effort; failure is
|
|
1718
|
+
* logged via debugLog and swallowed.
|
|
1711
1719
|
*/
|
|
1712
1720
|
restoreToProjectRoot(): void {
|
|
1713
1721
|
if (!this.s.originalBasePath) return;
|
|
1714
1722
|
this.s.basePath = this.s.originalBasePath;
|
|
1723
|
+
try {
|
|
1724
|
+
process.chdir(this.s.basePath);
|
|
1725
|
+
} catch (err) {
|
|
1726
|
+
debugLog("WorktreeLifecycle", {
|
|
1727
|
+
action: "restoreToProjectRoot",
|
|
1728
|
+
result: "chdir-failed",
|
|
1729
|
+
basePath: this.s.basePath,
|
|
1730
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1731
|
+
});
|
|
1732
|
+
}
|
|
1715
1733
|
rebuildGitService(this.s, this.deps);
|
|
1716
1734
|
invalidateAllCaches();
|
|
1717
1735
|
}
|