gsd-pi 2.53.0-dev.a67436f → 2.53.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.
Files changed (165) hide show
  1. package/dist/headless-ui.d.ts +2 -2
  2. package/dist/headless-ui.js +15 -18
  3. package/dist/headless.d.ts +0 -11
  4. package/dist/headless.js +38 -178
  5. package/dist/web/standalone/.next/BUILD_ID +1 -1
  6. package/dist/web/standalone/.next/app-path-routes-manifest.json +17 -17
  7. package/dist/web/standalone/.next/build-manifest.json +3 -3
  8. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  9. package/dist/web/standalone/.next/required-server-files.json +4 -4
  10. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  11. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  12. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  13. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  14. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  15. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  16. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  17. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  18. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  19. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  20. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  21. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  22. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  23. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  24. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  25. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  26. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  27. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  28. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  29. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  30. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  31. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  32. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  33. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  34. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  35. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  36. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  37. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  38. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  39. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  40. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  41. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  42. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  43. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  44. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  45. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  46. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  47. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  48. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  49. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  50. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  51. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  52. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  53. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  54. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  55. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  56. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  57. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  58. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  59. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  60. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  61. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  62. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  63. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  64. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  65. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  66. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  67. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  68. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  69. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  70. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  71. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  72. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  73. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  74. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  75. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  76. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  77. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  78. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  79. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  80. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  81. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  82. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  83. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  84. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  85. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  86. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  87. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  88. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  89. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  90. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  91. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  92. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  93. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  94. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  95. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  96. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  97. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  98. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  99. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  100. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  101. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  102. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  103. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  105. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  109. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  112. package/dist/web/standalone/.next/server/app/index.html +1 -1
  113. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  114. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  115. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  116. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  118. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/page.js +2 -2
  120. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app-paths-manifest.json +17 -17
  122. package/dist/web/standalone/.next/server/chunks/2229.js +1 -1
  123. package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
  124. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/middleware.js +2 -2
  126. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  128. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  129. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  130. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  131. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-f2a7482d42a5614b.js → page-2f24283c162b6ab3.js} +1 -1
  132. package/dist/web/standalone/.next/static/chunks/app/{layout-a16c7a7ecdf0c2cf.js → layout-9ecfd95f343793f0.js} +1 -1
  133. package/dist/web/standalone/.next/static/chunks/app/page-fbecd1237e2d6d1f.js +1 -0
  134. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +1 -0
  135. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +1 -0
  136. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  137. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  138. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  139. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  140. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  141. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  142. package/dist/web/standalone/server.js +1 -1
  143. package/package.json +1 -1
  144. package/packages/mcp-server/README.md +6 -6
  145. package/packages/mcp-server/package.json +4 -14
  146. package/packages/mcp-server/src/cli.ts +1 -1
  147. package/packages/mcp-server/src/index.ts +1 -1
  148. package/packages/mcp-server/src/mcp-server.test.ts +2 -2
  149. package/packages/mcp-server/src/session-manager.ts +2 -2
  150. package/packages/mcp-server/src/types.ts +1 -1
  151. package/packages/rpc-client/package.json +3 -17
  152. package/dist/web/standalone/.next/static/chunks/app/page-b950e4e384cc62b3.js +0 -1
  153. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +0 -1
  154. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +0 -1
  155. package/packages/rpc-client/README.md +0 -125
  156. package/packages/rpc-client/examples/basic-usage.ts +0 -13
  157. package/packages/rpc-client/src/index.ts +0 -10
  158. package/packages/rpc-client/src/jsonl.ts +0 -64
  159. package/packages/rpc-client/src/rpc-client.test.ts +0 -568
  160. package/packages/rpc-client/src/rpc-client.ts +0 -666
  161. package/packages/rpc-client/src/rpc-types.ts +0 -399
  162. package/packages/rpc-client/tsconfig.examples.json +0 -17
  163. package/packages/rpc-client/tsconfig.json +0 -24
  164. /package/dist/web/standalone/.next/static/{YO-PWFRitlHM-L-dotlmm → mWBOLPnUoeaTGiD-vhu5O}/_buildManifest.js +0 -0
  165. /package/dist/web/standalone/.next/static/{YO-PWFRitlHM-L-dotlmm → mWBOLPnUoeaTGiD-vhu5O}/_ssgManifest.js +0 -0
@@ -18,6 +18,6 @@ interface ExtensionUIRequest {
18
18
  [key: string]: unknown;
19
19
  }
20
20
  export type { ExtensionUIRequest };
21
- export declare function handleExtensionUIRequest(event: ExtensionUIRequest, client: RpcClient): void;
21
+ export declare function handleExtensionUIRequest(event: ExtensionUIRequest, writeToStdin: (data: string) => void): void;
22
22
  export declare function formatProgress(event: Record<string, unknown>, verbose: boolean): string | null;
23
- export declare function startSupervisedStdinReader(client: RpcClient, onResponse: (id: string) => void): () => void;
23
+ export declare function startSupervisedStdinReader(stdinWriter: (data: string) => void, client: RpcClient, onResponse: (id: string) => void): () => void;
@@ -5,12 +5,13 @@
5
5
  * formats progress events for stderr output, and reads orchestrator
6
6
  * commands from stdin in supervised mode.
7
7
  */
8
- import { attachJsonlLineReader } from '@gsd/pi-coding-agent';
8
+ import { attachJsonlLineReader, serializeJsonLine } from '@gsd/pi-coding-agent';
9
9
  // ---------------------------------------------------------------------------
10
10
  // Extension UI Auto-Responder
11
11
  // ---------------------------------------------------------------------------
12
- export function handleExtensionUIRequest(event, client) {
12
+ export function handleExtensionUIRequest(event, writeToStdin) {
13
13
  const { id, method } = event;
14
+ let response;
14
15
  switch (method) {
15
16
  case 'select': {
16
17
  // Lock-guard prompts list "View status" first, but headless needs "Force start"
@@ -22,30 +23,31 @@ export function handleExtensionUIRequest(event, client) {
22
23
  if (forceOption)
23
24
  selected = forceOption;
24
25
  }
25
- client.sendUIResponse(id, { value: selected });
26
+ response = { type: 'extension_ui_response', id, value: selected };
26
27
  break;
27
28
  }
28
29
  case 'confirm':
29
- client.sendUIResponse(id, { confirmed: true });
30
+ response = { type: 'extension_ui_response', id, confirmed: true };
30
31
  break;
31
32
  case 'input':
32
- client.sendUIResponse(id, { value: '' });
33
+ response = { type: 'extension_ui_response', id, value: '' };
33
34
  break;
34
35
  case 'editor':
35
- client.sendUIResponse(id, { value: event.prefill ?? '' });
36
+ response = { type: 'extension_ui_response', id, value: event.prefill ?? '' };
36
37
  break;
37
38
  case 'notify':
38
39
  case 'setStatus':
39
40
  case 'setWidget':
40
41
  case 'setTitle':
41
42
  case 'set_editor_text':
42
- client.sendUIResponse(id, { value: '' });
43
+ response = { type: 'extension_ui_response', id, value: '' };
43
44
  break;
44
45
  default:
45
46
  process.stderr.write(`[headless] Warning: unknown extension_ui_request method "${method}", cancelling\n`);
46
- client.sendUIResponse(id, { cancelled: true });
47
+ response = { type: 'extension_ui_response', id, cancelled: true };
47
48
  break;
48
49
  }
50
+ writeToStdin(serializeJsonLine(response));
49
51
  }
50
52
  // ---------------------------------------------------------------------------
51
53
  // Progress Formatter
@@ -76,7 +78,7 @@ export function formatProgress(event, verbose) {
76
78
  // ---------------------------------------------------------------------------
77
79
  // Supervised Stdin Reader
78
80
  // ---------------------------------------------------------------------------
79
- export function startSupervisedStdinReader(client, onResponse) {
81
+ export function startSupervisedStdinReader(stdinWriter, client, onResponse) {
80
82
  return attachJsonlLineReader(process.stdin, (line) => {
81
83
  let msg;
82
84
  try {
@@ -88,17 +90,12 @@ export function startSupervisedStdinReader(client, onResponse) {
88
90
  }
89
91
  const type = String(msg.type ?? '');
90
92
  switch (type) {
91
- case 'extension_ui_response': {
92
- const id = String(msg.id ?? '');
93
- const value = msg.value !== undefined ? String(msg.value) : undefined;
94
- const confirmed = typeof msg.confirmed === 'boolean' ? msg.confirmed : undefined;
95
- const cancelled = typeof msg.cancelled === 'boolean' ? msg.cancelled : undefined;
96
- client.sendUIResponse(id, { value, confirmed, cancelled });
97
- if (id) {
98
- onResponse(id);
93
+ case 'extension_ui_response':
94
+ stdinWriter(line + '\n');
95
+ if (typeof msg.id === 'string') {
96
+ onResponse(msg.id);
99
97
  }
100
98
  break;
101
- }
102
99
  case 'prompt':
103
100
  client.prompt(String(msg.message ?? ''));
104
101
  break;
@@ -11,7 +11,6 @@
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';
15
14
  import type { OutputFormat } from './headless-types.js';
16
15
  export interface HeadlessOptions {
17
16
  timeout: number;
@@ -32,15 +31,5 @@ export interface HeadlessOptions {
32
31
  resumeSession?: string;
33
32
  bare?: boolean;
34
33
  }
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;
45
34
  export declare function parseHeadlessArgs(argv: string[]): HeadlessOptions;
46
35
  export declare function runHeadless(options: HeadlessOptions): Promise<void>;
package/dist/headless.js CHANGED
@@ -14,35 +14,12 @@
14
14
  import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
15
15
  import { join } from 'node:path';
16
16
  import { resolve } from 'node:path';
17
- import { RpcClient, SessionManager } from '@gsd/pi-coding-agent';
18
- import { getProjectSessionsDir } from './project-sessions.js';
17
+ import { RpcClient } from '@gsd/pi-coding-agent';
19
18
  import { loadAndValidateAnswerFile, AnswerInjector } from './headless-answers.js';
20
- import { isTerminalNotification, isBlockedNotification, isMilestoneReadyNotification, isQuickCommand, FIRE_AND_FORGET_METHODS, IDLE_TIMEOUT_MS, NEW_MILESTONE_IDLE_TIMEOUT_MS, EXIT_SUCCESS, EXIT_ERROR, EXIT_BLOCKED, EXIT_CANCELLED, mapStatusToExitCode, } from './headless-events.js';
19
+ import { isTerminalNotification, isBlockedNotification, isMilestoneReadyNotification, isQuickCommand, FIRE_AND_FORGET_METHODS, IDLE_TIMEOUT_MS, NEW_MILESTONE_IDLE_TIMEOUT_MS, EXIT_SUCCESS, EXIT_ERROR, EXIT_BLOCKED, EXIT_CANCELLED, } from './headless-events.js';
21
20
  import { VALID_OUTPUT_FORMATS } from './headless-types.js';
22
21
  import { handleExtensionUIRequest, formatProgress, startSupervisedStdinReader, } from './headless-ui.js';
23
22
  import { loadContext, bootstrapGsdProject, } from './headless-context.js';
24
- /**
25
- * Resolve a session prefix to a single session.
26
- * Exact id match is preferred over prefix match.
27
- * Returns `{ session }` on unique match or `{ error }` on 0/ambiguous matches.
28
- */
29
- export function resolveResumeSession(sessions, prefix) {
30
- // Exact match takes priority
31
- const exact = sessions.find(s => s.id === prefix);
32
- if (exact) {
33
- return { session: exact };
34
- }
35
- // Prefix match
36
- const matches = sessions.filter(s => s.id.startsWith(prefix));
37
- if (matches.length === 0) {
38
- return { error: `No session matching '${prefix}' found` };
39
- }
40
- if (matches.length > 1) {
41
- const list = matches.map(s => ` ${s.id}`).join('\n');
42
- return { error: `Ambiguous session prefix '${prefix}' matches ${matches.length} sessions:\n${list}` };
43
- }
44
- return { session: matches[0] };
45
- }
46
23
  // ---------------------------------------------------------------------------
47
24
  // CLI Argument Parser
48
25
  // ---------------------------------------------------------------------------
@@ -279,39 +256,6 @@ async function runHeadlessOnce(options, restartCount) {
279
256
  let exitCode = 0;
280
257
  let milestoneReady = false; // tracks "Milestone X ready." for auto-chaining
281
258
  const recentEvents = [];
282
- // JSON batch mode: cost aggregation (cumulative-max pattern per K004)
283
- let cumulativeCostUsd = 0;
284
- let cumulativeInputTokens = 0;
285
- let cumulativeOutputTokens = 0;
286
- let cumulativeCacheReadTokens = 0;
287
- let cumulativeCacheWriteTokens = 0;
288
- let lastSessionId;
289
- // Emit HeadlessJsonResult to stdout for --output-format json batch mode
290
- function emitBatchJsonResult() {
291
- if (options.outputFormat !== 'json')
292
- return;
293
- const duration = Date.now() - startTime;
294
- const status = blocked ? 'blocked'
295
- : exitCode === EXIT_CANCELLED ? 'cancelled'
296
- : exitCode === EXIT_ERROR ? (totalEvents === 0 ? 'error' : 'timeout')
297
- : 'success';
298
- const result = {
299
- status,
300
- exitCode,
301
- sessionId: lastSessionId,
302
- duration,
303
- cost: {
304
- total: cumulativeCostUsd,
305
- input_tokens: cumulativeInputTokens,
306
- output_tokens: cumulativeOutputTokens,
307
- cache_read_tokens: cumulativeCacheReadTokens,
308
- cache_write_tokens: cumulativeCacheWriteTokens,
309
- },
310
- toolCalls: toolCallCount,
311
- events: totalEvents,
312
- };
313
- process.stdout.write(JSON.stringify(result) + '\n');
314
- }
315
259
  function trackEvent(event) {
316
260
  totalEvents++;
317
261
  const type = String(event.type ?? 'unknown');
@@ -328,11 +272,8 @@ async function runHeadlessOnce(options, restartCount) {
328
272
  if (recentEvents.length > 20)
329
273
  recentEvents.shift();
330
274
  }
331
- // Client started flag replaces old stdinWriter null-check
332
- let clientStarted = false;
333
- // Adapter for AnswerInjector — wraps client.sendUIResponse in a writeToStdin-compatible callback
334
- // Initialized after client.start(); events won't fire before then
335
- let injectorStdinAdapter = () => { };
275
+ // Stdin writer for sending extension_ui_response to child
276
+ let stdinWriter = null;
336
277
  // Supervised mode state
337
278
  const pendingResponseTimers = new Map();
338
279
  let supervisedFallback = false;
@@ -379,54 +320,21 @@ async function runHeadlessOnce(options, restartCount) {
379
320
  resetIdleTimer();
380
321
  // Answer injector: observe events for question metadata
381
322
  injector?.observeEvent(eventObj);
382
- // --json / --output-format stream-json: forward events as JSONL to stdout (filtered if --events)
383
- // --output-format json (batch mode): suppress streaming, track cost for final result
384
- if (options.json && options.outputFormat === 'stream-json') {
323
+ // --json mode: forward events as JSONL to stdout (filtered if --events)
324
+ if (options.json) {
385
325
  const eventType = String(eventObj.type ?? '');
386
326
  if (!options.eventFilter || options.eventFilter.has(eventType)) {
387
327
  process.stdout.write(JSON.stringify(eventObj) + '\n');
388
328
  }
389
329
  }
390
- else if (options.outputFormat === 'json') {
391
- // Batch mode: silently track cost_update events (cumulative-max per K004)
392
- const eventType = String(eventObj.type ?? '');
393
- if (eventType === 'cost_update') {
394
- const data = eventObj;
395
- const cumCost = data.cumulativeCost;
396
- if (cumCost) {
397
- cumulativeCostUsd = Math.max(cumulativeCostUsd, Number(cumCost.costUsd ?? 0));
398
- const tokens = data.tokens;
399
- if (tokens) {
400
- cumulativeInputTokens = Math.max(cumulativeInputTokens, tokens.input ?? 0);
401
- cumulativeOutputTokens = Math.max(cumulativeOutputTokens, tokens.output ?? 0);
402
- cumulativeCacheReadTokens = Math.max(cumulativeCacheReadTokens, tokens.cacheRead ?? 0);
403
- cumulativeCacheWriteTokens = Math.max(cumulativeCacheWriteTokens, tokens.cacheWrite ?? 0);
404
- }
405
- }
406
- }
407
- // Track sessionId from init_result
408
- if (eventType === 'init_result') {
409
- lastSessionId = String(eventObj.sessionId ?? '');
410
- }
411
- }
412
- else if (!options.json) {
330
+ else {
413
331
  // Progress output to stderr
414
332
  const line = formatProgress(eventObj, !!options.verbose);
415
333
  if (line)
416
334
  process.stderr.write(line + '\n');
417
335
  }
418
- // Handle execution_complete (v2 structured completion)
419
- if (eventObj.type === 'execution_complete' && !completed) {
420
- completed = true;
421
- const status = String(eventObj.status ?? 'success');
422
- exitCode = mapStatusToExitCode(status);
423
- if (eventObj.status === 'blocked')
424
- blocked = true;
425
- resolveCompletion();
426
- return;
427
- }
428
336
  // Handle extension_ui_request
429
- if (eventObj.type === 'extension_ui_request' && clientStarted) {
337
+ if (eventObj.type === 'extension_ui_request' && stdinWriter) {
430
338
  // Check for terminal notification before auto-responding
431
339
  if (isBlockedNotification(eventObj)) {
432
340
  blocked = true;
@@ -440,7 +348,7 @@ async function runHeadlessOnce(options, restartCount) {
440
348
  }
441
349
  // Answer injection: try to handle with pre-supplied answers before supervised/auto
442
350
  if (injector && !FIRE_AND_FORGET_METHODS.has(String(eventObj.method ?? ''))) {
443
- if (injector.tryHandle(eventObj, injectorStdinAdapter)) {
351
+ if (injector.tryHandle(eventObj, stdinWriter)) {
444
352
  if (completed) {
445
353
  exitCode = blocked ? EXIT_BLOCKED : EXIT_SUCCESS;
446
354
  resolveCompletion();
@@ -456,13 +364,13 @@ async function runHeadlessOnce(options, restartCount) {
456
364
  const eventId = String(eventObj.id ?? '');
457
365
  const timer = setTimeout(() => {
458
366
  pendingResponseTimers.delete(eventId);
459
- handleExtensionUIRequest(eventObj, client);
367
+ handleExtensionUIRequest(eventObj, stdinWriter);
460
368
  process.stdout.write(JSON.stringify({ type: 'supervised_timeout', id: eventId, method }) + '\n');
461
369
  }, responseTimeout);
462
370
  pendingResponseTimers.set(eventId, timer);
463
371
  }
464
372
  else {
465
- handleExtensionUIRequest(eventObj, client);
373
+ handleExtensionUIRequest(eventObj, stdinWriter);
466
374
  }
467
375
  // If we detected a terminal notification, resolve after responding
468
376
  if (completed) {
@@ -485,22 +393,13 @@ async function runHeadlessOnce(options, restartCount) {
485
393
  process.stderr.write('\n[headless] Interrupted, stopping child process...\n');
486
394
  interrupted = true;
487
395
  exitCode = EXIT_CANCELLED;
488
- // Kill child process — don't await, just fire and exit.
489
- // The main flow may be awaiting a promise that resolves when the child dies,
490
- // which would race with this handler. Exit synchronously to ensure correct exit code.
491
- try {
492
- client.stop().catch(() => { });
493
- }
494
- catch { }
495
- if (timeoutTimer)
496
- clearTimeout(timeoutTimer);
497
- if (idleTimer)
498
- clearTimeout(idleTimer);
499
- // Emit batch JSON result if in json mode before exiting
500
- if (options.outputFormat === 'json') {
501
- emitBatchJsonResult();
502
- }
503
- process.exit(exitCode);
396
+ client.stop().finally(() => {
397
+ if (timeoutTimer)
398
+ clearTimeout(timeoutTimer);
399
+ if (idleTimer)
400
+ clearTimeout(idleTimer);
401
+ process.exit(exitCode);
402
+ });
504
403
  };
505
404
  process.on('SIGINT', signalHandler);
506
405
  process.on('SIGTERM', signalHandler);
@@ -514,55 +413,21 @@ async function runHeadlessOnce(options, restartCount) {
514
413
  clearTimeout(timeoutTimer);
515
414
  process.exit(1);
516
415
  }
517
- // v2 protocol negotiation attempt init for structured completion events
518
- let v2Enabled = false;
519
- try {
520
- await client.init({ clientId: 'gsd-headless' });
521
- v2Enabled = true;
522
- }
523
- catch {
524
- process.stderr.write('[headless] Warning: v2 init failed, falling back to v1 string-matching\n');
525
- }
526
- clientStarted = true;
527
- // --resume: resolve session ID and switch to it
528
- if (options.resumeSession) {
529
- const projectSessionsDir = getProjectSessionsDir(process.cwd());
530
- const sessions = await SessionManager.list(process.cwd(), projectSessionsDir);
531
- const result = resolveResumeSession(sessions, options.resumeSession);
532
- if (result.error) {
533
- process.stderr.write(`[headless] Error: ${result.error}\n`);
534
- await client.stop();
535
- if (timeoutTimer)
536
- clearTimeout(timeoutTimer);
537
- process.exit(1);
538
- }
539
- const matched = result.session;
540
- const switchResult = await client.switchSession(matched.path);
541
- if (switchResult.cancelled) {
542
- process.stderr.write(`[headless] Error: Session switch to '${matched.id}' was cancelled by an extension\n`);
543
- await client.stop();
544
- if (timeoutTimer)
545
- clearTimeout(timeoutTimer);
546
- process.exit(1);
547
- }
548
- process.stderr.write(`[headless] Resuming session ${matched.id}\n`);
416
+ // Access stdin writer from the internal process
417
+ const internalProcess = client.process;
418
+ if (!internalProcess?.stdin) {
419
+ process.stderr.write('[headless] Error: Cannot access child process stdin\n');
420
+ await client.stop();
421
+ if (timeoutTimer)
422
+ clearTimeout(timeoutTimer);
423
+ process.exit(1);
549
424
  }
550
- // Build injector adapter — wraps client.sendUIResponse for AnswerInjector's writeToStdin interface
551
- injectorStdinAdapter = (data) => {
552
- try {
553
- const parsed = JSON.parse(data.trim());
554
- if (parsed.type === 'extension_ui_response' && parsed.id) {
555
- const { id, value, values, confirmed, cancelled } = parsed;
556
- client.sendUIResponse(id, { value, values, confirmed, cancelled });
557
- }
558
- }
559
- catch {
560
- process.stderr.write('[headless] Warning: injector adapter received unparseable data\n');
561
- }
425
+ stdinWriter = (data) => {
426
+ internalProcess.stdin.write(data);
562
427
  };
563
428
  // Start supervised stdin reader for orchestrator commands
564
429
  if (options.supervised) {
565
- stopSupervisedReader = startSupervisedStdinReader(client, (id) => {
430
+ stopSupervisedReader = startSupervisedStdinReader(stdinWriter, client, (id) => {
566
431
  const timer = pendingResponseTimers.get(id);
567
432
  if (timer) {
568
433
  clearTimeout(timer);
@@ -572,18 +437,15 @@ async function runHeadlessOnce(options, restartCount) {
572
437
  // Ensure stdin is in flowing mode for JSONL reading
573
438
  process.stdin.resume();
574
439
  }
575
- // Detect child process crash (read-only exit event subscription — not stdin access)
576
- const internalProcess = client.process;
577
- if (internalProcess) {
578
- internalProcess.on('exit', (code) => {
579
- if (!completed) {
580
- const msg = `[headless] Child process exited unexpectedly with code ${code ?? 'null'}\n`;
581
- process.stderr.write(msg);
582
- exitCode = EXIT_ERROR;
583
- resolveCompletion();
584
- }
585
- });
586
- }
440
+ // Detect child process crash
441
+ internalProcess.on('exit', (code) => {
442
+ if (!completed) {
443
+ const msg = `[headless] Child process exited unexpectedly with code ${code ?? 'null'}\n`;
444
+ process.stderr.write(msg);
445
+ exitCode = EXIT_ERROR;
446
+ resolveCompletion();
447
+ }
448
+ });
587
449
  if (!options.json) {
588
450
  process.stderr.write(`[headless] Running /gsd ${options.command}${options.commandArgs.length > 0 ? ' ' + options.commandArgs.join(' ') : ''}...\n`);
589
451
  }
@@ -668,7 +530,5 @@ async function runHeadlessOnce(options, restartCount) {
668
530
  }
669
531
  }
670
532
  }
671
- // Emit structured JSON result in batch mode
672
- emitBatchJsonResult();
673
533
  return { exitCode, interrupted };
674
534
  }
@@ -1 +1 @@
1
- YO-PWFRitlHM-L-dotlmm
1
+ mWBOLPnUoeaTGiD-vhu5O
@@ -1,46 +1,46 @@
1
1
  {
2
- "/_global-error/page": "/_global-error",
3
2
  "/_not-found/page": "/_not-found",
4
- "/api/bridge-terminal/input/route": "/api/bridge-terminal/input",
5
- "/api/boot/route": "/api/boot",
3
+ "/_global-error/page": "/_global-error",
6
4
  "/api/bridge-terminal/resize/route": "/api/bridge-terminal/resize",
5
+ "/api/boot/route": "/api/boot",
6
+ "/api/bridge-terminal/input/route": "/api/bridge-terminal/input",
7
7
  "/api/bridge-terminal/stream/route": "/api/bridge-terminal/stream",
8
+ "/api/dev-mode/route": "/api/dev-mode",
8
9
  "/api/cleanup/route": "/api/cleanup",
9
- "/api/export-data/route": "/api/export-data",
10
10
  "/api/doctor/route": "/api/doctor",
11
11
  "/api/browse-directories/route": "/api/browse-directories",
12
- "/api/dev-mode/route": "/api/dev-mode",
13
- "/api/captures/route": "/api/captures",
14
- "/api/history/route": "/api/history",
12
+ "/api/export-data/route": "/api/export-data",
15
13
  "/api/forensics/route": "/api/forensics",
14
+ "/api/captures/route": "/api/captures",
16
15
  "/api/git/route": "/api/git",
16
+ "/api/history/route": "/api/history",
17
17
  "/api/hooks/route": "/api/hooks",
18
- "/api/inspect/route": "/api/inspect",
19
- "/api/live-state/route": "/api/live-state",
20
18
  "/api/knowledge/route": "/api/knowledge",
19
+ "/api/inspect/route": "/api/inspect",
21
20
  "/api/experimental/route": "/api/experimental",
21
+ "/api/live-state/route": "/api/live-state",
22
22
  "/api/preferences/route": "/api/preferences",
23
23
  "/api/recovery/route": "/api/recovery",
24
24
  "/api/onboarding/route": "/api/onboarding",
25
- "/api/session/browser/route": "/api/session/browser",
26
25
  "/api/projects/route": "/api/projects",
27
- "/api/session/manage/route": "/api/session/manage",
26
+ "/api/session/browser/route": "/api/session/browser",
28
27
  "/api/session/command/route": "/api/session/command",
29
- "/api/skill-health/route": "/api/skill-health",
30
28
  "/api/session/events/route": "/api/session/events",
29
+ "/api/session/manage/route": "/api/session/manage",
31
30
  "/api/settings-data/route": "/api/settings-data",
32
31
  "/api/shutdown/route": "/api/shutdown",
32
+ "/api/skill-health/route": "/api/skill-health",
33
33
  "/api/steer/route": "/api/steer",
34
+ "/api/terminal/input/route": "/api/terminal/input",
34
35
  "/api/terminal/resize/route": "/api/terminal/resize",
35
36
  "/api/switch-root/route": "/api/switch-root",
36
- "/api/files/route": "/api/files",
37
- "/api/terminal/input/route": "/api/terminal/input",
38
- "/api/visualizer/route": "/api/visualizer",
37
+ "/api/terminal/sessions/route": "/api/terminal/sessions",
39
38
  "/api/terminal/stream/route": "/api/terminal/stream",
40
39
  "/api/undo/route": "/api/undo",
41
- "/api/terminal/sessions/route": "/api/terminal/sessions",
40
+ "/api/files/route": "/api/files",
41
+ "/api/terminal/upload/route": "/api/terminal/upload",
42
+ "/api/visualizer/route": "/api/visualizer",
42
43
  "/api/update/route": "/api/update",
43
44
  "/api/remote-questions/route": "/api/remote-questions",
44
- "/api/terminal/upload/route": "/api/terminal/upload",
45
45
  "/page": "/"
46
46
  }
@@ -4,14 +4,14 @@
4
4
  ],
5
5
  "devFiles": [],
6
6
  "lowPriorityFiles": [
7
- "static/YO-PWFRitlHM-L-dotlmm/_buildManifest.js",
8
- "static/YO-PWFRitlHM-L-dotlmm/_ssgManifest.js"
7
+ "static/mWBOLPnUoeaTGiD-vhu5O/_buildManifest.js",
8
+ "static/mWBOLPnUoeaTGiD-vhu5O/_ssgManifest.js"
9
9
  ],
10
10
  "rootMainFiles": [
11
11
  "static/chunks/webpack-bca0e732db0dcec3.js",
12
12
  "static/chunks/4bd1b696-e5d7c65570c947b7.js",
13
13
  "static/chunks/3794-337d1ca25ad99a89.js",
14
- "static/chunks/main-app-fdab67f7802d7832.js"
14
+ "static/chunks/main-app-d3d4c336195465f9.js"
15
15
  ],
16
16
  "rootMainFilesTree": {},
17
17
  "pages": {
@@ -78,8 +78,8 @@
78
78
  "dynamicRoutes": {},
79
79
  "notFoundRoutes": [],
80
80
  "preview": {
81
- "previewModeId": "01331f5d86acc7be1d3ecc8d5855e334",
82
- "previewModeSigningKey": "8b6653cdd01c63bde017b6a42df870bc138ec94025546cdb71ac3548cfea7fa6",
83
- "previewModeEncryptionKey": "2d7b20c003d03450d2f327b36c6e5db81437c825c1417b0299956d4083d83ea7"
81
+ "previewModeId": "d295367633ac46f8d8b141bc50fa0ae0",
82
+ "previewModeSigningKey": "544b70ab915f56609f2afe474d867f217ec3842f3ef6b58de09607bbafb0e432",
83
+ "previewModeEncryptionKey": "389e809ac429411dec37ec0518d948521954643fc0f04066066ec0af454d99a5"
84
84
  }
85
85
  }
@@ -100,7 +100,7 @@
100
100
  "transform": "lodash/{{member}}"
101
101
  }
102
102
  },
103
- "outputFileTracingRoot": "/__w/gsd-2/gsd-2",
103
+ "outputFileTracingRoot": "/home/runner/_work/gsd-2/gsd-2",
104
104
  "cacheComponents": false,
105
105
  "cacheLife": {
106
106
  "default": {
@@ -157,7 +157,7 @@
157
157
  "proxyPrefetch": "flexible",
158
158
  "optimisticClientCache": true,
159
159
  "manualClientBasePath": false,
160
- "cpus": 5,
160
+ "cpus": 9,
161
161
  "memoryBasedWorkersCount": false,
162
162
  "imgOptConcurrency": null,
163
163
  "imgOptTimeoutInSeconds": 7,
@@ -297,11 +297,11 @@
297
297
  "node-pty"
298
298
  ],
299
299
  "turbopack": {
300
- "root": "/__w/gsd-2/gsd-2"
300
+ "root": "/home/runner/_work/gsd-2/gsd-2"
301
301
  },
302
302
  "distDirRoot": ".next"
303
303
  },
304
- "appDir": "/__w/gsd-2/gsd-2/web",
304
+ "appDir": "/home/runner/_work/gsd-2/gsd-2/web",
305
305
  "relativeAppDir": "web",
306
306
  "files": [
307
307
  ".next/routes-manifest.json",