gsd-pi 2.53.0 → 2.54.0-dev.16631ca
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/cli.js +19 -19
- package/dist/headless-ui.d.ts +29 -3
- package/dist/headless-ui.js +221 -28
- package/dist/headless.d.ts +11 -0
- package/dist/headless.js +238 -41
- package/dist/resources/extensions/bg-shell/bg-shell-lifecycle.js +2 -2
- package/dist/resources/extensions/bg-shell/utilities.js +34 -5
- package/dist/resources/extensions/gsd/auto/phases.js +10 -1
- package/dist/resources/extensions/gsd/auto-dispatch.js +1 -1
- package/dist/resources/extensions/gsd/auto-model-selection.js +17 -1
- package/dist/resources/extensions/gsd/auto-prompts.js +9 -0
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +18 -5
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +19 -19
- package/dist/web/standalone/.next/build-manifest.json +4 -4
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
- package/dist/web/standalone/.next/required-server-files.json +4 -4
- 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 +2 -2
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/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/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 +4 -4
- 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 +19 -19
- package/dist/web/standalone/.next/server/chunks/2229.js +2 -2
- package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
- 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/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/4024.82f2e2a838908338.js +9 -0
- package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-b950e4e384cc62b3.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-bca0e732db0dcec3.js → webpack-70adf6e3be5479ce.js} +1 -1
- 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/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/package.json +1 -1
- package/packages/mcp-server/README.md +6 -6
- package/packages/mcp-server/package.json +14 -4
- package/packages/mcp-server/src/cli.ts +1 -1
- package/packages/mcp-server/src/index.ts +1 -1
- package/packages/mcp-server/src/mcp-server.test.ts +2 -2
- package/packages/mcp-server/src/session-manager.ts +2 -2
- package/packages/mcp-server/src/types.ts +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +14 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/model-registry.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +16 -2
- package/packages/rpc-client/README.md +125 -0
- package/packages/rpc-client/examples/basic-usage.ts +13 -0
- package/packages/rpc-client/package.json +17 -3
- package/packages/rpc-client/src/index.ts +10 -0
- package/packages/rpc-client/src/jsonl.ts +64 -0
- package/packages/rpc-client/src/rpc-client.test.ts +568 -0
- package/packages/rpc-client/src/rpc-client.ts +666 -0
- package/packages/rpc-client/src/rpc-types.ts +399 -0
- package/packages/rpc-client/tsconfig.examples.json +17 -0
- package/packages/rpc-client/tsconfig.json +24 -0
- package/pkg/package.json +1 -1
- package/src/resources/extensions/bg-shell/bg-shell-lifecycle.ts +2 -2
- package/src/resources/extensions/bg-shell/utilities.ts +39 -4
- package/src/resources/extensions/gsd/auto/phases.ts +14 -2
- package/src/resources/extensions/gsd/auto-dispatch.ts +1 -1
- package/src/resources/extensions/gsd/auto-model-selection.ts +21 -1
- package/src/resources/extensions/gsd/auto-prompts.ts +15 -0
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +19 -6
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +139 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/plan-milestone-queue-context.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/register-extension-guard.test.ts +59 -0
- package/dist/web/standalone/.next/static/chunks/4024.87fd909ae0110f50.js +0 -9
- package/dist/web/standalone/.next/static/chunks/app/page-fbecd1237e2d6d1f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- /package/dist/web/standalone/.next/static/{mWBOLPnUoeaTGiD-vhu5O → 8yiPxQ52ue_s6qdrrAxsH}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{mWBOLPnUoeaTGiD-vhu5O → 8yiPxQ52ue_s6qdrrAxsH}/_ssgManifest.js +0 -0
package/dist/cli.js
CHANGED
|
@@ -103,19 +103,6 @@ const cliFlags = parseCliArgs(process.argv);
|
|
|
103
103
|
const isPrintMode = cliFlags.print || cliFlags.mode !== undefined;
|
|
104
104
|
// Early resource-skew check — must run before TTY gate so version mismatch
|
|
105
105
|
// errors surface even in non-TTY environments.
|
|
106
|
-
exitIfManagedResourcesAreNewer(agentDir);
|
|
107
|
-
// Early TTY check — must come before heavy initialization to avoid dangling
|
|
108
|
-
// handles that prevent process.exit() from completing promptly.
|
|
109
|
-
const hasSubcommand = cliFlags.messages.length > 0;
|
|
110
|
-
if (!process.stdin.isTTY && !isPrintMode && !hasSubcommand && !cliFlags.listModels && !cliFlags.web) {
|
|
111
|
-
process.stderr.write('[gsd] Error: Interactive mode requires a terminal (TTY).\n');
|
|
112
|
-
process.stderr.write('[gsd] Non-interactive alternatives:\n');
|
|
113
|
-
process.stderr.write('[gsd] gsd --print "your message" Single-shot prompt\n');
|
|
114
|
-
process.stderr.write('[gsd] gsd --mode rpc JSON-RPC over stdin/stdout\n');
|
|
115
|
-
process.stderr.write('[gsd] gsd --mode mcp MCP server over stdin/stdout\n');
|
|
116
|
-
process.stderr.write('[gsd] gsd --mode text "message" Text output mode\n');
|
|
117
|
-
process.exit(1);
|
|
118
|
-
}
|
|
119
106
|
async function ensureRtkBootstrap() {
|
|
120
107
|
if (ensureRtkBootstrap._done)
|
|
121
108
|
return;
|
|
@@ -136,6 +123,25 @@ async function ensureRtkBootstrap() {
|
|
|
136
123
|
process.stderr.write(`[gsd] Warning: RTK unavailable — continuing without shell-command compression (${rtkStatus.reason}).\n`);
|
|
137
124
|
}
|
|
138
125
|
}
|
|
126
|
+
// `gsd update` — update to the latest version via npm
|
|
127
|
+
if (cliFlags.messages[0] === 'update') {
|
|
128
|
+
const { runUpdate } = await import('./update-cmd.js');
|
|
129
|
+
await runUpdate();
|
|
130
|
+
process.exit(0);
|
|
131
|
+
}
|
|
132
|
+
exitIfManagedResourcesAreNewer(agentDir);
|
|
133
|
+
// Early TTY check — must come before heavy initialization to avoid dangling
|
|
134
|
+
// handles that prevent process.exit() from completing promptly.
|
|
135
|
+
const hasSubcommand = cliFlags.messages.length > 0;
|
|
136
|
+
if (!process.stdin.isTTY && !isPrintMode && !hasSubcommand && !cliFlags.listModels && !cliFlags.web) {
|
|
137
|
+
process.stderr.write('[gsd] Error: Interactive mode requires a terminal (TTY).\n');
|
|
138
|
+
process.stderr.write('[gsd] Non-interactive alternatives:\n');
|
|
139
|
+
process.stderr.write('[gsd] gsd --print "your message" Single-shot prompt\n');
|
|
140
|
+
process.stderr.write('[gsd] gsd --mode rpc JSON-RPC over stdin/stdout\n');
|
|
141
|
+
process.stderr.write('[gsd] gsd --mode mcp MCP server over stdin/stdout\n');
|
|
142
|
+
process.stderr.write('[gsd] gsd --mode text "message" Text output mode\n');
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
139
145
|
// `gsd <subcommand> --help` — show subcommand-specific help
|
|
140
146
|
const subcommand = cliFlags.messages[0];
|
|
141
147
|
if (subcommand && process.argv.includes('--help')) {
|
|
@@ -162,12 +168,6 @@ if (cliFlags.messages[0] === 'config') {
|
|
|
162
168
|
await runOnboarding(authStorage);
|
|
163
169
|
process.exit(0);
|
|
164
170
|
}
|
|
165
|
-
// `gsd update` — update to the latest version via npm
|
|
166
|
-
if (cliFlags.messages[0] === 'update') {
|
|
167
|
-
const { runUpdate } = await import('./update-cmd.js');
|
|
168
|
-
await runUpdate();
|
|
169
|
-
process.exit(0);
|
|
170
|
-
}
|
|
171
171
|
// `gsd web stop [path|all]` — stop web server before anything else
|
|
172
172
|
if (cliFlags.messages[0] === 'web' && cliFlags.messages[1] === 'stop') {
|
|
173
173
|
const webFlags = parseWebCliArgs(process.argv);
|
package/dist/headless-ui.d.ts
CHANGED
|
@@ -18,6 +18,32 @@ interface ExtensionUIRequest {
|
|
|
18
18
|
[key: string]: unknown;
|
|
19
19
|
}
|
|
20
20
|
export type { ExtensionUIRequest };
|
|
21
|
-
|
|
22
|
-
export
|
|
23
|
-
|
|
21
|
+
/** Context passed alongside an event for richer formatting. */
|
|
22
|
+
export interface ProgressContext {
|
|
23
|
+
verbose: boolean;
|
|
24
|
+
toolDuration?: number;
|
|
25
|
+
lastCost?: {
|
|
26
|
+
costUsd: number;
|
|
27
|
+
inputTokens: number;
|
|
28
|
+
outputTokens: number;
|
|
29
|
+
};
|
|
30
|
+
thinkingPreview?: string;
|
|
31
|
+
isError?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Produce a short human-readable summary of tool arguments.
|
|
35
|
+
* Returns a string like "path/to/file.ts" or "grep pattern *.ts" — never the
|
|
36
|
+
* full JSON blob.
|
|
37
|
+
*/
|
|
38
|
+
export declare function summarizeToolArgs(toolName: unknown, toolInput: unknown): string;
|
|
39
|
+
export declare function handleExtensionUIRequest(event: ExtensionUIRequest, client: RpcClient): void;
|
|
40
|
+
export declare function formatProgress(event: Record<string, unknown>, ctx: ProgressContext): string | null;
|
|
41
|
+
/**
|
|
42
|
+
* Format a thinking preview line from accumulated LLM text deltas.
|
|
43
|
+
*/
|
|
44
|
+
export declare function formatThinkingLine(text: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* Format a cost line (used for periodic cost updates in verbose mode).
|
|
47
|
+
*/
|
|
48
|
+
export declare function formatCostLine(costUsd: number, inputTokens: number, outputTokens: number): string;
|
|
49
|
+
export declare function startSupervisedStdinReader(client: RpcClient, onResponse: (id: string) => void): () => void;
|
package/dist/headless-ui.js
CHANGED
|
@@ -5,13 +5,107 @@
|
|
|
5
5
|
* formats progress events for stderr output, and reads orchestrator
|
|
6
6
|
* commands from stdin in supervised mode.
|
|
7
7
|
*/
|
|
8
|
-
import { attachJsonlLineReader
|
|
8
|
+
import { attachJsonlLineReader } from '@gsd/pi-coding-agent';
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// ANSI Color Helpers
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
const _c = {
|
|
13
|
+
reset: '\x1b[0m',
|
|
14
|
+
bold: '\x1b[1m',
|
|
15
|
+
dim: '\x1b[2m',
|
|
16
|
+
italic: '\x1b[3m',
|
|
17
|
+
red: '\x1b[31m',
|
|
18
|
+
green: '\x1b[32m',
|
|
19
|
+
yellow: '\x1b[33m',
|
|
20
|
+
cyan: '\x1b[36m',
|
|
21
|
+
gray: '\x1b[90m',
|
|
22
|
+
};
|
|
23
|
+
/** Build a no-op color map (all codes empty). */
|
|
24
|
+
function noColor() {
|
|
25
|
+
const nc = {};
|
|
26
|
+
for (const k of Object.keys(_c))
|
|
27
|
+
nc[k] = '';
|
|
28
|
+
return nc;
|
|
29
|
+
}
|
|
30
|
+
const colorsDisabled = !!process.env['NO_COLOR'] || !process.stderr.isTTY;
|
|
31
|
+
const c = colorsDisabled ? noColor() : _c;
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// Tool-Arg Summarizer
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
/**
|
|
36
|
+
* Produce a short human-readable summary of tool arguments.
|
|
37
|
+
* Returns a string like "path/to/file.ts" or "grep pattern *.ts" — never the
|
|
38
|
+
* full JSON blob.
|
|
39
|
+
*/
|
|
40
|
+
export function summarizeToolArgs(toolName, toolInput) {
|
|
41
|
+
const name = String(toolName ?? '');
|
|
42
|
+
const input = (toolInput && typeof toolInput === 'object') ? toolInput : {};
|
|
43
|
+
switch (name) {
|
|
44
|
+
case 'Read':
|
|
45
|
+
case 'read':
|
|
46
|
+
return shortPath(input.file_path) || '';
|
|
47
|
+
case 'Write':
|
|
48
|
+
case 'write':
|
|
49
|
+
return shortPath(input.file_path) || '';
|
|
50
|
+
case 'Edit':
|
|
51
|
+
case 'edit':
|
|
52
|
+
return shortPath(input.file_path) || '';
|
|
53
|
+
case 'Bash':
|
|
54
|
+
case 'bash': {
|
|
55
|
+
const cmd = String(input.command ?? '');
|
|
56
|
+
return cmd.length > 80 ? cmd.slice(0, 77) + '...' : cmd;
|
|
57
|
+
}
|
|
58
|
+
case 'Glob':
|
|
59
|
+
case 'glob':
|
|
60
|
+
return String(input.pattern ?? '');
|
|
61
|
+
case 'Grep':
|
|
62
|
+
case 'grep':
|
|
63
|
+
case 'Search':
|
|
64
|
+
case 'search': {
|
|
65
|
+
const pat = String(input.pattern ?? '');
|
|
66
|
+
const g = input.glob ? ` ${input.glob}` : '';
|
|
67
|
+
return `${pat}${g}`;
|
|
68
|
+
}
|
|
69
|
+
case 'Task':
|
|
70
|
+
case 'task': {
|
|
71
|
+
const desc = String(input.description ?? input.prompt ?? '');
|
|
72
|
+
return desc.length > 60 ? desc.slice(0, 57) + '...' : desc;
|
|
73
|
+
}
|
|
74
|
+
default: {
|
|
75
|
+
// Fallback: show first string-valued key up to 60 chars
|
|
76
|
+
for (const v of Object.values(input)) {
|
|
77
|
+
if (typeof v === 'string' && v.length > 0) {
|
|
78
|
+
return v.length > 60 ? v.slice(0, 57) + '...' : v;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return '';
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function shortPath(p) {
|
|
86
|
+
if (typeof p !== 'string')
|
|
87
|
+
return '';
|
|
88
|
+
// Strip common CWD prefix to save space
|
|
89
|
+
const cwd = process.cwd();
|
|
90
|
+
if (p.startsWith(cwd + '/'))
|
|
91
|
+
return p.slice(cwd.length + 1);
|
|
92
|
+
// Strip /Users/*/Developer/ prefix
|
|
93
|
+
return p.replace(/^\/Users\/[^/]+\/Developer\//, '');
|
|
94
|
+
}
|
|
95
|
+
// ---------------------------------------------------------------------------
|
|
96
|
+
// Format Duration
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
function formatDuration(ms) {
|
|
99
|
+
if (ms < 1000)
|
|
100
|
+
return `${ms}ms`;
|
|
101
|
+
const s = (ms / 1000).toFixed(1);
|
|
102
|
+
return `${s}s`;
|
|
103
|
+
}
|
|
9
104
|
// ---------------------------------------------------------------------------
|
|
10
105
|
// Extension UI Auto-Responder
|
|
11
106
|
// ---------------------------------------------------------------------------
|
|
12
|
-
export function handleExtensionUIRequest(event,
|
|
107
|
+
export function handleExtensionUIRequest(event, client) {
|
|
13
108
|
const { id, method } = event;
|
|
14
|
-
let response;
|
|
15
109
|
switch (method) {
|
|
16
110
|
case 'select': {
|
|
17
111
|
// Lock-guard prompts list "View status" first, but headless needs "Force start"
|
|
@@ -23,62 +117,156 @@ export function handleExtensionUIRequest(event, writeToStdin) {
|
|
|
23
117
|
if (forceOption)
|
|
24
118
|
selected = forceOption;
|
|
25
119
|
}
|
|
26
|
-
|
|
120
|
+
client.sendUIResponse(id, { value: selected });
|
|
27
121
|
break;
|
|
28
122
|
}
|
|
29
123
|
case 'confirm':
|
|
30
|
-
|
|
124
|
+
client.sendUIResponse(id, { confirmed: true });
|
|
31
125
|
break;
|
|
32
126
|
case 'input':
|
|
33
|
-
|
|
127
|
+
client.sendUIResponse(id, { value: '' });
|
|
34
128
|
break;
|
|
35
129
|
case 'editor':
|
|
36
|
-
|
|
130
|
+
client.sendUIResponse(id, { value: event.prefill ?? '' });
|
|
37
131
|
break;
|
|
38
132
|
case 'notify':
|
|
39
133
|
case 'setStatus':
|
|
40
134
|
case 'setWidget':
|
|
41
135
|
case 'setTitle':
|
|
42
136
|
case 'set_editor_text':
|
|
43
|
-
|
|
137
|
+
client.sendUIResponse(id, { value: '' });
|
|
44
138
|
break;
|
|
45
139
|
default:
|
|
46
140
|
process.stderr.write(`[headless] Warning: unknown extension_ui_request method "${method}", cancelling\n`);
|
|
47
|
-
|
|
141
|
+
client.sendUIResponse(id, { cancelled: true });
|
|
48
142
|
break;
|
|
49
143
|
}
|
|
50
|
-
writeToStdin(serializeJsonLine(response));
|
|
51
144
|
}
|
|
52
145
|
// ---------------------------------------------------------------------------
|
|
53
146
|
// Progress Formatter
|
|
54
147
|
// ---------------------------------------------------------------------------
|
|
55
|
-
export function formatProgress(event,
|
|
148
|
+
export function formatProgress(event, ctx) {
|
|
56
149
|
const type = String(event.type ?? '');
|
|
150
|
+
// Emit accumulated thinking preview before tool calls
|
|
151
|
+
if (ctx.thinkingPreview) {
|
|
152
|
+
// thinkingPreview is handled by the caller in headless.ts — it prepends
|
|
153
|
+
// the thinking line before the current event's line. We return the thinking
|
|
154
|
+
// line as a prefix joined with newline.
|
|
155
|
+
}
|
|
57
156
|
switch (type) {
|
|
58
|
-
case 'tool_execution_start':
|
|
59
|
-
if (verbose)
|
|
60
|
-
return
|
|
61
|
-
|
|
157
|
+
case 'tool_execution_start': {
|
|
158
|
+
if (!ctx.verbose)
|
|
159
|
+
return null;
|
|
160
|
+
const name = String(event.toolName ?? 'unknown');
|
|
161
|
+
const args = summarizeToolArgs(event.toolName, event.args);
|
|
162
|
+
const argStr = args ? ` ${c.dim}${args}${c.reset}` : '';
|
|
163
|
+
return ` ${c.dim}[tool]${c.reset} ${name}${argStr}`;
|
|
164
|
+
}
|
|
165
|
+
case 'tool_execution_end': {
|
|
166
|
+
if (!ctx.verbose)
|
|
167
|
+
return null;
|
|
168
|
+
const name = String(event.toolName ?? 'unknown');
|
|
169
|
+
const durationStr = ctx.toolDuration != null ? ` ${c.dim}${formatDuration(ctx.toolDuration)}${c.reset}` : '';
|
|
170
|
+
if (ctx.isError) {
|
|
171
|
+
return ` ${c.red}[tool] ${name} error${c.reset}${durationStr}`;
|
|
172
|
+
}
|
|
173
|
+
return ` ${c.dim}[tool] ${name} done${c.reset}${durationStr}`;
|
|
174
|
+
}
|
|
62
175
|
case 'agent_start':
|
|
63
|
-
return
|
|
64
|
-
case 'agent_end':
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
176
|
+
return `${c.dim}[agent] Session started${c.reset}`;
|
|
177
|
+
case 'agent_end': {
|
|
178
|
+
let line = `${c.dim}[agent] Session ended${c.reset}`;
|
|
179
|
+
if (ctx.lastCost) {
|
|
180
|
+
const cost = `$${ctx.lastCost.costUsd.toFixed(4)}`;
|
|
181
|
+
const tokens = `${ctx.lastCost.inputTokens + ctx.lastCost.outputTokens} tokens`;
|
|
182
|
+
line += ` ${c.dim}(${cost}, ${tokens})${c.reset}`;
|
|
183
|
+
}
|
|
184
|
+
return line;
|
|
185
|
+
}
|
|
186
|
+
case 'extension_ui_request': {
|
|
187
|
+
const method = String(event.method ?? '');
|
|
188
|
+
if (method === 'notify') {
|
|
189
|
+
const msg = String(event.message ?? '');
|
|
190
|
+
if (!msg)
|
|
191
|
+
return null;
|
|
192
|
+
// Bold important notifications
|
|
193
|
+
const isImportant = /^(committed:|verification gate:|milestone|blocked:)/i.test(msg);
|
|
194
|
+
return isImportant
|
|
195
|
+
? `${c.bold}[gsd] ${msg}${c.reset}`
|
|
196
|
+
: `[gsd] ${msg}`;
|
|
69
197
|
}
|
|
70
|
-
if (
|
|
71
|
-
|
|
198
|
+
if (method === 'setStatus') {
|
|
199
|
+
// Parse statusKey for phase transitions
|
|
200
|
+
const statusKey = String(event.statusKey ?? '');
|
|
201
|
+
const msg = String(event.message ?? '');
|
|
202
|
+
if (!statusKey && !msg)
|
|
203
|
+
return null; // suppress empty status lines
|
|
204
|
+
// Show meaningful phase transitions
|
|
205
|
+
if (statusKey) {
|
|
206
|
+
const label = parsePhaseLabel(statusKey, msg);
|
|
207
|
+
if (label)
|
|
208
|
+
return `${c.cyan}[phase] ${label}${c.reset}`;
|
|
209
|
+
}
|
|
210
|
+
// Fallback: show message if non-empty
|
|
211
|
+
if (msg)
|
|
212
|
+
return `${c.cyan}[phase] ${msg}${c.reset}`;
|
|
213
|
+
return null;
|
|
72
214
|
}
|
|
73
215
|
return null;
|
|
216
|
+
}
|
|
74
217
|
default:
|
|
75
218
|
return null;
|
|
76
219
|
}
|
|
77
220
|
}
|
|
221
|
+
/**
|
|
222
|
+
* Format a thinking preview line from accumulated LLM text deltas.
|
|
223
|
+
*/
|
|
224
|
+
export function formatThinkingLine(text) {
|
|
225
|
+
const trimmed = text.replace(/\s+/g, ' ').trim();
|
|
226
|
+
const truncated = trimmed.length > 120 ? trimmed.slice(0, 117) + '...' : trimmed;
|
|
227
|
+
return `${c.dim}${c.italic}[thinking] ${truncated}${c.reset}`;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Format a cost line (used for periodic cost updates in verbose mode).
|
|
231
|
+
*/
|
|
232
|
+
export function formatCostLine(costUsd, inputTokens, outputTokens) {
|
|
233
|
+
return `${c.dim}[cost] $${costUsd.toFixed(4)} (${inputTokens + outputTokens} tokens)${c.reset}`;
|
|
234
|
+
}
|
|
235
|
+
// ---------------------------------------------------------------------------
|
|
236
|
+
// Phase Label Parser
|
|
237
|
+
// ---------------------------------------------------------------------------
|
|
238
|
+
/**
|
|
239
|
+
* Parse a statusKey into a human-readable phase label.
|
|
240
|
+
* statusKey format varies but common patterns:
|
|
241
|
+
* "milestone:M1", "slice:S1.1", "task:T1.1.1", "phase:discuss", etc.
|
|
242
|
+
*/
|
|
243
|
+
function parsePhaseLabel(statusKey, message) {
|
|
244
|
+
// Direct phase/milestone/slice/task keys
|
|
245
|
+
const parts = statusKey.split(':');
|
|
246
|
+
if (parts.length >= 2) {
|
|
247
|
+
const [kind, value] = parts;
|
|
248
|
+
switch (kind.toLowerCase()) {
|
|
249
|
+
case 'milestone':
|
|
250
|
+
return `Milestone ${value}${message ? ' -- ' + message : ''}`;
|
|
251
|
+
case 'slice':
|
|
252
|
+
return `Slice ${value}${message ? ' -- ' + message : ''}`;
|
|
253
|
+
case 'task':
|
|
254
|
+
return `Task ${value}${message ? ' -- ' + message : ''}`;
|
|
255
|
+
case 'phase':
|
|
256
|
+
return `Phase: ${value}${message ? ' -- ' + message : ''}`;
|
|
257
|
+
default:
|
|
258
|
+
return `${kind}: ${value}${message ? ' -- ' + message : ''}`;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
// Single-word status keys with a message
|
|
262
|
+
if (message)
|
|
263
|
+
return `${statusKey}: ${message}`;
|
|
264
|
+
return statusKey || null;
|
|
265
|
+
}
|
|
78
266
|
// ---------------------------------------------------------------------------
|
|
79
267
|
// Supervised Stdin Reader
|
|
80
268
|
// ---------------------------------------------------------------------------
|
|
81
|
-
export function startSupervisedStdinReader(
|
|
269
|
+
export function startSupervisedStdinReader(client, onResponse) {
|
|
82
270
|
return attachJsonlLineReader(process.stdin, (line) => {
|
|
83
271
|
let msg;
|
|
84
272
|
try {
|
|
@@ -90,12 +278,17 @@ export function startSupervisedStdinReader(stdinWriter, client, onResponse) {
|
|
|
90
278
|
}
|
|
91
279
|
const type = String(msg.type ?? '');
|
|
92
280
|
switch (type) {
|
|
93
|
-
case 'extension_ui_response':
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
281
|
+
case 'extension_ui_response': {
|
|
282
|
+
const id = String(msg.id ?? '');
|
|
283
|
+
const value = msg.value !== undefined ? String(msg.value) : undefined;
|
|
284
|
+
const confirmed = typeof msg.confirmed === 'boolean' ? msg.confirmed : undefined;
|
|
285
|
+
const cancelled = typeof msg.cancelled === 'boolean' ? msg.cancelled : undefined;
|
|
286
|
+
client.sendUIResponse(id, { value, confirmed, cancelled });
|
|
287
|
+
if (id) {
|
|
288
|
+
onResponse(id);
|
|
97
289
|
}
|
|
98
290
|
break;
|
|
291
|
+
}
|
|
99
292
|
case 'prompt':
|
|
100
293
|
client.prompt(String(msg.message ?? ''));
|
|
101
294
|
break;
|
package/dist/headless.d.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* 10 — blocked (command reported a blocker)
|
|
12
12
|
* 11 — cancelled (SIGINT/SIGTERM received)
|
|
13
13
|
*/
|
|
14
|
+
import type { SessionInfo } from '@gsd/pi-coding-agent';
|
|
14
15
|
import type { OutputFormat } from './headless-types.js';
|
|
15
16
|
export interface HeadlessOptions {
|
|
16
17
|
timeout: number;
|
|
@@ -31,5 +32,15 @@ export interface HeadlessOptions {
|
|
|
31
32
|
resumeSession?: string;
|
|
32
33
|
bare?: boolean;
|
|
33
34
|
}
|
|
35
|
+
export interface ResumeSessionResult {
|
|
36
|
+
session?: SessionInfo;
|
|
37
|
+
error?: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Resolve a session prefix to a single session.
|
|
41
|
+
* Exact id match is preferred over prefix match.
|
|
42
|
+
* Returns `{ session }` on unique match or `{ error }` on 0/ambiguous matches.
|
|
43
|
+
*/
|
|
44
|
+
export declare function resolveResumeSession(sessions: SessionInfo[], prefix: string): ResumeSessionResult;
|
|
34
45
|
export declare function parseHeadlessArgs(argv: string[]): HeadlessOptions;
|
|
35
46
|
export declare function runHeadless(options: HeadlessOptions): Promise<void>;
|