gsd-pi 2.80.0-dev.488219eb6 → 2.80.0-dev.4edec4620
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 +11 -3
- package/dist/resources/extensions/gsd/auto-dashboard.js +18 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +21 -10
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +19 -2
- package/dist/resources/extensions/gsd/guided-flow.js +6 -0
- package/dist/resources/extensions/gsd/health-widget.js +3 -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 +10 -10
- 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 +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.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 +10 -10
- package/dist/web/standalone/.next/server/middleware-build-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/package.json +1 -1
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/types.d.ts +2 -0
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/src/types.ts +3 -0
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +12 -1
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +5 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +8 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +7 -2
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +15 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +11 -0
- package/packages/pi-coding-agent/src/core/sdk.ts +7 -1
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +12 -3
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +41 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +20 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +20 -10
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +19 -2
- package/src/resources/extensions/gsd/guided-flow.ts +6 -0
- package/src/resources/extensions/gsd/health-widget.ts +3 -0
- package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +210 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +40 -1
- /package/dist/web/standalone/.next/static/{G68KoLv5claox_Dyd4pZn → eeMbUJZnoHp7l3SZHeXY9}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{G68KoLv5claox_Dyd4pZn → eeMbUJZnoHp7l3SZHeXY9}/_ssgManifest.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
ddf27c3bbbe27e53
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// GSD2 - Claude Code CLI provider stream adapter
|
|
1
2
|
/**
|
|
2
3
|
* Stream adapter: bridges the Claude Agent SDK into GSD's streamSimple contract.
|
|
3
4
|
*
|
|
@@ -16,6 +17,10 @@ import { dirname, join } from "node:path";
|
|
|
16
17
|
import { PartialMessageBuilder, ZERO_USAGE, mapUsage } from "./partial-builder.js";
|
|
17
18
|
import { buildWorkflowMcpServers } from "../gsd/workflow-mcp.js";
|
|
18
19
|
import { showInterviewRound } from "../shared/tui.js";
|
|
20
|
+
/** Resolve the workspace root for local Claude Code process execution. */
|
|
21
|
+
export function resolveClaudeCodeCwd(options) {
|
|
22
|
+
return options?.cwd && options.cwd.trim().length > 0 ? options.cwd : process.cwd();
|
|
23
|
+
}
|
|
19
24
|
/** Label used for the free-text fallback option in single-choice elicitation questions. */
|
|
20
25
|
const OTHER_OPTION_LABEL = "None of the above";
|
|
21
26
|
/** Regex pattern that identifies field names and descriptions that should be treated as sensitive/secure inputs. */
|
|
@@ -1051,8 +1056,9 @@ function mapThinkingLevelToAnthropicEffort(level, modelId) {
|
|
|
1051
1056
|
* behaviour pass `permissionMode: "bypassPermissions"` explicitly.
|
|
1052
1057
|
*/
|
|
1053
1058
|
export function buildSdkOptions(modelId, prompt, overrides, extraOptions = {}) {
|
|
1054
|
-
const { reasoning, ...sdkExtraOptions } = extraOptions;
|
|
1055
|
-
const
|
|
1059
|
+
const { reasoning, cwd, ...sdkExtraOptions } = extraOptions;
|
|
1060
|
+
const sdkCwd = typeof cwd === "string" && cwd.trim().length > 0 ? cwd : process.cwd();
|
|
1061
|
+
const mcpServers = buildWorkflowMcpServers(sdkCwd);
|
|
1056
1062
|
const permissionMode = overrides?.permissionMode ?? "bypassPermissions";
|
|
1057
1063
|
// Globally unblock the tools GSD expects Claude Code to run. When the
|
|
1058
1064
|
// workflow MCP server is available, prefer its `ask_user_questions` tool over
|
|
@@ -1090,7 +1096,7 @@ export function buildSdkOptions(modelId, prompt, overrides, extraOptions = {}) {
|
|
|
1090
1096
|
model: modelId,
|
|
1091
1097
|
includePartialMessages: true,
|
|
1092
1098
|
persistSession: true,
|
|
1093
|
-
cwd:
|
|
1099
|
+
cwd: sdkCwd,
|
|
1094
1100
|
permissionMode,
|
|
1095
1101
|
allowDangerouslySkipPermissions: permissionMode === "bypassPermissions",
|
|
1096
1102
|
settingSources: ["project"],
|
|
@@ -1352,12 +1358,14 @@ async function pumpSdkMessages(model, context, options, stream) {
|
|
|
1352
1358
|
const queryPrompt = buildSdkQueryPrompt(context, prompt);
|
|
1353
1359
|
const permissionMode = await resolveClaudePermissionMode();
|
|
1354
1360
|
const uiContext = options?.extensionUIContext;
|
|
1361
|
+
const cwd = resolveClaudeCodeCwd(options);
|
|
1355
1362
|
const canUseToolHandler = createClaudeCodeCanUseToolHandler(uiContext);
|
|
1356
1363
|
// When no UI is available (headless / auto-mode), auto-approve all
|
|
1357
1364
|
// tool requests. This replaces the old bypassPermissions workaround.
|
|
1358
1365
|
const canUseToolFallback = canUseToolHandler
|
|
1359
1366
|
?? (async (_toolName, _input, opts) => ({ behavior: "allow", toolUseID: opts.toolUseID }));
|
|
1360
1367
|
const sdkOpts = buildSdkOptions(modelId, prompt, { permissionMode }, {
|
|
1368
|
+
cwd,
|
|
1361
1369
|
reasoning: options?.reasoning,
|
|
1362
1370
|
canUseTool: canUseToolFallback,
|
|
1363
1371
|
...(uiContext
|
|
@@ -468,6 +468,20 @@ export function _resetWidgetModeForTests() {
|
|
|
468
468
|
export function updateProgressWidget(ctx, unitType, unitId, state, accessors, tierBadge) {
|
|
469
469
|
if (!ctx.hasUI)
|
|
470
470
|
return;
|
|
471
|
+
// Welcome header is a startup-only banner — permanently suppress it once
|
|
472
|
+
// auto-mode activates. The dashboard widget owns all status from here.
|
|
473
|
+
// Note: setHeader(undefined) restores the built-in header (logo +
|
|
474
|
+
// instructions). To actually render zero lines, install an empty header.
|
|
475
|
+
if (typeof ctx.ui?.setHeader === "function") {
|
|
476
|
+
ctx.ui.setHeader(() => ({
|
|
477
|
+
render() { return []; },
|
|
478
|
+
invalidate() { },
|
|
479
|
+
}));
|
|
480
|
+
}
|
|
481
|
+
// Clear wizard step badge — auto-mode owns the UI from this point
|
|
482
|
+
if (typeof ctx.ui?.setStatus === "function") {
|
|
483
|
+
ctx.ui.setStatus("gsd-step", undefined);
|
|
484
|
+
}
|
|
471
485
|
const verb = unitVerb(unitType);
|
|
472
486
|
const phaseLabel = unitPhaseLabel(unitType);
|
|
473
487
|
const mid = state.activeMilestone;
|
|
@@ -857,6 +871,10 @@ export function updateProgressWidget(ctx, unitType, unitId, state, accessors, ti
|
|
|
857
871
|
? lastCommit.message.slice(0, maxCommitLen - 1) + "…"
|
|
858
872
|
: lastCommit.message
|
|
859
873
|
: "";
|
|
874
|
+
// Step-mode guidance — shown above keyboard hints when auto is paused
|
|
875
|
+
if (accessors.isStepMode()) {
|
|
876
|
+
lines.push(`${pad}${theme.fg("accent", "→")} ${theme.fg("dim", "Ctrl+N to advance to next step · /gsd status for overview")}`);
|
|
877
|
+
}
|
|
860
878
|
// Hints line
|
|
861
879
|
const hintParts = [];
|
|
862
880
|
hintParts.push("esc pause");
|
|
@@ -66,16 +66,27 @@ async function installWelcomeHeader(ctx) {
|
|
|
66
66
|
remoteChannel = rc.channel;
|
|
67
67
|
}
|
|
68
68
|
catch { /* non-fatal */ }
|
|
69
|
-
ctx.ui.setHeader(() =>
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
width
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
69
|
+
ctx.ui.setHeader(() => {
|
|
70
|
+
let cachedLines;
|
|
71
|
+
let cachedWidth;
|
|
72
|
+
return {
|
|
73
|
+
render(width) {
|
|
74
|
+
if (cachedLines !== undefined && cachedWidth === width)
|
|
75
|
+
return cachedLines;
|
|
76
|
+
cachedLines = welcome.buildWelcomeScreenLines({
|
|
77
|
+
version: process.env.GSD_VERSION || "0.0.0",
|
|
78
|
+
remoteChannel,
|
|
79
|
+
width,
|
|
80
|
+
});
|
|
81
|
+
cachedWidth = width;
|
|
82
|
+
return cachedLines;
|
|
83
|
+
},
|
|
84
|
+
invalidate() {
|
|
85
|
+
cachedLines = undefined;
|
|
86
|
+
cachedWidth = undefined;
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
});
|
|
79
90
|
}
|
|
80
91
|
catch {
|
|
81
92
|
/* non-fatal */
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
// GSD2 - Write gate runtime persistence and policy guards.
|
|
2
|
+
import { copyFileSync, existsSync, lstatSync, mkdirSync, readFileSync, readlinkSync, realpathSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
|
|
2
3
|
import { isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
3
4
|
import { minimatch } from "minimatch";
|
|
4
5
|
import { getIsolationMode } from "../preferences.js";
|
|
@@ -116,6 +117,22 @@ function shouldPersistWriteGateSnapshot(env = process.env) {
|
|
|
116
117
|
function writeGateSnapshotPath(basePath) {
|
|
117
118
|
return join(basePath, ".gsd", "runtime", "write-gate-state.json");
|
|
118
119
|
}
|
|
120
|
+
function ensureWriteGateSnapshotDirectory(basePath) {
|
|
121
|
+
const gsdPath = join(basePath, ".gsd");
|
|
122
|
+
if (!existsSync(gsdPath)) {
|
|
123
|
+
try {
|
|
124
|
+
const stat = lstatSync(gsdPath);
|
|
125
|
+
if (stat.isSymbolicLink()) {
|
|
126
|
+
const target = readlinkSync(gsdPath);
|
|
127
|
+
mkdirSync(isAbsolute(target) ? target : resolve(basePath, target), { recursive: true });
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
// If .gsd truly does not exist, the runtime mkdir below will create it.
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
mkdirSync(join(gsdPath, "runtime"), { recursive: true });
|
|
135
|
+
}
|
|
119
136
|
function currentWriteGateSnapshot(basePath = process.cwd()) {
|
|
120
137
|
const state = getWriteGateState(basePath);
|
|
121
138
|
return {
|
|
@@ -129,7 +146,7 @@ function persistWriteGateSnapshot(basePath) {
|
|
|
129
146
|
if (!shouldPersistWriteGateSnapshot())
|
|
130
147
|
return;
|
|
131
148
|
const path = writeGateSnapshotPath(basePath);
|
|
132
|
-
|
|
149
|
+
ensureWriteGateSnapshotDirectory(basePath);
|
|
133
150
|
const tempPath = `${path}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
134
151
|
writeFileSync(tempPath, JSON.stringify(currentWriteGateSnapshot(basePath), null, 2), "utf-8");
|
|
135
152
|
try {
|
|
@@ -1844,6 +1844,7 @@ export async function showSmartEntry(ctx, pi, basePath, options) {
|
|
|
1844
1844
|
const isFirst = milestoneIds.length === 0;
|
|
1845
1845
|
if (isFirst) {
|
|
1846
1846
|
// First ever — skip wizard, just ask directly
|
|
1847
|
+
ctx.ui.setStatus("gsd-step", "New Milestone · answer the questions above to plan");
|
|
1847
1848
|
setPendingAutoStart(basePath, { ctx, pi, basePath, milestoneId: nextId, step: stepMode });
|
|
1848
1849
|
await dispatchWorkflow(pi, await prepareAndBuildDiscussPrompt(ctx, pi, nextId, `New project, milestone ${nextId}. Do NOT read or explore .gsd/ — it's empty scaffolding.`, basePath), "gsd-run", ctx, "discuss-milestone");
|
|
1849
1850
|
}
|
|
@@ -1870,6 +1871,7 @@ export async function showSmartEntry(ctx, pi, basePath, options) {
|
|
|
1870
1871
|
await runQuickTaskChoice(ctx, pi);
|
|
1871
1872
|
}
|
|
1872
1873
|
else if (choice === "new_milestone") {
|
|
1874
|
+
ctx.ui.setStatus("gsd-step", "New Milestone · answer the questions above to plan");
|
|
1873
1875
|
setPendingAutoStart(basePath, { ctx, pi, basePath, milestoneId: nextId, step: stepMode });
|
|
1874
1876
|
await dispatchWorkflow(pi, await prepareAndBuildDiscussPrompt(ctx, pi, nextId, `New milestone ${nextId}.`, basePath), "gsd-run", ctx, "discuss-milestone");
|
|
1875
1877
|
}
|
|
@@ -2042,6 +2044,7 @@ export async function showSmartEntry(ctx, pi, basePath, options) {
|
|
|
2042
2044
|
await runQuickTaskChoice(ctx, pi);
|
|
2043
2045
|
}
|
|
2044
2046
|
else if (choice === "plan") {
|
|
2047
|
+
ctx.ui.setStatus("gsd-step", "Planning Milestone · decomposing into slices");
|
|
2045
2048
|
setPendingAutoStart(basePath, { ctx, pi, basePath, milestoneId, step: stepMode });
|
|
2046
2049
|
await dispatchWorkflow(pi, await buildPlanMilestonePrompt(milestoneId, milestoneTitle, basePath), "gsd-run", ctx, "plan-milestone");
|
|
2047
2050
|
}
|
|
@@ -2166,6 +2169,7 @@ export async function showSmartEntry(ctx, pi, basePath, options) {
|
|
|
2166
2169
|
notYetMessage: "Run /gsd when ready.",
|
|
2167
2170
|
});
|
|
2168
2171
|
if (choice === "plan") {
|
|
2172
|
+
ctx.ui.setStatus("gsd-step", "Slice Planning · answer the questions above");
|
|
2169
2173
|
await dispatchWorkflow(pi, await buildPlanSlicePrompt(milestoneId, milestoneTitle, sliceId, sliceTitle, basePath), "gsd-run", ctx, "plan-slice");
|
|
2170
2174
|
}
|
|
2171
2175
|
else if (choice === "discuss") {
|
|
@@ -2225,6 +2229,7 @@ export async function showSmartEntry(ctx, pi, basePath, options) {
|
|
|
2225
2229
|
notYetMessage: "Run /gsd when ready.",
|
|
2226
2230
|
});
|
|
2227
2231
|
if (choice === "complete") {
|
|
2232
|
+
ctx.ui.setStatus("gsd-step", "Completing Slice · review changes above");
|
|
2228
2233
|
await dispatchWorkflow(pi, await buildCompleteSlicePrompt(milestoneId, milestoneTitle, sliceId, sliceTitle, basePath), "gsd-run", ctx, "complete-slice");
|
|
2229
2234
|
}
|
|
2230
2235
|
else if (choice === "status") {
|
|
@@ -2285,6 +2290,7 @@ export async function showSmartEntry(ctx, pi, basePath, options) {
|
|
|
2285
2290
|
return;
|
|
2286
2291
|
}
|
|
2287
2292
|
if (choice === "execute") {
|
|
2293
|
+
ctx.ui.setStatus("gsd-step", "Executing Task · follow progress above");
|
|
2288
2294
|
if (hasInterrupted) {
|
|
2289
2295
|
await dispatchWorkflow(pi, loadPrompt("guided-resume-task", {
|
|
2290
2296
|
milestoneId,
|
|
@@ -118,6 +118,9 @@ export function initHealthWidget(ctx) {
|
|
|
118
118
|
render(width) {
|
|
119
119
|
if (!cachedLines || cachedWidth !== width) {
|
|
120
120
|
cachedLines = buildHealthLines(data, width);
|
|
121
|
+
if (data.projectState === "active") {
|
|
122
|
+
cachedLines = [...cachedLines, _theme.fg("dim", " /gsd auto to run · /gsd status for overview · /gsd help")];
|
|
123
|
+
}
|
|
121
124
|
cachedWidth = width;
|
|
122
125
|
}
|
|
123
126
|
return cachedLines;
|