@opengsd/gsd-pi 1.0.2-dev.fb7ddf1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +8 -1
- package/dist/resources/extensions/gsd/auto/phases.js +7 -4
- package/dist/resources/extensions/gsd/auto.js +7 -4
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +7 -7
- 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/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +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.js +2 -2
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- 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 +3 -3
- 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/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +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 +7 -7
- package/dist/web/standalone/.next/server/chunks/1834.js +3 -3
- package/dist/web/standalone/.next/server/chunks/7039.js +4 -4
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- 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/app/_not-found/{page-8867401a0497345a.js → page-9d0456bae07ee738.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/layout-d5eb6f78269341a2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/{page-4dbe7cf7d6733ab1.js → page-3dbf4b75cbfa8ff0.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/main-app-91185bf25c4a9d61.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-687e13572ab5c769.js +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/package.json +6 -6
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +57 -26
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/session-manager.d.ts +12 -0
- package/packages/mcp-server/dist/session-manager.d.ts.map +1 -1
- package/packages/mcp-server/dist/session-manager.js +22 -0
- package/packages/mcp-server/dist/session-manager.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +124 -7
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +45 -0
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +38 -2
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/package.json +1 -1
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +9 -1
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +19 -5
- package/src/resources/extensions/gsd/auto/loop-deps.ts +5 -0
- package/src/resources/extensions/gsd/auto/phases.ts +7 -2
- package/src/resources/extensions/gsd/auto.ts +9 -4
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +66 -23
- package/src/resources/extensions/gsd/tests/complete-milestone-prompt-rendering.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +26 -2
- package/dist/web/standalone/.next/static/chunks/app/layout-7669bce99bfc10fd.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-40a5bbdf7ffc2008.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-7df29967b89ea48a.js +0 -1
- /package/dist/web/standalone/.next/static/{tH1tnDYt1E0hK9Ien73Z0 → QMnuAY25UqnNzPB_UqAWF}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{tH1tnDYt1E0hK9Ien73Z0 → QMnuAY25UqnNzPB_UqAWF}/_ssgManifest.js +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gsd/pi-coding-agent",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Coding agent CLI (vendored from earendil-works/pi)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"gsd": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"copy-assets": "node scripts/copy-assets.cjs"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@opengsd/contracts": "^1.0
|
|
36
|
+
"@opengsd/contracts": "^1.1.0",
|
|
37
37
|
"@mariozechner/jiti": "^2.6.2",
|
|
38
38
|
"@silvia-odwyer/photon-node": "0.3.4",
|
|
39
39
|
"chalk": "5.6.2",
|
|
@@ -53,11 +53,11 @@
|
|
|
53
53
|
"typebox": "1.1.38",
|
|
54
54
|
"undici": "7.26.0",
|
|
55
55
|
"yaml": "2.9.0",
|
|
56
|
-
"@gsd/agent-core": "^1.0
|
|
57
|
-
"@gsd/native": "^1.0
|
|
58
|
-
"@gsd/pi-agent-core": "^1.0
|
|
59
|
-
"@gsd/pi-ai": "^1.0
|
|
60
|
-
"@gsd/pi-tui": "^1.0
|
|
56
|
+
"@gsd/agent-core": "^1.1.0",
|
|
57
|
+
"@gsd/native": "^1.1.0",
|
|
58
|
+
"@gsd/pi-agent-core": "^1.1.0",
|
|
59
|
+
"@gsd/pi-ai": "^1.1.0",
|
|
60
|
+
"@gsd/pi-tui": "^1.1.0",
|
|
61
61
|
"@sinclair/typebox": "^0.34.41"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengsd/rpc-client",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Standalone RPC client SDK for GSD — zero internal dependencies",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"gsd": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"test": "node --test dist/rpc-client.test.js"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@opengsd/contracts": "^1.0
|
|
37
|
+
"@opengsd/contracts": "^1.1.0"
|
|
38
38
|
},
|
|
39
39
|
"engines": {
|
|
40
40
|
"node": ">=22.0.0"
|
package/pkg/package.json
CHANGED
|
@@ -351,6 +351,9 @@ export function buildPromptFromContext(context: Context, toolContext: PromptTool
|
|
|
351
351
|
const toolSearchLine = toolContext.workflowMcpServerName
|
|
352
352
|
? "- ToolSearch is NOT available — never use it to discover tools; invoke the MCP tool directly\n"
|
|
353
353
|
: "- ToolSearch is NOT available — never use it to discover tools\n";
|
|
354
|
+
const browserToolLine =
|
|
355
|
+
"- Pi/GSD browser_* tools from prior context (for example browser_navigate, browser_find, browser_evaluate, browser_close) are not Claude Code tools. " +
|
|
356
|
+
"Never use ToolSearch to select browser_* tools; for browser verification, use Bash to run a local Playwright/Node check unless an explicit browser MCP tool is already listed.\n";
|
|
354
357
|
|
|
355
358
|
// The prior system context lists pi-native tool names (lowercase: bash, read, gsd_exec, etc.)
|
|
356
359
|
// but this process runs inside Claude Code where tool names differ. Inject a remapping note
|
|
@@ -362,6 +365,7 @@ export function buildPromptFromContext(context: Context, toolContext: PromptTool
|
|
|
362
365
|
"- Shell commands: 'Bash' (not 'bash')\n" +
|
|
363
366
|
"- File operations: 'Read', 'Write', 'Edit', 'Glob', 'Grep' (PascalCase, not lowercase)\n" +
|
|
364
367
|
workflowToolLine +
|
|
368
|
+
browserToolLine +
|
|
365
369
|
toolSearchLine +
|
|
366
370
|
"</tool_context>",
|
|
367
371
|
);
|
|
@@ -1523,7 +1527,11 @@ export function buildSdkOptions(
|
|
|
1523
1527
|
const workflowMcpTools = filteredMcpServers
|
|
1524
1528
|
? Object.keys(filteredMcpServers).map((serverName) => `mcp__${serverName}__*`)
|
|
1525
1529
|
: (!workflowExplicitlyBlocked && workflowServerName ? [`mcp__${workflowServerName}__*`] : []);
|
|
1526
|
-
const disallowedTools: string[] = [...(
|
|
1530
|
+
const disallowedTools: string[] = [...new Set([
|
|
1531
|
+
"ToolSearch",
|
|
1532
|
+
...(workflowMcpTools.length > 0 ? ["AskUserQuestion"] : []),
|
|
1533
|
+
...extraDisallowedTools,
|
|
1534
|
+
])];
|
|
1527
1535
|
const allowedTools = [
|
|
1528
1536
|
"Read",
|
|
1529
1537
|
"Write",
|
|
@@ -431,6 +431,20 @@ describe("stream-adapter — no transcript fabrication (#4102)", () => {
|
|
|
431
431
|
assert.ok(!prompt.includes("mcp__gsd-workflow__<tool_name>"));
|
|
432
432
|
assert.ok(!prompt.includes("mcp__gsd-workflow__gsd_exec"));
|
|
433
433
|
});
|
|
434
|
+
|
|
435
|
+
test("buildPromptFromContext remaps pi-native browser tools for Claude Code", () => {
|
|
436
|
+
const context: Context = {
|
|
437
|
+
systemPrompt: "Browser verification: use browser_find and browser_navigate.",
|
|
438
|
+
messages: [{ role: "user", content: "Verify the app" } as Message],
|
|
439
|
+
};
|
|
440
|
+
|
|
441
|
+
const prompt = buildPromptFromContext(context, { workflowMcpServerName: "gsd-workflow" });
|
|
442
|
+
|
|
443
|
+
assert.ok(prompt.includes("browser_navigate"), "remap should name stale browser tool examples");
|
|
444
|
+
assert.ok(prompt.includes("not Claude Code tools"), "remap should explain browser_* is unavailable in Claude Code");
|
|
445
|
+
assert.ok(prompt.includes("Never use ToolSearch to select browser_* tools"));
|
|
446
|
+
assert.ok(prompt.includes("Bash to run a local Playwright/Node check"));
|
|
447
|
+
});
|
|
434
448
|
});
|
|
435
449
|
|
|
436
450
|
describe("stream-adapter — Claude Code external tool results", () => {
|
|
@@ -925,7 +939,7 @@ describe("stream-adapter — session persistence (#2859)", () => {
|
|
|
925
939
|
assert.equal(srv.env.GSD_CLI_PATH, "/tmp/gsd");
|
|
926
940
|
assert.equal(srv.env.GSD_PERSIST_WRITE_GATE_STATE, "1");
|
|
927
941
|
assert.equal(srv.env.GSD_WORKFLOW_PROJECT_ROOT, "/tmp/project");
|
|
928
|
-
assert.deepEqual(options.disallowedTools, ["AskUserQuestion"]);
|
|
942
|
+
assert.deepEqual(options.disallowedTools, ["ToolSearch", "AskUserQuestion"]);
|
|
929
943
|
assert.deepEqual(options.allowedTools, [
|
|
930
944
|
"Read",
|
|
931
945
|
"Write",
|
|
@@ -961,7 +975,7 @@ describe("stream-adapter — session persistence (#2859)", () => {
|
|
|
961
975
|
const options = buildSdkOptions("claude-sonnet-4-20250514", "test");
|
|
962
976
|
const mcpServers = options.mcpServers as Record<string, any>;
|
|
963
977
|
assert.ok(mcpServers?.["custom-workflow"], "expected custom workflow server config");
|
|
964
|
-
assert.deepEqual(options.disallowedTools, ["AskUserQuestion"]);
|
|
978
|
+
assert.deepEqual(options.disallowedTools, ["ToolSearch", "AskUserQuestion"]);
|
|
965
979
|
assert.deepEqual(options.allowedTools, [
|
|
966
980
|
"Read",
|
|
967
981
|
"Write",
|
|
@@ -1005,9 +1019,9 @@ describe("stream-adapter — session persistence (#2859)", () => {
|
|
|
1005
1019
|
const mcpServers = (options as any).mcpServers;
|
|
1006
1020
|
if (mcpServers) {
|
|
1007
1021
|
assert.ok(mcpServers["gsd-workflow"], "if present, must be gsd-workflow");
|
|
1008
|
-
assert.deepEqual((options as any).disallowedTools, ["AskUserQuestion"]);
|
|
1022
|
+
assert.deepEqual((options as any).disallowedTools, ["ToolSearch", "AskUserQuestion"]);
|
|
1009
1023
|
} else {
|
|
1010
|
-
assert.deepEqual((options as any).disallowedTools, []);
|
|
1024
|
+
assert.deepEqual((options as any).disallowedTools, ["ToolSearch"]);
|
|
1011
1025
|
}
|
|
1012
1026
|
rmSync(emptyDir, { recursive: true, force: true });
|
|
1013
1027
|
} finally {
|
|
@@ -1046,7 +1060,7 @@ describe("stream-adapter — session persistence (#2859)", () => {
|
|
|
1046
1060
|
assert.equal(srv.env.GSD_CLI_PATH, "/tmp/gsd");
|
|
1047
1061
|
assert.equal(srv.env.GSD_PERSIST_WRITE_GATE_STATE, "1");
|
|
1048
1062
|
assert.equal(srv.env.GSD_WORKFLOW_PROJECT_ROOT, resolvedRepoDir);
|
|
1049
|
-
assert.deepEqual(options.disallowedTools, ["AskUserQuestion"]);
|
|
1063
|
+
assert.deepEqual(options.disallowedTools, ["ToolSearch", "AskUserQuestion"]);
|
|
1050
1064
|
} finally {
|
|
1051
1065
|
process.chdir(originalCwd);
|
|
1052
1066
|
rmSync(repoDir, { recursive: true, force: true });
|
|
@@ -33,6 +33,11 @@ export interface StopAutoOptions {
|
|
|
33
33
|
milestoneTitle?: string | null;
|
|
34
34
|
allMilestonesComplete?: boolean;
|
|
35
35
|
};
|
|
36
|
+
/**
|
|
37
|
+
* Foreground closeout-boundary stops already have the useful final surface in
|
|
38
|
+
* the transcript. Preserve it instead of installing a replacement widget.
|
|
39
|
+
*/
|
|
40
|
+
preserveCloseoutTranscript?: boolean;
|
|
36
41
|
/** Preserve, rather than merge, a completed milestone during stop cleanup. */
|
|
37
42
|
preserveCompletedMilestoneBranch?: boolean;
|
|
38
43
|
}
|
|
@@ -583,6 +583,7 @@ async function restorePreflightStashOrStop(
|
|
|
583
583
|
export async function _runMilestoneMergeWithStashRestore(
|
|
584
584
|
ic: IterationContext,
|
|
585
585
|
milestoneId: string,
|
|
586
|
+
options: { preserveCloseoutTranscript?: boolean } = {},
|
|
586
587
|
): Promise<{ action: "break"; reason: string } | null> {
|
|
587
588
|
const { ctx, pi, s, deps } = ic;
|
|
588
589
|
|
|
@@ -597,6 +598,7 @@ export async function _runMilestoneMergeWithStashRestore(
|
|
|
597
598
|
: `Pre-merge dirty working tree overlaps milestone ${milestoneId}`;
|
|
598
599
|
await deps.stopAuto(ctx, pi, reason, {
|
|
599
600
|
preserveCompletedMilestoneBranch: true,
|
|
601
|
+
preserveCloseoutTranscript: options.preserveCloseoutTranscript,
|
|
600
602
|
});
|
|
601
603
|
return {
|
|
602
604
|
action: "break",
|
|
@@ -677,6 +679,7 @@ export async function _runMilestoneMergeWithStashRestore(
|
|
|
677
679
|
export async function _runMilestoneMergeOnceWithStashRestore(
|
|
678
680
|
ic: IterationContext,
|
|
679
681
|
milestoneId: string,
|
|
682
|
+
options: { preserveCloseoutTranscript?: boolean } = {},
|
|
680
683
|
): Promise<{ action: "break"; reason: string } | null> {
|
|
681
684
|
if (ic.s.milestoneMergedInPhases) {
|
|
682
685
|
debugLog("autoLoop", {
|
|
@@ -686,7 +689,7 @@ export async function _runMilestoneMergeOnceWithStashRestore(
|
|
|
686
689
|
});
|
|
687
690
|
return null;
|
|
688
691
|
}
|
|
689
|
-
return _runMilestoneMergeWithStashRestore(ic, milestoneId);
|
|
692
|
+
return _runMilestoneMergeWithStashRestore(ic, milestoneId, options);
|
|
690
693
|
}
|
|
691
694
|
|
|
692
695
|
async function emitCancelledUnitEnd(
|
|
@@ -3063,7 +3066,9 @@ export async function runFinalize(
|
|
|
3063
3066
|
}
|
|
3064
3067
|
|
|
3065
3068
|
if (preUnitSnapshot?.type === "complete-milestone" && s.currentMilestoneId) {
|
|
3066
|
-
const stop = await _runMilestoneMergeOnceWithStashRestore(ic, s.currentMilestoneId
|
|
3069
|
+
const stop = await _runMilestoneMergeOnceWithStashRestore(ic, s.currentMilestoneId, {
|
|
3070
|
+
preserveCloseoutTranscript: true,
|
|
3071
|
+
});
|
|
3067
3072
|
if (stop) {
|
|
3068
3073
|
clearFinalizingUnit();
|
|
3069
3074
|
return stop;
|
|
@@ -1381,9 +1381,13 @@ export async function stopAuto(
|
|
|
1381
1381
|
const loadedPreferences = loadEffectiveGSDPreferences(s.basePath || undefined)?.preferences;
|
|
1382
1382
|
const stopNotificationPrefix = formatAutoStopNotificationPrefix(reason);
|
|
1383
1383
|
const displayReason = formatAutoStopDisplayReason(reason);
|
|
1384
|
+
const isHeadlessStop = process.env.GSD_HEADLESS === "1";
|
|
1384
1385
|
const completionStopRequested = Boolean(options.completionWidget);
|
|
1385
|
-
const
|
|
1386
|
-
|
|
1386
|
+
const preserveCloseoutTranscript = !isHeadlessStop && (
|
|
1387
|
+
options.preserveCloseoutTranscript ?? completionStopRequested
|
|
1388
|
+
);
|
|
1389
|
+
const installCompletionWidget = completionStopRequested && !preserveCloseoutTranscript;
|
|
1390
|
+
const preserveCompletionSurface = completionStopRequested || preserveCloseoutTranscript;
|
|
1387
1391
|
s.completionStopInProgress = preserveCompletionSurface;
|
|
1388
1392
|
|
|
1389
1393
|
// #4764 — telemetry: record the exit reason, isolation mode, whether an auto
|
|
@@ -1808,8 +1812,9 @@ export async function stopAuto(
|
|
|
1808
1812
|
if (installCompletionWidget) {
|
|
1809
1813
|
// Completion stops keep the durable final closeout surface visible.
|
|
1810
1814
|
} else if (preserveCompletionSurface) {
|
|
1811
|
-
|
|
1812
|
-
|
|
1815
|
+
// Foreground closeout-boundary stops preserve the transcript that the
|
|
1816
|
+
// completing unit already printed. Avoid replacing it with a widget or
|
|
1817
|
+
// clearing the progress slot, which can push the closeout into scrollback.
|
|
1813
1818
|
} else {
|
|
1814
1819
|
ctx?.ui.setWidget("gsd-progress", undefined);
|
|
1815
1820
|
const status = isBlockedStopReason(reason) ? "blocked" : reason?.toLowerCase().includes("fail") ? "failed" : "stopped";
|
|
@@ -84,7 +84,7 @@ Subagents report only; they do not write user source. Fold any findings into Dec
|
|
|
84
84
|
- `deviations` (string) — Deviations from the original plan
|
|
85
85
|
|
|
86
86
|
14. Do not commit manually — the system auto-commits your changes after this unit completes.
|
|
87
|
-
-
|
|
87
|
+
- After `gsd_complete_milestone` succeeds, emit only one closeout line: "Milestone {{milestoneId}} complete." Do not add a second final-status block, repeat the tool result, or restate the closeout summary.
|
|
88
88
|
|
|
89
89
|
**Important:** Do NOT skip code-change, success-criteria, or definition-of-done verification (steps 4-6). The summary must reflect verified outcomes. Verification failures block completion; there is no override. If a verification tool fails, errors, or returns unexpected output, treat it as failure.
|
|
90
90
|
|
|
@@ -486,7 +486,7 @@ test("rerootCommandSession refreshes command workspace to project root", async (
|
|
|
486
486
|
assert.deepEqual(calls, ["/project/root"]);
|
|
487
487
|
});
|
|
488
488
|
|
|
489
|
-
test("stopAuto foreground completion closeout reroots session and
|
|
489
|
+
test("stopAuto foreground completion closeout reroots session and preserves the transcript surface", async (t) => {
|
|
490
490
|
const base = mkdtempSync(join(tmpdir(), "gsd-completion-stop-"));
|
|
491
491
|
const previousCwd = process.cwd();
|
|
492
492
|
const widgetCalls: Array<[string, unknown]> = [];
|
|
@@ -604,19 +604,11 @@ test("stopAuto foreground completion closeout reroots session and installs the d
|
|
|
604
604
|
assert.deepEqual(newSessionWorkspaces, [base], "completion stop must reroot command session to original project root");
|
|
605
605
|
assert.equal(restoreCalls, 1, "completion stop must restore project root through lifecycle");
|
|
606
606
|
assert.equal(realpathSync(process.cwd()), realpathSync(base), "completion stop must chdir back to project root");
|
|
607
|
-
const lastProgressWidget = widgetCalls.filter(([key]) => key === "gsd-progress").at(-1);
|
|
608
607
|
assert.equal(
|
|
609
|
-
typeof
|
|
610
|
-
|
|
611
|
-
"foreground completion stop must
|
|
608
|
+
widgetCalls.some(([key, value]) => key === "gsd-progress" && typeof value === "function"),
|
|
609
|
+
false,
|
|
610
|
+
"foreground completion stop must not install a replacement roll-up widget over the transcript",
|
|
612
611
|
);
|
|
613
|
-
const rollup = (lastProgressWidget?.[1] as any)(
|
|
614
|
-
{ requestRender() {} },
|
|
615
|
-
{ fg: (_color: string, text: string) => text, bold: (text: string) => text },
|
|
616
|
-
).render(140).join("\n");
|
|
617
|
-
assert.match(rollup, /Milestone M003 roll-up/);
|
|
618
|
-
assert.match(rollup, /Budget tracking/);
|
|
619
|
-
assert.match(rollup, /Users can see what shipped without opening a fresh session/);
|
|
620
612
|
assert.ok(
|
|
621
613
|
notifications.every(message => !message.includes("/gsd auto to resume")),
|
|
622
614
|
"completion stop notification must not tell users to resume a finished auto run",
|
|
@@ -739,7 +731,66 @@ test("stopAuto completion closeout emits a headless terminal notification withou
|
|
|
739
731
|
}
|
|
740
732
|
});
|
|
741
733
|
|
|
742
|
-
test("stopAuto
|
|
734
|
+
test("stopAuto closeout-transcript preservation suppresses generic stop widgets", async () => {
|
|
735
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-closeout-transcript-stop-"));
|
|
736
|
+
const previousCwd = process.cwd();
|
|
737
|
+
const widgetCalls: Array<[string, unknown]> = [];
|
|
738
|
+
const notifications: string[] = [];
|
|
739
|
+
|
|
740
|
+
autoSession.reset();
|
|
741
|
+
autoSession.active = true;
|
|
742
|
+
autoSession.paused = false;
|
|
743
|
+
autoSession.basePath = base;
|
|
744
|
+
autoSession.originalBasePath = base;
|
|
745
|
+
|
|
746
|
+
try {
|
|
747
|
+
await stopAuto(
|
|
748
|
+
{
|
|
749
|
+
hasUI: true,
|
|
750
|
+
ui: {
|
|
751
|
+
setStatus: () => {},
|
|
752
|
+
setWidget: (key: string, value: unknown) => {
|
|
753
|
+
widgetCalls.push([key, value]);
|
|
754
|
+
},
|
|
755
|
+
setHeader: () => {},
|
|
756
|
+
notify: (message: string) => {
|
|
757
|
+
notifications.push(message);
|
|
758
|
+
},
|
|
759
|
+
},
|
|
760
|
+
modelRegistry: { find: () => null },
|
|
761
|
+
} as any,
|
|
762
|
+
{ events: { emit: () => {} } } as any,
|
|
763
|
+
"Pre-merge dirty working tree overlaps milestone M003",
|
|
764
|
+
{
|
|
765
|
+
preserveCloseoutTranscript: true,
|
|
766
|
+
preserveCompletedMilestoneBranch: true,
|
|
767
|
+
},
|
|
768
|
+
);
|
|
769
|
+
|
|
770
|
+
assert.equal(
|
|
771
|
+
widgetCalls.some(([key]) => key === "gsd-outcome"),
|
|
772
|
+
false,
|
|
773
|
+
"closeout-preserving stop must not install a generic auto-stopped outcome",
|
|
774
|
+
);
|
|
775
|
+
assert.equal(
|
|
776
|
+
widgetCalls.some(([key, value]) => key === "gsd-progress" && value === undefined),
|
|
777
|
+
false,
|
|
778
|
+
"closeout-preserving stop must not clear the transcript/progress surface",
|
|
779
|
+
);
|
|
780
|
+
assert.equal(
|
|
781
|
+
notifications.some(message => message.includes("Auto-mode stopped")),
|
|
782
|
+
false,
|
|
783
|
+
"closeout-preserving stop must not append a duplicate terminal stop notification",
|
|
784
|
+
);
|
|
785
|
+
} finally {
|
|
786
|
+
try { closeDatabase(); } catch { /* noop */ }
|
|
787
|
+
autoSession.reset();
|
|
788
|
+
process.chdir(previousCwd);
|
|
789
|
+
rmSync(base, { recursive: true, force: true });
|
|
790
|
+
}
|
|
791
|
+
});
|
|
792
|
+
|
|
793
|
+
test("stopAuto foreground all-complete closeout preserves the transcript surface", async () => {
|
|
743
794
|
const base = mkdtempSync(join(tmpdir(), "gsd-all-complete-closeout-"));
|
|
744
795
|
const previousCwd = process.cwd();
|
|
745
796
|
const widgetCalls: Array<[string, unknown]> = [];
|
|
@@ -789,17 +840,9 @@ test("stopAuto foreground all-complete closeout leaves a durable roll-up as the
|
|
|
789
840
|
|
|
790
841
|
assert.equal(
|
|
791
842
|
widgetCalls.some(([key, value]) => key === "gsd-progress" && typeof value === "function"),
|
|
792
|
-
|
|
793
|
-
"foreground all-complete closeout must
|
|
843
|
+
false,
|
|
844
|
+
"foreground all-complete closeout must not replace the visible transcript with a roll-up widget",
|
|
794
845
|
);
|
|
795
|
-
const finalProgress = widgetCalls.filter(([key]) => key === "gsd-progress").at(-1);
|
|
796
|
-
assert.equal(typeof finalProgress?.[1], "function", "foreground all-complete closeout keeps the roll-up visible");
|
|
797
|
-
const rollup = (finalProgress?.[1] as any)(
|
|
798
|
-
{ requestRender() {} },
|
|
799
|
-
{ fg: (_color: string, text: string) => text, bold: (text: string) => text },
|
|
800
|
-
).render(140).join("\n");
|
|
801
|
-
assert.match(rollup, /All milestones complete/);
|
|
802
|
-
assert.match(rollup, /Review the roll-up/);
|
|
803
846
|
const finalOutcome = widgetCalls.filter(([key]) => key === "gsd-outcome").at(-1);
|
|
804
847
|
assert.equal(finalOutcome?.[1], undefined, "foreground all-complete closeout must not add an outcome replacement");
|
|
805
848
|
} finally {
|
|
@@ -43,5 +43,6 @@ test("complete milestone prompt renders compact verification and completion guid
|
|
|
43
43
|
assert.match(prompt, /self-diff/i);
|
|
44
44
|
assert.match(prompt, /GSD-(?:Task|Unit)/);
|
|
45
45
|
assert.match(prompt, /Milestone M001 complete/);
|
|
46
|
+
assert.match(prompt, /Do not add a second final-status block/);
|
|
46
47
|
assert.doesNotMatch(prompt, /\{\{[a-zA-Z][a-zA-Z0-9_]*\}\}/);
|
|
47
48
|
});
|
|
@@ -17,7 +17,7 @@ interface CallLog {
|
|
|
17
17
|
mergeCalls: number;
|
|
18
18
|
postflightCalls: number;
|
|
19
19
|
stopAutoCalls: Array<string | undefined>;
|
|
20
|
-
stopAutoOptions: Array<{ preserveCompletedMilestoneBranch?: boolean } | undefined>;
|
|
20
|
+
stopAutoOptions: Array<{ preserveCompletedMilestoneBranch?: boolean; preserveCloseoutTranscript?: boolean } | undefined>;
|
|
21
21
|
pauseAutoCalls: Array<string | undefined>;
|
|
22
22
|
notifyCalls: Array<{ message: string; level: string }>;
|
|
23
23
|
milestoneMergedInPhases: boolean;
|
|
@@ -104,7 +104,7 @@ function buildIc(opts: {
|
|
|
104
104
|
_c?: unknown,
|
|
105
105
|
_p?: unknown,
|
|
106
106
|
reason?: string,
|
|
107
|
-
options?: { preserveCompletedMilestoneBranch?: boolean },
|
|
107
|
+
options?: { preserveCompletedMilestoneBranch?: boolean; preserveCloseoutTranscript?: boolean },
|
|
108
108
|
) => {
|
|
109
109
|
log.stopAutoCalls.push(reason);
|
|
110
110
|
log.stopAutoOptions.push(options);
|
|
@@ -293,6 +293,30 @@ test("dirty overlap: preflight stops before merge and postflight restore", async
|
|
|
293
293
|
);
|
|
294
294
|
});
|
|
295
295
|
|
|
296
|
+
test("dirty overlap after closeout preserves the visible closeout transcript", async () => {
|
|
297
|
+
const { ic, log } = buildIc({
|
|
298
|
+
preflightResult: PREFLIGHT_BLOCKED,
|
|
299
|
+
mergeBehavior: "succeed",
|
|
300
|
+
postflightResult: POP_OK,
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
const result = await _runMilestoneMergeWithStashRestore(ic, "M002", {
|
|
304
|
+
preserveCloseoutTranscript: true,
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
assert.deepEqual(result, {
|
|
308
|
+
action: "break",
|
|
309
|
+
reason: "preflight-dirty-overlap",
|
|
310
|
+
});
|
|
311
|
+
assert.equal(log.mergeCalls, 0, "blocked preflight must not start milestone merge");
|
|
312
|
+
assert.equal(log.stopAutoOptions[0]?.preserveCompletedMilestoneBranch, true);
|
|
313
|
+
assert.equal(
|
|
314
|
+
log.stopAutoOptions[0]?.preserveCloseoutTranscript,
|
|
315
|
+
true,
|
|
316
|
+
"post-closeout merge blocks must not replace the closeout transcript with a stop widget",
|
|
317
|
+
);
|
|
318
|
+
});
|
|
319
|
+
|
|
296
320
|
test("unmerged conflicts: preflight stops before merge and postflight restore", async () => {
|
|
297
321
|
const { ic, log } = buildIc({
|
|
298
322
|
preflightResult: PREFLIGHT_UNMERGED,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[7177],{2022:()=>{},40275:(e,r,s)=>{Promise.resolve().then(s.t.bind(s,2022,23)),Promise.resolve().then(s.bind(s,66998)),Promise.resolve().then(s.bind(s,48333))},48333:(e,r,s)=>{"use strict";s.d(r,{Toaster:()=>a});var o=s(27552),t=s(52919),n=s(80413);let a=({...e})=>{let{theme:r="system"}=(0,t.D)();return(0,o.jsx)(n.l$,{theme:r,className:"toaster group",style:{"--normal-bg":"var(--popover)","--normal-text":"var(--popover-foreground)","--normal-border":"var(--border)"},...e})}},66998:(e,r,s)=>{"use strict";s.d(r,{ThemeProvider:()=>n});var o=s(27552);s(32140);var t=s(52919);function n({children:e,...r}){return(0,o.jsx)(t.N,{...r,children:e})}}},e=>{e.O(0,[789,963,806,4630,7358],()=>e(e.s=40275)),_N_E=e.O()}]);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[7358],{6415:(e,s,n)=>{Promise.resolve().then(n.t.bind(n,1278,23)),Promise.resolve().then(n.t.bind(n,3591,23)),Promise.resolve().then(n.t.bind(n,99333,23)),Promise.resolve().then(n.t.bind(n,14382,23)),Promise.resolve().then(n.t.bind(n,15398,23)),Promise.resolve().then(n.t.bind(n,11948,23)),Promise.resolve().then(n.t.bind(n,61903,23)),Promise.resolve().then(n.bind(n,85742))},98156:()=>{}},e=>{var s=s=>e(e.s=s);e.O(0,[806,4630],()=>(s(74274),s(6415))),_N_E=e.O()}]);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[9337],{88935:(e,s,_)=>{Promise.resolve().then(_.t.bind(_,1278,23))}},e=>{e.O(0,[806,4630,7358],()=>e(e.s=88935)),_N_E=e.O()}]);
|
|
File without changes
|
|
File without changes
|