lsd-pi 1.2.3 → 1.3.2

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 (254) hide show
  1. package/README.md +22 -16
  2. package/dist/app-paths.d.ts +4 -0
  3. package/dist/app-paths.js +4 -0
  4. package/dist/bedrock-auth.d.ts +4 -0
  5. package/dist/bedrock-auth.js +4 -0
  6. package/dist/bundled-extension-paths.d.ts +4 -0
  7. package/dist/bundled-extension-paths.js +4 -0
  8. package/dist/cli-theme.d.ts +2 -2
  9. package/dist/cli-theme.js +13 -14
  10. package/dist/cli.js +43 -3
  11. package/dist/codex-rotate-settings.d.ts +4 -0
  12. package/dist/codex-rotate-settings.js +4 -0
  13. package/dist/help-text.d.ts +4 -0
  14. package/dist/help-text.js +4 -0
  15. package/dist/lsd-brand.d.ts +4 -0
  16. package/dist/lsd-brand.js +4 -0
  17. package/dist/onboarding-llm.d.ts +5 -0
  18. package/dist/onboarding-llm.js +5 -0
  19. package/dist/project-sessions.d.ts +4 -0
  20. package/dist/project-sessions.js +4 -0
  21. package/dist/resources/agents/generic.md +1 -0
  22. package/dist/resources/agents/scout.md +8 -1
  23. package/dist/resources/agents/worker.md +1 -0
  24. package/dist/resources/extensions/ask-user-questions.js +70 -0
  25. package/dist/resources/extensions/bg-shell/bg-shell-tool.js +6 -16
  26. package/dist/resources/extensions/mac-tools/index.js +19 -34
  27. package/dist/resources/extensions/memory/index.js +20 -2
  28. package/dist/resources/extensions/shared/interview-ui.js +103 -20
  29. package/dist/resources/extensions/slash-commands/plan.js +18 -17
  30. package/dist/resources/extensions/slash-commands/tools.js +40 -4
  31. package/dist/resources/extensions/subagent/agent-switcher-component.js +208 -0
  32. package/dist/resources/extensions/subagent/agent-switcher-model.js +107 -0
  33. package/dist/resources/extensions/subagent/agents.js +2 -1
  34. package/dist/resources/extensions/subagent/background-job-manager.js +11 -6
  35. package/dist/resources/extensions/subagent/background-runner.js +4 -0
  36. package/dist/resources/extensions/subagent/index.js +714 -21
  37. package/dist/resources/extensions/subagent/launch-helpers.js +21 -6
  38. package/dist/shared-paths.d.ts +4 -0
  39. package/dist/shared-paths.js +4 -0
  40. package/dist/shared-preferences.d.ts +4 -0
  41. package/dist/shared-preferences.js +4 -0
  42. package/dist/startup-model-validation.d.ts +1 -1
  43. package/dist/startup-timings.d.ts +4 -0
  44. package/dist/startup-timings.js +4 -0
  45. package/dist/update-check.d.ts +4 -0
  46. package/dist/update-check.js +4 -0
  47. package/dist/update-cmd.d.ts +4 -0
  48. package/dist/update-cmd.js +4 -0
  49. package/dist/welcome-screen.js +4 -4
  50. package/dist/wizard.d.ts +4 -0
  51. package/dist/wizard.js +4 -0
  52. package/package.json +1 -1
  53. package/packages/pi-agent-core/dist/agent.d.ts +9 -0
  54. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  55. package/packages/pi-agent-core/dist/agent.js +89 -5
  56. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  57. package/packages/pi-agent-core/dist/types.d.ts +13 -2
  58. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  59. package/packages/pi-agent-core/dist/types.js.map +1 -1
  60. package/packages/pi-agent-core/src/agent.ts +110 -4
  61. package/packages/pi-agent-core/src/types.ts +12 -3
  62. package/packages/pi-ai/dist/adaptive/classifier.d.ts +29 -0
  63. package/packages/pi-ai/dist/adaptive/classifier.d.ts.map +1 -0
  64. package/packages/pi-ai/dist/adaptive/classifier.js +72 -0
  65. package/packages/pi-ai/dist/adaptive/classifier.js.map +1 -0
  66. package/packages/pi-ai/dist/adaptive/classifier.test.d.ts +2 -0
  67. package/packages/pi-ai/dist/adaptive/classifier.test.d.ts.map +1 -0
  68. package/packages/pi-ai/dist/adaptive/classifier.test.js +32 -0
  69. package/packages/pi-ai/dist/adaptive/classifier.test.js.map +1 -0
  70. package/packages/pi-ai/dist/index.d.ts +1 -0
  71. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  72. package/packages/pi-ai/dist/index.js +1 -0
  73. package/packages/pi-ai/dist/index.js.map +1 -1
  74. package/packages/pi-ai/dist/providers/amazon-bedrock.js +0 -2
  75. package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  76. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  77. package/packages/pi-ai/dist/providers/anthropic-shared.js +11 -3
  78. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  79. package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts +1 -1
  80. package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
  81. package/packages/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
  82. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
  83. package/packages/pi-ai/dist/providers/google-gemini-cli.js +0 -4
  84. package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
  85. package/packages/pi-ai/dist/providers/google-vertex.js +0 -5
  86. package/packages/pi-ai/dist/providers/google-vertex.js.map +1 -1
  87. package/packages/pi-ai/dist/providers/google.js +0 -5
  88. package/packages/pi-ai/dist/providers/google.js.map +1 -1
  89. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts +1 -1
  90. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  91. package/packages/pi-ai/dist/providers/openai-codex-responses.js +0 -2
  92. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  93. package/packages/pi-ai/dist/providers/openai-completions.d.ts +1 -1
  94. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  95. package/packages/pi-ai/dist/providers/openai-completions.js +0 -1
  96. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  97. package/packages/pi-ai/dist/providers/openai-responses.d.ts +1 -1
  98. package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
  99. package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
  100. package/packages/pi-ai/dist/providers/openai-shared.d.ts +0 -1
  101. package/packages/pi-ai/dist/providers/openai-shared.d.ts.map +1 -1
  102. package/packages/pi-ai/dist/providers/openai-shared.js +0 -4
  103. package/packages/pi-ai/dist/providers/openai-shared.js.map +1 -1
  104. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  105. package/packages/pi-ai/dist/providers/simple-options.js +0 -1
  106. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  107. package/packages/pi-ai/dist/types.d.ts +1 -2
  108. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  109. package/packages/pi-ai/dist/types.js.map +1 -1
  110. package/packages/pi-ai/src/adaptive/classifier.test.ts +38 -0
  111. package/packages/pi-ai/src/adaptive/classifier.ts +107 -0
  112. package/packages/pi-ai/src/index.ts +1 -0
  113. package/packages/pi-ai/src/providers/amazon-bedrock.ts +0 -2
  114. package/packages/pi-ai/src/providers/anthropic-shared.ts +12 -3
  115. package/packages/pi-ai/src/providers/azure-openai-responses.ts +1 -1
  116. package/packages/pi-ai/src/providers/google-gemini-cli.ts +0 -4
  117. package/packages/pi-ai/src/providers/google-vertex.ts +0 -5
  118. package/packages/pi-ai/src/providers/google.ts +0 -5
  119. package/packages/pi-ai/src/providers/openai-codex-responses.ts +1 -3
  120. package/packages/pi-ai/src/providers/openai-completions.ts +1 -2
  121. package/packages/pi-ai/src/providers/openai-responses.ts +1 -1
  122. package/packages/pi-ai/src/providers/openai-shared.ts +0 -3
  123. package/packages/pi-ai/src/providers/simple-options.ts +0 -1
  124. package/packages/pi-ai/src/types.ts +1 -2
  125. package/packages/pi-coding-agent/dist/cli/args.js +2 -2
  126. package/packages/pi-coding-agent/dist/cli/args.js.map +1 -1
  127. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +7 -2
  128. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  129. package/packages/pi-coding-agent/dist/core/agent-session.js +62 -23
  130. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  131. package/packages/pi-coding-agent/dist/core/lsp/lsp.md +3 -1
  132. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  133. package/packages/pi-coding-agent/dist/core/sdk.js +32 -6
  134. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  135. package/packages/pi-coding-agent/dist/core/sdk.test.js +37 -0
  136. package/packages/pi-coding-agent/dist/core/sdk.test.js.map +1 -1
  137. package/packages/pi-coding-agent/dist/core/session-manager.d.ts +8 -0
  138. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  139. package/packages/pi-coding-agent/dist/core/session-manager.js +4 -0
  140. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  141. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +12 -7
  142. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  143. package/packages/pi-coding-agent/dist/core/settings-manager.js +20 -2
  144. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  145. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  146. package/packages/pi-coding-agent/dist/core/skills.js +4 -1
  147. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  148. package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -1
  149. package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
  150. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  151. package/packages/pi-coding-agent/dist/core/system-prompt.js +6 -2
  152. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  153. package/packages/pi-coding-agent/dist/core/tools/grep.js +1 -1
  154. package/packages/pi-coding-agent/dist/core/tools/grep.js.map +1 -1
  155. package/packages/pi-coding-agent/dist/core/tools/index.d.ts +2 -0
  156. package/packages/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
  157. package/packages/pi-coding-agent/dist/core/tools/index.js +2 -0
  158. package/packages/pi-coding-agent/dist/core/tools/index.js.map +1 -1
  159. package/packages/pi-coding-agent/dist/core/tools/pty.d.ts +10 -1
  160. package/packages/pi-coding-agent/dist/core/tools/pty.d.ts.map +1 -1
  161. package/packages/pi-coding-agent/dist/core/tools/pty.js +29 -3
  162. package/packages/pi-coding-agent/dist/core/tools/pty.js.map +1 -1
  163. package/packages/pi-coding-agent/dist/modes/interactive/components/embedded-terminal.js +1 -1
  164. package/packages/pi-coding-agent/dist/modes/interactive/components/embedded-terminal.js.map +1 -1
  165. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  166. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +12 -2
  167. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  168. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +7 -2
  169. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  170. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +23 -4
  171. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  172. package/packages/pi-coding-agent/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  173. package/packages/pi-coding-agent/dist/modes/interactive/components/thinking-selector.js +1 -2
  174. package/packages/pi-coding-agent/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  175. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  176. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +9 -0
  177. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  178. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  179. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +53 -2
  180. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  181. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +2 -2
  182. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  183. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +10 -6
  184. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  185. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +1 -1
  186. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  187. package/packages/pi-coding-agent/dist/modes/print-mode.d.ts.map +1 -1
  188. package/packages/pi-coding-agent/dist/modes/print-mode.js +6 -0
  189. package/packages/pi-coding-agent/dist/modes/print-mode.js.map +1 -1
  190. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  191. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +20 -0
  192. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  193. package/packages/pi-coding-agent/dist/tests/path-display.test.js +15 -0
  194. package/packages/pi-coding-agent/dist/tests/path-display.test.js.map +1 -1
  195. package/packages/pi-coding-agent/package.json +1 -1
  196. package/packages/pi-coding-agent/src/cli/args.ts +2 -2
  197. package/packages/pi-coding-agent/src/core/agent-session.ts +67 -25
  198. package/packages/pi-coding-agent/src/core/lsp/lsp.md +3 -1
  199. package/packages/pi-coding-agent/src/core/sdk.test.ts +45 -0
  200. package/packages/pi-coding-agent/src/core/sdk.ts +35 -6
  201. package/packages/pi-coding-agent/src/core/session-manager.ts +12 -0
  202. package/packages/pi-coding-agent/src/core/settings-manager.ts +32 -9
  203. package/packages/pi-coding-agent/src/core/skills.ts +4 -1
  204. package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -1
  205. package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -2
  206. package/packages/pi-coding-agent/src/core/tools/grep.ts +1 -1
  207. package/packages/pi-coding-agent/src/core/tools/index.ts +3 -0
  208. package/packages/pi-coding-agent/src/core/tools/pty.ts +45 -6
  209. package/packages/pi-coding-agent/src/modes/interactive/components/embedded-terminal.ts +1 -1
  210. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +10 -2
  211. package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +31 -7
  212. package/packages/pi-coding-agent/src/modes/interactive/components/thinking-selector.ts +1 -2
  213. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +9 -0
  214. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +65 -3
  215. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +11 -7
  216. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +1 -1
  217. package/packages/pi-coding-agent/src/modes/print-mode.ts +6 -0
  218. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +29 -0
  219. package/packages/pi-coding-agent/src/tests/path-display.test.ts +17 -0
  220. package/packages/pi-tui/dist/components/loader.d.ts +5 -2
  221. package/packages/pi-tui/dist/components/loader.d.ts.map +1 -1
  222. package/packages/pi-tui/dist/components/loader.js +33 -3
  223. package/packages/pi-tui/dist/components/loader.js.map +1 -1
  224. package/packages/pi-tui/src/components/loader.ts +31 -3
  225. package/packages/rpc-client/src/index.ts +1 -1
  226. package/packages/rpc-client/src/rpc-client.ts +29 -0
  227. package/packages/rpc-client/src/rpc-types.ts +1 -1
  228. package/pkg/dist/modes/interactive/theme/theme.d.ts +2 -2
  229. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  230. package/pkg/dist/modes/interactive/theme/theme.js +10 -6
  231. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  232. package/pkg/dist/modes/interactive/theme/themes.js +1 -1
  233. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  234. package/pkg/package.json +1 -1
  235. package/src/resources/agents/generic.md +1 -0
  236. package/src/resources/agents/scout.md +8 -1
  237. package/src/resources/agents/worker.md +1 -0
  238. package/src/resources/extensions/ask-user-questions.ts +88 -0
  239. package/src/resources/extensions/bg-shell/bg-shell-tool.ts +6 -16
  240. package/src/resources/extensions/mac-tools/index.ts +19 -34
  241. package/src/resources/extensions/memory/index.ts +22 -2
  242. package/src/resources/extensions/shared/interview-ui.ts +108 -15
  243. package/src/resources/extensions/shared/tests/ask-user-freetext.test.ts +61 -0
  244. package/src/resources/extensions/shared/tests/custom-ui-fallbacks.test.ts +46 -0
  245. package/src/resources/extensions/slash-commands/plan.ts +18 -19
  246. package/src/resources/extensions/slash-commands/tools.ts +43 -4
  247. package/src/resources/extensions/subagent/agent-switcher-component.ts +228 -0
  248. package/src/resources/extensions/subagent/agent-switcher-model.ts +160 -0
  249. package/src/resources/extensions/subagent/agents.ts +2 -1
  250. package/src/resources/extensions/subagent/background-job-manager.ts +29 -6
  251. package/src/resources/extensions/subagent/background-runner.ts +8 -0
  252. package/src/resources/extensions/subagent/background-types.ts +4 -0
  253. package/src/resources/extensions/subagent/index.ts +834 -19
  254. package/src/resources/extensions/subagent/launch-helpers.ts +16 -4
@@ -147,11 +147,26 @@ class PtySessionManager {
147
147
  const timeoutMs = Math.max(50, options?.timeoutMs ?? 30000);
148
148
  const stableMs = Math.max(50, options?.stableMs ?? 800);
149
149
  const view = options?.view ?? "viewport";
150
+ const signal = options?.signal;
151
+ const onUpdate = options?.onUpdate;
150
152
  const start = Date.now();
151
153
  let lastSnapshot = "";
152
154
  let stableSince = Date.now();
155
+ let lastUpdateText = "";
153
156
  while (Date.now() - start < timeoutMs) {
157
+ if (signal?.aborted) {
158
+ throw new Error(`pty_wait cancelled`);
159
+ }
154
160
  const { text } = await this.read(sessionId, view);
161
+ // Push live screen text updates to UI
162
+ if (onUpdate && text !== lastUpdateText) {
163
+ lastUpdateText = text;
164
+ const session = this.get(sessionId);
165
+ onUpdate({
166
+ content: [{ type: "text", text: buildReadText(session, view, text) }],
167
+ details: { sessionId, pid: session.pty.handle.pid, completed: session.completed, cancelled: session.cancelled, exitCode: session.exitCode, view, screenText: text },
168
+ });
169
+ }
155
170
  if (options?.text) {
156
171
  if (text.includes(options.text)) {
157
172
  return { session: this.get(sessionId), text };
@@ -169,7 +184,10 @@ class PtySessionManager {
169
184
  return { session: this.get(sessionId), text };
170
185
  }
171
186
  }
172
- await new Promise((resolve) => setTimeout(resolve, 100));
187
+ await new Promise((resolve) => {
188
+ const t = setTimeout(resolve, 100);
189
+ signal?.addEventListener("abort", () => { clearTimeout(t); resolve(); }, { once: true });
190
+ });
173
191
  }
174
192
  await this.read(sessionId, view);
175
193
  throw new Error(options?.text
@@ -240,9 +258,9 @@ export function createPtyTools(cwd) {
240
258
  label: "pty_wait",
241
259
  description: "Wait until text appears in a PTY session or until the PTY screen stops changing. Useful between pty_send calls.",
242
260
  parameters: ptyWaitSchema,
243
- execute: async (_toolCallId, { sessionId, text, view, timeoutMs, stableMs }) => {
261
+ execute: async (_toolCallId, { sessionId, text, view, timeoutMs, stableMs }, signal, onUpdate) => {
244
262
  const effectiveView = view ?? "viewport";
245
- const result = await manager.wait(sessionId, { text, view: effectiveView, timeoutMs, stableMs });
263
+ const result = await manager.wait(sessionId, { text, view: effectiveView, timeoutMs, stableMs, signal, onUpdate: onUpdate });
246
264
  return {
247
265
  content: [{ type: "text", text: buildReadText(result.session, effectiveView, result.text) }],
248
266
  details: { sessionId, pid: result.session.pty.handle.pid, completed: result.session.completed, cancelled: result.session.cancelled, exitCode: result.session.exitCode, view: effectiveView, screenText: result.text },
@@ -276,6 +294,13 @@ export function createPtyTools(cwd) {
276
294
  };
277
295
  },
278
296
  };
297
+ /** Write raw input to an active PTY session by ID. Used by the UI when the user focuses and types into an agent PTY terminal. */
298
+ function writeToSession(sessionId, input) {
299
+ const session = manager.sessions.get(sessionId);
300
+ if (session && !session.completed && session.pty.handle.isActive()) {
301
+ session.pty.handle.write(input);
302
+ }
303
+ }
279
304
  return {
280
305
  pty_start: ptyStartTool,
281
306
  pty_send: ptySendTool,
@@ -283,6 +308,7 @@ export function createPtyTools(cwd) {
283
308
  pty_wait: ptyWaitTool,
284
309
  pty_resize: ptyResizeTool,
285
310
  pty_kill: ptyKillTool,
311
+ writeToSession,
286
312
  };
287
313
  }
288
314
  export const ptyToolNames = ["pty_start", "pty_send", "pty_read", "pty_wait", "pty_resize", "pty_kill"];
@@ -1 +1 @@
1
- {"version":3,"file":"pty.js","sourceRoot":"","sources":["../../../src/core/tools/pty.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type { AgentTool } from \"@gsd/pi-agent-core\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport { executeBashInPty, type PtyExecutionSession } from \"../pty-executor.js\";\nimport {\n\tcreateHeadlessTerminal,\n\tsnapshotTerminalBufferText,\n\tsnapshotTerminalViewportText,\n\ttype HeadlessTerminal,\n} from \"../../utils/terminal-screen.js\";\n\nconst ptyStartSchema = Type.Object({\n\tcommand: Type.String({ description: \"Shell command to start inside the PTY\" }),\n\tcols: Type.Optional(Type.Number({ description: \"Terminal width in columns (default 80)\" })),\n\trows: Type.Optional(Type.Number({ description: \"Terminal height in rows (default 24)\" })),\n\tloginShell: Type.Optional(Type.Boolean({ description: \"Whether to run the command in a login shell\" })),\n});\n\nconst ptySendSchema = Type.Object({\n\tsessionId: Type.String({ description: \"PTY session id from pty_start\" }),\n\tinput: Type.String({ description: \"Text or control sequence to send, e.g. \\\"y\\\\r\\\" or \\\"\\\\u001b[A\\\"\" }),\n});\n\nconst ptyReadSchema = Type.Object({\n\tsessionId: Type.String({ description: \"PTY session id from pty_start\" }),\n\tview: Type.Optional(Type.Union([\n\t\tType.Literal(\"viewport\"),\n\t\tType.Literal(\"buffer\"),\n\t], { description: \"Read the visible screen (viewport) or the full logical buffer\" })),\n});\n\nconst ptyWaitSchema = Type.Object({\n\tsessionId: Type.String({ description: \"PTY session id from pty_start\" }),\n\ttext: Type.Optional(Type.String({ description: \"Wait until the viewport or buffer contains this text\" })),\n\tview: Type.Optional(Type.Union([\n\t\tType.Literal(\"viewport\"),\n\t\tType.Literal(\"buffer\"),\n\t], { description: \"Where to search for the text (default viewport)\" })),\n\ttimeoutMs: Type.Optional(Type.Number({ description: \"How long to wait before timing out (default 30000)\" })),\n\tstableMs: Type.Optional(Type.Number({ description: \"If text is omitted, wait until the screen stops changing for this long (default 800)\" })),\n});\n\nconst ptyResizeSchema = Type.Object({\n\tsessionId: Type.String({ description: \"PTY session id from pty_start\" }),\n\tcols: Type.Number({ description: \"Terminal width in columns\" }),\n\trows: Type.Number({ description: \"Terminal height in rows\" }),\n});\n\nconst ptyKillSchema = Type.Object({\n\tsessionId: Type.String({ description: \"PTY session id from pty_start\" }),\n});\n\nexport type PtyStartInput = Static<typeof ptyStartSchema>;\nexport type PtySendInput = Static<typeof ptySendSchema>;\nexport type PtyReadInput = Static<typeof ptyReadSchema>;\nexport type PtyWaitInput = Static<typeof ptyWaitSchema>;\nexport type PtyResizeInput = Static<typeof ptyResizeSchema>;\nexport type PtyKillInput = Static<typeof ptyKillSchema>;\n\ninterface ManagedPtySession {\n\tid: string;\n\tcommand: string;\n\tpty: PtyExecutionSession;\n\tterminal: HeadlessTerminal;\n\twriteChain: Promise<void>;\n\tcompleted: boolean;\n\tcancelled: boolean;\n\texitCode?: number;\n\tcreatedAt: number;\n\tlastUpdateAt: number;\n}\n\nexport interface PtyToolDetails {\n\tsessionId: string;\n\tpid?: number;\n\tcompleted?: boolean;\n\tcancelled?: boolean;\n\texitCode?: number;\n\tview?: \"viewport\" | \"buffer\";\n\tscreenText?: string;\n}\n\nclass PtySessionManager {\n\tprivate sessions = new Map<string, ManagedPtySession>();\n\n\tconstructor(private cwd: string) {}\n\n\tasync start(command: string, options?: { cols?: number; rows?: number; loginShell?: boolean }): Promise<ManagedPtySession> {\n\t\tconst id = `pty_${randomUUID().slice(0, 8)}`;\n\t\tconst terminal = createHeadlessTerminal(options?.cols ?? 80, options?.rows ?? 24, 10000);\n\t\tconst session: ManagedPtySession = {\n\t\t\tid,\n\t\t\tcommand,\n\t\t\tpty: undefined as unknown as PtyExecutionSession,\n\t\t\tterminal,\n\t\t\twriteChain: Promise.resolve(),\n\t\t\tcompleted: false,\n\t\t\tcancelled: false,\n\t\t\tcreatedAt: Date.now(),\n\t\t\tlastUpdateAt: Date.now(),\n\t\t};\n\t\tthis.sessions.set(id, session);\n\n\t\tlet pty: PtyExecutionSession;\n\t\ttry {\n\t\t\tpty = await executeBashInPty(command, {\n\t\t\t\tcols: options?.cols,\n\t\t\t\trows: options?.rows,\n\t\t\t\tcwd: this.cwd,\n\t\t\t\tloginShell: options?.loginShell,\n\t\t\t\tonChunk: (chunk) => {\n\t\t\t\t\tconst current = this.sessions.get(id);\n\t\t\t\t\tif (!current) return;\n\t\t\t\t\tcurrent.lastUpdateAt = Date.now();\n\t\t\t\t\tcurrent.writeChain = current.writeChain.then(\n\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\tnew Promise<void>((resolve) => {\n\t\t\t\t\t\t\t\tcurrent.terminal.write(chunk, () => resolve());\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthis.sessions.delete(id);\n\t\t\tthrow error;\n\t\t}\n\t\tsession.pty = pty;\n\n\t\tpty.result\n\t\t\t.then((result) => {\n\t\t\t\tconst current = this.sessions.get(id);\n\t\t\t\tif (!current) return;\n\t\t\t\tcurrent.completed = true;\n\t\t\t\tcurrent.cancelled = result.cancelled;\n\t\t\t\tcurrent.exitCode = result.exitCode;\n\t\t\t\tcurrent.lastUpdateAt = Date.now();\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tconst current = this.sessions.get(id);\n\t\t\t\tif (!current) return;\n\t\t\t\tcurrent.completed = true;\n\t\t\t\tcurrent.lastUpdateAt = Date.now();\n\t\t\t});\n\n\t\treturn session;\n\t}\n\n\tget(sessionId: string): ManagedPtySession {\n\t\tconst session = this.sessions.get(sessionId);\n\t\tif (!session) {\n\t\t\tthrow new Error(`PTY session not found: ${sessionId}`);\n\t\t}\n\t\treturn session;\n\t}\n\n\tasync send(sessionId: string, input: string): Promise<ManagedPtySession> {\n\t\tconst session = this.get(sessionId);\n\t\tif (session.completed || !session.pty.handle.isActive()) {\n\t\t\tthrow new Error(`PTY session is no longer active: ${sessionId}`);\n\t\t}\n\t\tsession.pty.handle.write(input);\n\t\tsession.lastUpdateAt = Date.now();\n\t\tawait new Promise((resolve) => setTimeout(resolve, 50));\n\t\treturn session;\n\t}\n\n\tasync resize(sessionId: string, cols: number, rows: number): Promise<ManagedPtySession> {\n\t\tconst session = this.get(sessionId);\n\t\tconst safeCols = Math.max(20, cols);\n\t\tconst safeRows = Math.max(5, rows);\n\t\tsession.pty.handle.resize(safeCols, safeRows);\n\t\tsession.terminal.resize(safeCols, safeRows);\n\t\tsession.lastUpdateAt = Date.now();\n\t\treturn session;\n\t}\n\n\tasync kill(sessionId: string): Promise<ManagedPtySession> {\n\t\tconst session = this.get(sessionId);\n\t\tif (session.pty.handle.isActive()) {\n\t\t\tsession.pty.handle.kill();\n\t\t}\n\t\tsession.cancelled = true;\n\t\tsession.completed = true;\n\t\tsession.lastUpdateAt = Date.now();\n\t\treturn session;\n\t}\n\n\tasync read(sessionId: string, view: \"viewport\" | \"buffer\" = \"viewport\"): Promise<{ session: ManagedPtySession; text: string }> {\n\t\tconst session = this.get(sessionId);\n\t\tawait session.writeChain;\n\t\tconst text = view === \"buffer\"\n\t\t\t? snapshotTerminalBufferText(session.terminal)\n\t\t\t: snapshotTerminalViewportText(session.terminal);\n\t\treturn { session, text };\n\t}\n\n\tasync wait(\n\t\tsessionId: string,\n\t\toptions?: { text?: string; view?: \"viewport\" | \"buffer\"; timeoutMs?: number; stableMs?: number },\n\t): Promise<{ session: ManagedPtySession; text: string }> {\n\t\tconst timeoutMs = Math.max(50, options?.timeoutMs ?? 30000);\n\t\tconst stableMs = Math.max(50, options?.stableMs ?? 800);\n\t\tconst view = options?.view ?? \"viewport\";\n\t\tconst start = Date.now();\n\t\tlet lastSnapshot = \"\";\n\t\tlet stableSince = Date.now();\n\n\t\twhile (Date.now() - start < timeoutMs) {\n\t\t\tconst { text } = await this.read(sessionId, view);\n\t\t\tif (options?.text) {\n\t\t\t\tif (text.includes(options.text)) {\n\t\t\t\t\treturn { session: this.get(sessionId), text };\n\t\t\t\t}\n\t\t\t\tif (this.get(sessionId).completed) {\n\t\t\t\t\treturn { session: this.get(sessionId), text };\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (text !== lastSnapshot) {\n\t\t\t\t\tlastSnapshot = text;\n\t\t\t\t\tstableSince = Date.now();\n\t\t\t\t} else if (Date.now() - stableSince >= stableMs || this.get(sessionId).completed) {\n\t\t\t\t\treturn { session: this.get(sessionId), text };\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 100));\n\t\t}\n\n\t\tawait this.read(sessionId, view);\n\t\tthrow new Error(\n\t\t\toptions?.text\n\t\t\t\t? `Timed out waiting for text in PTY session ${sessionId}: ${options.text}`\n\t\t\t\t: `Timed out waiting for PTY session ${sessionId} to stabilize`,\n\t\t);\n\t}\n}\n\nfunction formatSessionSummary(session: ManagedPtySession): string {\n\tconst bits = [`session ${session.id}`, `pid ${session.pty.handle.pid}`];\n\tif (session.completed) {\n\t\tbits.push(session.cancelled ? \"cancelled\" : `completed${session.exitCode !== undefined ? ` exit ${session.exitCode}` : \"\"}`);\n\t} else {\n\t\tbits.push(\"running\");\n\t}\n\treturn bits.join(\" · \");\n}\n\nfunction buildReadText(session: ManagedPtySession, view: \"viewport\" | \"buffer\", text: string): string {\n\tconst header = `[${formatSessionSummary(session)} · ${view}]`;\n\treturn text ? `${header}\\n${text}` : `${header}\\n(no visible text)`;\n}\n\nexport function createPtyTools(cwd: string): Record<string, AgentTool<any, PtyToolDetails>> {\n\tconst manager = new PtySessionManager(cwd);\n\n\tconst ptyStartTool: AgentTool<typeof ptyStartSchema, PtyToolDetails> = {\n\t\tname: \"pty_start\",\n\t\tlabel: \"pty_start\",\n\t\tdescription: \"Start an agent-controlled interactive PTY session. Use this when a command requires terminal interaction, prompts, or a full-screen TUI. Returns a sessionId for follow-up pty_send/pty_read/pty_wait/pty_kill calls.\",\n\t\tparameters: ptyStartSchema,\n\t\texecute: async (_toolCallId, { command, cols, rows, loginShell }) => {\n\t\t\tconst session = await manager.start(command, { cols, rows, loginShell });\n\t\t\tconst { text } = await manager.read(session.id, \"viewport\");\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: `Started PTY session ${session.id} for: ${command}\\n${buildReadText(session, \"viewport\", text)}` }],\n\t\t\t\tdetails: { sessionId: session.id, pid: session.pty.handle.pid, completed: session.completed, cancelled: session.cancelled, exitCode: session.exitCode, view: \"viewport\", screenText: text },\n\t\t\t};\n\t\t},\n\t};\n\n\tconst ptySendTool: AgentTool<typeof ptySendSchema, PtyToolDetails> = {\n\t\tname: \"pty_send\",\n\t\tlabel: \"pty_send\",\n\t\tdescription: \"Send text or control sequences to an existing PTY session, e.g. \\\"y\\\\r\\\" or \\\"\\\\u001b[A\\\".\",\n\t\tparameters: ptySendSchema,\n\t\texecute: async (_toolCallId, { sessionId, input }) => {\n\t\t\tconst session = await manager.send(sessionId, input);\n\t\t\tconst { text } = await manager.read(sessionId, \"viewport\");\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: `Sent input to ${sessionId}: ${JSON.stringify(input)}\\n${buildReadText(session, \"viewport\", text)}` }],\n\t\t\t\tdetails: { sessionId, pid: session.pty.handle.pid, completed: session.completed, cancelled: session.cancelled, exitCode: session.exitCode, view: \"viewport\", screenText: text },\n\t\t\t};\n\t\t},\n\t};\n\n\tconst ptyReadTool: AgentTool<typeof ptyReadSchema, PtyToolDetails> = {\n\t\tname: \"pty_read\",\n\t\tlabel: \"pty_read\",\n\t\tdescription: \"Read the current PTY screen state. Use view='viewport' for the visible screen or view='buffer' for the full logical buffer.\",\n\t\tparameters: ptyReadSchema,\n\t\texecute: async (_toolCallId, { sessionId, view }) => {\n\t\t\tconst effectiveView = view ?? \"viewport\";\n\t\t\tconst { session, text } = await manager.read(sessionId, effectiveView);\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: buildReadText(session, effectiveView, text) }],\n\t\t\t\tdetails: { sessionId, pid: session.pty.handle.pid, completed: session.completed, cancelled: session.cancelled, exitCode: session.exitCode, view: effectiveView, screenText: text },\n\t\t\t};\n\t\t},\n\t};\n\n\tconst ptyWaitTool: AgentTool<typeof ptyWaitSchema, PtyToolDetails> = {\n\t\tname: \"pty_wait\",\n\t\tlabel: \"pty_wait\",\n\t\tdescription: \"Wait until text appears in a PTY session or until the PTY screen stops changing. Useful between pty_send calls.\",\n\t\tparameters: ptyWaitSchema,\n\t\texecute: async (_toolCallId, { sessionId, text, view, timeoutMs, stableMs }) => {\n\t\t\tconst effectiveView = view ?? \"viewport\";\n\t\t\tconst result = await manager.wait(sessionId, { text, view: effectiveView, timeoutMs, stableMs });\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: buildReadText(result.session, effectiveView, result.text) }],\n\t\t\t\tdetails: { sessionId, pid: result.session.pty.handle.pid, completed: result.session.completed, cancelled: result.session.cancelled, exitCode: result.session.exitCode, view: effectiveView, screenText: result.text },\n\t\t\t};\n\t\t},\n\t};\n\n\tconst ptyResizeTool: AgentTool<typeof ptyResizeSchema, PtyToolDetails> = {\n\t\tname: \"pty_resize\",\n\t\tlabel: \"pty_resize\",\n\t\tdescription: \"Resize an active PTY session to the given terminal dimensions.\",\n\t\tparameters: ptyResizeSchema,\n\t\texecute: async (_toolCallId, { sessionId, cols, rows }) => {\n\t\t\tconst session = await manager.resize(sessionId, cols, rows);\n\t\t\tconst { text } = await manager.read(sessionId, \"viewport\");\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: `Resized ${sessionId} to ${cols}x${rows}\\n${buildReadText(session, \"viewport\", text)}` }],\n\t\t\t\tdetails: { sessionId, pid: session.pty.handle.pid, completed: session.completed, cancelled: session.cancelled, exitCode: session.exitCode, view: \"viewport\", screenText: text },\n\t\t\t};\n\t\t},\n\t};\n\n\tconst ptyKillTool: AgentTool<typeof ptyKillSchema, PtyToolDetails> = {\n\t\tname: \"pty_kill\",\n\t\tlabel: \"pty_kill\",\n\t\tdescription: \"Terminate an agent-controlled PTY session.\",\n\t\tparameters: ptyKillSchema,\n\t\texecute: async (_toolCallId, { sessionId }) => {\n\t\t\tconst session = await manager.kill(sessionId);\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: `Terminated PTY session ${sessionId}. ${formatSessionSummary(session)}` }],\n\t\t\t\tdetails: { sessionId, pid: session.pty.handle.pid, completed: session.completed, cancelled: session.cancelled, exitCode: session.exitCode },\n\t\t\t};\n\t\t},\n\t};\n\n\treturn {\n\t\tpty_start: ptyStartTool,\n\t\tpty_send: ptySendTool,\n\t\tpty_read: ptyReadTool,\n\t\tpty_wait: ptyWaitTool,\n\t\tpty_resize: ptyResizeTool,\n\t\tpty_kill: ptyKillTool,\n\t};\n}\n\nexport const ptyToolNames = [\"pty_start\", \"pty_send\", \"pty_read\", \"pty_wait\", \"pty_resize\", \"pty_kill\"] as const;\n"]}
1
+ {"version":3,"file":"pty.js","sourceRoot":"","sources":["../../../src/core/tools/pty.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type { AgentTool } from \"@gsd/pi-agent-core\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport { executeBashInPty, type PtyExecutionSession } from \"../pty-executor.js\";\nimport {\n\tcreateHeadlessTerminal,\n\tsnapshotTerminalBufferText,\n\tsnapshotTerminalViewportText,\n\ttype HeadlessTerminal,\n} from \"../../utils/terminal-screen.js\";\n\nconst ptyStartSchema = Type.Object({\n\tcommand: Type.String({ description: \"Shell command to start inside the PTY\" }),\n\tcols: Type.Optional(Type.Number({ description: \"Terminal width in columns (default 80)\" })),\n\trows: Type.Optional(Type.Number({ description: \"Terminal height in rows (default 24)\" })),\n\tloginShell: Type.Optional(Type.Boolean({ description: \"Whether to run the command in a login shell\" })),\n});\n\nconst ptySendSchema = Type.Object({\n\tsessionId: Type.String({ description: \"PTY session id from pty_start\" }),\n\tinput: Type.String({ description: \"Text or control sequence to send, e.g. \\\"y\\\\r\\\" or \\\"\\\\u001b[A\\\"\" }),\n});\n\nconst ptyReadSchema = Type.Object({\n\tsessionId: Type.String({ description: \"PTY session id from pty_start\" }),\n\tview: Type.Optional(Type.Union([\n\t\tType.Literal(\"viewport\"),\n\t\tType.Literal(\"buffer\"),\n\t], { description: \"Read the visible screen (viewport) or the full logical buffer\" })),\n});\n\nconst ptyWaitSchema = Type.Object({\n\tsessionId: Type.String({ description: \"PTY session id from pty_start\" }),\n\ttext: Type.Optional(Type.String({ description: \"Wait until the viewport or buffer contains this text\" })),\n\tview: Type.Optional(Type.Union([\n\t\tType.Literal(\"viewport\"),\n\t\tType.Literal(\"buffer\"),\n\t], { description: \"Where to search for the text (default viewport)\" })),\n\ttimeoutMs: Type.Optional(Type.Number({ description: \"How long to wait before timing out (default 30000)\" })),\n\tstableMs: Type.Optional(Type.Number({ description: \"If text is omitted, wait until the screen stops changing for this long (default 800)\" })),\n});\n\nconst ptyResizeSchema = Type.Object({\n\tsessionId: Type.String({ description: \"PTY session id from pty_start\" }),\n\tcols: Type.Number({ description: \"Terminal width in columns\" }),\n\trows: Type.Number({ description: \"Terminal height in rows\" }),\n});\n\nconst ptyKillSchema = Type.Object({\n\tsessionId: Type.String({ description: \"PTY session id from pty_start\" }),\n});\n\nexport type PtyStartInput = Static<typeof ptyStartSchema>;\nexport type PtySendInput = Static<typeof ptySendSchema>;\nexport type PtyReadInput = Static<typeof ptyReadSchema>;\nexport type PtyWaitInput = Static<typeof ptyWaitSchema>;\nexport type PtyResizeInput = Static<typeof ptyResizeSchema>;\nexport type PtyKillInput = Static<typeof ptyKillSchema>;\n\ninterface ManagedPtySession {\n\tid: string;\n\tcommand: string;\n\tpty: PtyExecutionSession;\n\tterminal: HeadlessTerminal;\n\twriteChain: Promise<void>;\n\tcompleted: boolean;\n\tcancelled: boolean;\n\texitCode?: number;\n\tcreatedAt: number;\n\tlastUpdateAt: number;\n}\n\nexport interface PtyToolDetails {\n\tsessionId: string;\n\tpid?: number;\n\tcompleted?: boolean;\n\tcancelled?: boolean;\n\texitCode?: number;\n\tview?: \"viewport\" | \"buffer\";\n\tscreenText?: string;\n}\n\nclass PtySessionManager {\n\treadonly sessions = new Map<string, ManagedPtySession>();\n\n\tconstructor(private cwd: string) {}\n\n\tasync start(command: string, options?: { cols?: number; rows?: number; loginShell?: boolean }): Promise<ManagedPtySession> {\n\t\tconst id = `pty_${randomUUID().slice(0, 8)}`;\n\t\tconst terminal = createHeadlessTerminal(options?.cols ?? 80, options?.rows ?? 24, 10000);\n\t\tconst session: ManagedPtySession = {\n\t\t\tid,\n\t\t\tcommand,\n\t\t\tpty: undefined as unknown as PtyExecutionSession,\n\t\t\tterminal,\n\t\t\twriteChain: Promise.resolve(),\n\t\t\tcompleted: false,\n\t\t\tcancelled: false,\n\t\t\tcreatedAt: Date.now(),\n\t\t\tlastUpdateAt: Date.now(),\n\t\t};\n\t\tthis.sessions.set(id, session);\n\n\t\tlet pty: PtyExecutionSession;\n\t\ttry {\n\t\t\tpty = await executeBashInPty(command, {\n\t\t\t\tcols: options?.cols,\n\t\t\t\trows: options?.rows,\n\t\t\t\tcwd: this.cwd,\n\t\t\t\tloginShell: options?.loginShell,\n\t\t\t\tonChunk: (chunk) => {\n\t\t\t\t\tconst current = this.sessions.get(id);\n\t\t\t\t\tif (!current) return;\n\t\t\t\t\tcurrent.lastUpdateAt = Date.now();\n\t\t\t\t\tcurrent.writeChain = current.writeChain.then(\n\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\tnew Promise<void>((resolve) => {\n\t\t\t\t\t\t\t\tcurrent.terminal.write(chunk, () => resolve());\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthis.sessions.delete(id);\n\t\t\tthrow error;\n\t\t}\n\t\tsession.pty = pty;\n\n\t\tpty.result\n\t\t\t.then((result) => {\n\t\t\t\tconst current = this.sessions.get(id);\n\t\t\t\tif (!current) return;\n\t\t\t\tcurrent.completed = true;\n\t\t\t\tcurrent.cancelled = result.cancelled;\n\t\t\t\tcurrent.exitCode = result.exitCode;\n\t\t\t\tcurrent.lastUpdateAt = Date.now();\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tconst current = this.sessions.get(id);\n\t\t\t\tif (!current) return;\n\t\t\t\tcurrent.completed = true;\n\t\t\t\tcurrent.lastUpdateAt = Date.now();\n\t\t\t});\n\n\t\treturn session;\n\t}\n\n\tget(sessionId: string): ManagedPtySession {\n\t\tconst session = this.sessions.get(sessionId);\n\t\tif (!session) {\n\t\t\tthrow new Error(`PTY session not found: ${sessionId}`);\n\t\t}\n\t\treturn session;\n\t}\n\n\tasync send(sessionId: string, input: string): Promise<ManagedPtySession> {\n\t\tconst session = this.get(sessionId);\n\t\tif (session.completed || !session.pty.handle.isActive()) {\n\t\t\tthrow new Error(`PTY session is no longer active: ${sessionId}`);\n\t\t}\n\t\tsession.pty.handle.write(input);\n\t\tsession.lastUpdateAt = Date.now();\n\t\tawait new Promise((resolve) => setTimeout(resolve, 50));\n\t\treturn session;\n\t}\n\n\tasync resize(sessionId: string, cols: number, rows: number): Promise<ManagedPtySession> {\n\t\tconst session = this.get(sessionId);\n\t\tconst safeCols = Math.max(20, cols);\n\t\tconst safeRows = Math.max(5, rows);\n\t\tsession.pty.handle.resize(safeCols, safeRows);\n\t\tsession.terminal.resize(safeCols, safeRows);\n\t\tsession.lastUpdateAt = Date.now();\n\t\treturn session;\n\t}\n\n\tasync kill(sessionId: string): Promise<ManagedPtySession> {\n\t\tconst session = this.get(sessionId);\n\t\tif (session.pty.handle.isActive()) {\n\t\t\tsession.pty.handle.kill();\n\t\t}\n\t\tsession.cancelled = true;\n\t\tsession.completed = true;\n\t\tsession.lastUpdateAt = Date.now();\n\t\treturn session;\n\t}\n\n\tasync read(sessionId: string, view: \"viewport\" | \"buffer\" = \"viewport\"): Promise<{ session: ManagedPtySession; text: string }> {\n\t\tconst session = this.get(sessionId);\n\t\tawait session.writeChain;\n\t\tconst text = view === \"buffer\"\n\t\t\t? snapshotTerminalBufferText(session.terminal)\n\t\t\t: snapshotTerminalViewportText(session.terminal);\n\t\treturn { session, text };\n\t}\n\n\tasync wait(\n\t\tsessionId: string,\n\t\toptions?: { text?: string; view?: \"viewport\" | \"buffer\"; timeoutMs?: number; stableMs?: number; signal?: AbortSignal; onUpdate?: (result: { content: Array<{ type: string; text: string }>; details: any }) => void },\n\t): Promise<{ session: ManagedPtySession; text: string }> {\n\t\tconst timeoutMs = Math.max(50, options?.timeoutMs ?? 30000);\n\t\tconst stableMs = Math.max(50, options?.stableMs ?? 800);\n\t\tconst view = options?.view ?? \"viewport\";\n\t\tconst signal = options?.signal;\n\t\tconst onUpdate = options?.onUpdate;\n\t\tconst start = Date.now();\n\t\tlet lastSnapshot = \"\";\n\t\tlet stableSince = Date.now();\n\t\tlet lastUpdateText = \"\";\n\n\t\twhile (Date.now() - start < timeoutMs) {\n\t\t\tif (signal?.aborted) {\n\t\t\t\tthrow new Error(`pty_wait cancelled`);\n\t\t\t}\n\t\t\tconst { text } = await this.read(sessionId, view);\n\n\t\t\t// Push live screen text updates to UI\n\t\t\tif (onUpdate && text !== lastUpdateText) {\n\t\t\t\tlastUpdateText = text;\n\t\t\t\tconst session = this.get(sessionId);\n\t\t\t\tonUpdate({\n\t\t\t\t\tcontent: [{ type: \"text\", text: buildReadText(session, view, text) }],\n\t\t\t\t\tdetails: { sessionId, pid: session.pty.handle.pid, completed: session.completed, cancelled: session.cancelled, exitCode: session.exitCode, view, screenText: text },\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (options?.text) {\n\t\t\t\tif (text.includes(options.text)) {\n\t\t\t\t\treturn { session: this.get(sessionId), text };\n\t\t\t\t}\n\t\t\t\tif (this.get(sessionId).completed) {\n\t\t\t\t\treturn { session: this.get(sessionId), text };\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (text !== lastSnapshot) {\n\t\t\t\t\tlastSnapshot = text;\n\t\t\t\t\tstableSince = Date.now();\n\t\t\t\t} else if (Date.now() - stableSince >= stableMs || this.get(sessionId).completed) {\n\t\t\t\t\treturn { session: this.get(sessionId), text };\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tconst t = setTimeout(resolve, 100);\n\t\t\t\tsignal?.addEventListener(\"abort\", () => { clearTimeout(t); resolve(); }, { once: true });\n\t\t\t});\n\t\t}\n\n\t\tawait this.read(sessionId, view);\n\t\tthrow new Error(\n\t\t\toptions?.text\n\t\t\t\t? `Timed out waiting for text in PTY session ${sessionId}: ${options.text}`\n\t\t\t\t: `Timed out waiting for PTY session ${sessionId} to stabilize`,\n\t\t);\n\t}\n}\n\nfunction formatSessionSummary(session: ManagedPtySession): string {\n\tconst bits = [`session ${session.id}`, `pid ${session.pty.handle.pid}`];\n\tif (session.completed) {\n\t\tbits.push(session.cancelled ? \"cancelled\" : `completed${session.exitCode !== undefined ? ` exit ${session.exitCode}` : \"\"}`);\n\t} else {\n\t\tbits.push(\"running\");\n\t}\n\treturn bits.join(\" · \");\n}\n\nfunction buildReadText(session: ManagedPtySession, view: \"viewport\" | \"buffer\", text: string): string {\n\tconst header = `[${formatSessionSummary(session)} · ${view}]`;\n\treturn text ? `${header}\\n${text}` : `${header}\\n(no visible text)`;\n}\n\nexport interface PtyToolsResult {\n\tpty_start: AgentTool<any, PtyToolDetails>;\n\tpty_send: AgentTool<any, PtyToolDetails>;\n\tpty_read: AgentTool<any, PtyToolDetails>;\n\tpty_wait: AgentTool<any, PtyToolDetails>;\n\tpty_resize: AgentTool<any, PtyToolDetails>;\n\tpty_kill: AgentTool<any, PtyToolDetails>;\n\twriteToSession: (sessionId: string, input: string) => void;\n}\n\nexport function createPtyTools(cwd: string): PtyToolsResult {\n\tconst manager = new PtySessionManager(cwd);\n\n\tconst ptyStartTool: AgentTool<typeof ptyStartSchema, PtyToolDetails> = {\n\t\tname: \"pty_start\",\n\t\tlabel: \"pty_start\",\n\t\tdescription: \"Start an agent-controlled interactive PTY session. Use this when a command requires terminal interaction, prompts, or a full-screen TUI. Returns a sessionId for follow-up pty_send/pty_read/pty_wait/pty_kill calls.\",\n\t\tparameters: ptyStartSchema,\n\t\texecute: async (_toolCallId, { command, cols, rows, loginShell }) => {\n\t\t\tconst session = await manager.start(command, { cols, rows, loginShell });\n\t\t\tconst { text } = await manager.read(session.id, \"viewport\");\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: `Started PTY session ${session.id} for: ${command}\\n${buildReadText(session, \"viewport\", text)}` }],\n\t\t\t\tdetails: { sessionId: session.id, pid: session.pty.handle.pid, completed: session.completed, cancelled: session.cancelled, exitCode: session.exitCode, view: \"viewport\", screenText: text },\n\t\t\t};\n\t\t},\n\t};\n\n\tconst ptySendTool: AgentTool<typeof ptySendSchema, PtyToolDetails> = {\n\t\tname: \"pty_send\",\n\t\tlabel: \"pty_send\",\n\t\tdescription: \"Send text or control sequences to an existing PTY session, e.g. \\\"y\\\\r\\\" or \\\"\\\\u001b[A\\\".\",\n\t\tparameters: ptySendSchema,\n\t\texecute: async (_toolCallId, { sessionId, input }) => {\n\t\t\tconst session = await manager.send(sessionId, input);\n\t\t\tconst { text } = await manager.read(sessionId, \"viewport\");\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: `Sent input to ${sessionId}: ${JSON.stringify(input)}\\n${buildReadText(session, \"viewport\", text)}` }],\n\t\t\t\tdetails: { sessionId, pid: session.pty.handle.pid, completed: session.completed, cancelled: session.cancelled, exitCode: session.exitCode, view: \"viewport\", screenText: text },\n\t\t\t};\n\t\t},\n\t};\n\n\tconst ptyReadTool: AgentTool<typeof ptyReadSchema, PtyToolDetails> = {\n\t\tname: \"pty_read\",\n\t\tlabel: \"pty_read\",\n\t\tdescription: \"Read the current PTY screen state. Use view='viewport' for the visible screen or view='buffer' for the full logical buffer.\",\n\t\tparameters: ptyReadSchema,\n\t\texecute: async (_toolCallId, { sessionId, view }) => {\n\t\t\tconst effectiveView = view ?? \"viewport\";\n\t\t\tconst { session, text } = await manager.read(sessionId, effectiveView);\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: buildReadText(session, effectiveView, text) }],\n\t\t\t\tdetails: { sessionId, pid: session.pty.handle.pid, completed: session.completed, cancelled: session.cancelled, exitCode: session.exitCode, view: effectiveView, screenText: text },\n\t\t\t};\n\t\t},\n\t};\n\n\tconst ptyWaitTool: AgentTool<typeof ptyWaitSchema, PtyToolDetails> = {\n\t\tname: \"pty_wait\",\n\t\tlabel: \"pty_wait\",\n\t\tdescription: \"Wait until text appears in a PTY session or until the PTY screen stops changing. Useful between pty_send calls.\",\n\t\tparameters: ptyWaitSchema,\n\t\texecute: async (_toolCallId, { sessionId, text, view, timeoutMs, stableMs }, signal, onUpdate) => {\n\t\t\tconst effectiveView = view ?? \"viewport\";\n\t\t\tconst result = await manager.wait(sessionId, { text, view: effectiveView, timeoutMs, stableMs, signal, onUpdate: onUpdate as ((result: { content: Array<{ type: string; text: string }>; details: any }) => void) | undefined });\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: buildReadText(result.session, effectiveView, result.text) }],\n\t\t\t\tdetails: { sessionId, pid: result.session.pty.handle.pid, completed: result.session.completed, cancelled: result.session.cancelled, exitCode: result.session.exitCode, view: effectiveView, screenText: result.text },\n\t\t\t};\n\t\t},\n\t};\n\n\tconst ptyResizeTool: AgentTool<typeof ptyResizeSchema, PtyToolDetails> = {\n\t\tname: \"pty_resize\",\n\t\tlabel: \"pty_resize\",\n\t\tdescription: \"Resize an active PTY session to the given terminal dimensions.\",\n\t\tparameters: ptyResizeSchema,\n\t\texecute: async (_toolCallId, { sessionId, cols, rows }) => {\n\t\t\tconst session = await manager.resize(sessionId, cols, rows);\n\t\t\tconst { text } = await manager.read(sessionId, \"viewport\");\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: `Resized ${sessionId} to ${cols}x${rows}\\n${buildReadText(session, \"viewport\", text)}` }],\n\t\t\t\tdetails: { sessionId, pid: session.pty.handle.pid, completed: session.completed, cancelled: session.cancelled, exitCode: session.exitCode, view: \"viewport\", screenText: text },\n\t\t\t};\n\t\t},\n\t};\n\n\tconst ptyKillTool: AgentTool<typeof ptyKillSchema, PtyToolDetails> = {\n\t\tname: \"pty_kill\",\n\t\tlabel: \"pty_kill\",\n\t\tdescription: \"Terminate an agent-controlled PTY session.\",\n\t\tparameters: ptyKillSchema,\n\t\texecute: async (_toolCallId, { sessionId }) => {\n\t\t\tconst session = await manager.kill(sessionId);\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: `Terminated PTY session ${sessionId}. ${formatSessionSummary(session)}` }],\n\t\t\t\tdetails: { sessionId, pid: session.pty.handle.pid, completed: session.completed, cancelled: session.cancelled, exitCode: session.exitCode },\n\t\t\t};\n\t\t},\n\t};\n\n\t/** Write raw input to an active PTY session by ID. Used by the UI when the user focuses and types into an agent PTY terminal. */\n\tfunction writeToSession(sessionId: string, input: string): void {\n\t\tconst session = manager.sessions.get(sessionId);\n\t\tif (session && !session.completed && session.pty.handle.isActive()) {\n\t\t\tsession.pty.handle.write(input);\n\t\t}\n\t}\n\n\treturn {\n\t\tpty_start: ptyStartTool,\n\t\tpty_send: ptySendTool,\n\t\tpty_read: ptyReadTool,\n\t\tpty_wait: ptyWaitTool,\n\t\tpty_resize: ptyResizeTool,\n\t\tpty_kill: ptyKillTool,\n\t\twriteToSession,\n\t};\n}\n\nexport const ptyToolNames = [\"pty_start\", \"pty_send\", \"pty_read\", \"pty_wait\", \"pty_resize\", \"pty_kill\"] as const;\n"]}
@@ -157,7 +157,7 @@ export class EmbeddedTerminalComponent {
157
157
  const command = theme.bold(`$ ${this.command}`);
158
158
  const hint = this.focused
159
159
  ? theme.fg("muted", "Tab/Esc return · Shift+Tab sends Tab")
160
- : theme.fg("muted", `${this.focusKeyLabel} focus`);
160
+ : theme.fg("muted", `${this.focusKeyLabel} to focus`);
161
161
  const left = `${prefix} ${command}`;
162
162
  const leftWidth = visibleWidth(left);
163
163
  const hintWidth = visibleWidth(hint);
@@ -1 +1 @@
1
- {"version":3,"file":"embedded-terminal.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/embedded-terminal.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Embedded PTY terminal for user-triggered bash commands.\n * Renders a framed terminal surface and forwards keystrokes to a PTY handle.\n */\n\nimport { decodeKittyPrintable, matchesKey, parseKey, type Focusable, type TUI } from \"@gsd/pi-tui\";\nimport { truncateToWidth, visibleWidth } from \"@gsd/pi-tui\";\nimport type { PtyExecutionHandle } from \"../../../core/pty-executor.js\";\nimport { createHeadlessTerminal, snapshotTerminalLines, type HeadlessTerminal } from \"../../../utils/terminal-screen.js\";\nimport { theme } from \"../theme/theme.js\";\n\ntype ToolOutputMode = \"minimal\" | \"normal\";\n\nexport class EmbeddedTerminalComponent implements Focusable {\n public focused = false;\n\n private command: string;\n private status: \"running\" | \"complete\" | \"cancelled\" | \"error\" = \"running\";\n private exitCode: number | undefined;\n private focusKeyLabel: string;\n private renderedLines: string[] = [];\n private rawOutput = \"\";\n private terminal: HeadlessTerminal;\n private terminalWriteChain: Promise<void> = Promise.resolve();\n private handle?: PtyExecutionHandle;\n private releaseFocus?: () => void;\n private statusOverride?: string;\n\n constructor(\n command: string,\n _ui: TUI,\n _renderMode: ToolOutputMode,\n focusKeyLabel: string,\n _excludeFromContext = false,\n ) {\n this.command = command;\n this.focusKeyLabel = focusKeyLabel;\n this.terminal = createHeadlessTerminal();\n }\n\n setHandle(handle: PtyExecutionHandle, releaseFocus: () => void): void {\n this.handle = handle;\n this.releaseFocus = releaseFocus;\n }\n\n setScreenText(text: string): void {\n this.rawOutput = text;\n this.renderedLines = text ? text.split(\"\\n\") : [];\n }\n\n setStatusOverride(text: string | undefined): void {\n this.statusOverride = text;\n }\n\n resize(cols: number, rows: number): void {\n const safeCols = Math.max(20, cols);\n const safeRows = Math.max(5, rows);\n this.handle?.resize(safeCols, safeRows);\n this.terminal.resize(safeCols, safeRows);\n this.renderedLines = snapshotTerminalLines(this.terminal);\n }\n\n setExpanded(_expanded: boolean): void {\n // Interactive terminals are always rendered expanded for now.\n }\n\n setRenderMode(_mode: ToolOutputMode): void {\n // Interactive terminals are always rendered expanded for now.\n }\n\n appendOutput(chunk: string): void {\n this.rawOutput += chunk;\n this.terminalWriteChain = this.terminalWriteChain.then(\n () =>\n new Promise<void>((resolve) => {\n this.terminal.write(chunk, () => {\n this.renderedLines = snapshotTerminalLines(this.terminal);\n resolve();\n });\n }),\n );\n }\n\n setComplete(exitCode: number | undefined, cancelled: boolean): void {\n this.exitCode = exitCode;\n this.status = cancelled\n ? \"cancelled\"\n : exitCode !== undefined && exitCode !== 0\n ? \"error\"\n : \"complete\";\n }\n\n getOutput(): string {\n return this.rawOutput;\n }\n\n handleInput(data: string): void {\n if (matchesKey(data, \"escape\") || matchesKey(data, \"tab\")) {\n this.releaseFocus?.();\n return;\n }\n\n const kittyPrintable = decodeKittyPrintable(data);\n if (kittyPrintable !== undefined) {\n this.handle?.write(kittyPrintable);\n return;\n }\n\n const key = parseKey(data);\n switch (key) {\n case \"enter\":\n case \"shift+enter\":\n this.handle?.write(\"\\r\");\n return;\n case \"shift+tab\":\n case \"tab\":\n this.handle?.write(\"\\t\");\n return;\n case \"backspace\":\n case \"shift+backspace\":\n this.handle?.write(\"\\x7f\");\n return;\n case \"up\":\n this.handle?.write(\"\\x1b[A\");\n return;\n case \"down\":\n this.handle?.write(\"\\x1b[B\");\n return;\n case \"right\":\n this.handle?.write(\"\\x1b[C\");\n return;\n case \"left\":\n this.handle?.write(\"\\x1b[D\");\n return;\n case \"ctrl+c\":\n this.handle?.write(\"\\x03\");\n return;\n case \"ctrl+d\":\n this.handle?.write(\"\\x04\");\n return;\n }\n\n if (data.length === 1 && data >= \" \" && data !== \"\\x7f\") {\n this.handle?.write(data);\n }\n }\n\n invalidate(): void {\n // No-op; render reads directly from current state.\n }\n\n render(width: number): string[] {\n const innerWidth = Math.max(10, width - 2);\n const frameColor = this.status === \"error\"\n ? \"error\"\n : this.focused\n ? \"success\"\n : \"success\";\n const border = (text: string) => theme.fg(frameColor, text);\n\n const lines: string[] = [];\n lines.push(border(`╭${\"─\".repeat(innerWidth)}╮`));\n\n for (const line of this.buildBodyLines(innerWidth)) {\n const content = truncateToWidth(line, innerWidth, \"\", true);\n lines.push(`${border(\"│\")}${content}${border(\"│\")}`);\n }\n\n lines.push(border(`╰${\"─\".repeat(innerWidth)}╯`));\n return lines;\n }\n\n private buildBodyLines(innerWidth: number): string[] {\n const body: string[] = [];\n body.push(this.buildHeaderText(innerWidth));\n body.push(\"\");\n\n const visibleTerminalLines = this.getVisibleTerminalLines();\n if (visibleTerminalLines.length > 0) {\n body.push(...visibleTerminalLines);\n } else if (this.status === \"running\") {\n body.push(theme.fg(\"dim\", \"Terminal waiting for output…\"));\n }\n\n body.push(\"\");\n body.push(this.buildStatusText(innerWidth));\n return body;\n }\n\n private getVisibleTerminalLines(): string[] {\n const lines = [...this.renderedLines];\n while (lines.length > 0 && lines[lines.length - 1] === \"\") {\n lines.pop();\n }\n return lines;\n }\n\n private buildHeaderText(innerWidth: number): string {\n const prefix = this.focused\n ? theme.fg(\"success\", theme.bold(\" TERMINAL \"))\n : theme.fg(\"success\", \" terminal \");\n const command = theme.bold(`$ ${this.command}`);\n const hint = this.focused\n ? theme.fg(\"muted\", \"Tab/Esc return · Shift+Tab sends Tab\")\n : theme.fg(\"muted\", `${this.focusKeyLabel} focus`);\n\n const left = `${prefix} ${command}`;\n const leftWidth = visibleWidth(left);\n const hintWidth = visibleWidth(hint);\n if (leftWidth + 2 + hintWidth <= innerWidth) {\n return left + \" \".repeat(innerWidth - leftWidth - hintWidth) + hint;\n }\n return truncateToWidth(`${left} ${hint}`, innerWidth, \"...\");\n }\n\n private buildStatusText(innerWidth: number): string {\n let statusText: string;\n if (this.status === \"running\") {\n statusText = this.statusOverride\n ? this.statusOverride\n : this.focused\n ? theme.fg(\"success\", theme.bold(\"INPUT CAPTURED\")) + theme.fg(\"muted\", \" — typing goes to the terminal\")\n : theme.fg(\"muted\", `Press ${this.focusKeyLabel} to focus this terminal`);\n } else if (this.status === \"cancelled\") {\n statusText = theme.fg(\"warning\", \"(cancelled)\");\n } else if (this.status === \"error\") {\n statusText = theme.fg(\"error\", `(exit ${this.exitCode})`);\n } else {\n statusText = theme.fg(\"success\", \"(done)\");\n }\n return truncateToWidth(statusText, innerWidth, \"...\");\n }\n}\n"]}
1
+ {"version":3,"file":"embedded-terminal.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/embedded-terminal.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Embedded PTY terminal for user-triggered bash commands.\n * Renders a framed terminal surface and forwards keystrokes to a PTY handle.\n */\n\nimport { decodeKittyPrintable, matchesKey, parseKey, type Focusable, type TUI } from \"@gsd/pi-tui\";\nimport { truncateToWidth, visibleWidth } from \"@gsd/pi-tui\";\nimport type { PtyExecutionHandle } from \"../../../core/pty-executor.js\";\nimport { createHeadlessTerminal, snapshotTerminalLines, type HeadlessTerminal } from \"../../../utils/terminal-screen.js\";\nimport { theme } from \"../theme/theme.js\";\n\ntype ToolOutputMode = \"minimal\" | \"normal\";\n\nexport class EmbeddedTerminalComponent implements Focusable {\n public focused = false;\n\n private command: string;\n private status: \"running\" | \"complete\" | \"cancelled\" | \"error\" = \"running\";\n private exitCode: number | undefined;\n private focusKeyLabel: string;\n private renderedLines: string[] = [];\n private rawOutput = \"\";\n private terminal: HeadlessTerminal;\n private terminalWriteChain: Promise<void> = Promise.resolve();\n private handle?: PtyExecutionHandle;\n private releaseFocus?: () => void;\n private statusOverride?: string;\n\n constructor(\n command: string,\n _ui: TUI,\n _renderMode: ToolOutputMode,\n focusKeyLabel: string,\n _excludeFromContext = false,\n ) {\n this.command = command;\n this.focusKeyLabel = focusKeyLabel;\n this.terminal = createHeadlessTerminal();\n }\n\n setHandle(handle: PtyExecutionHandle, releaseFocus: () => void): void {\n this.handle = handle;\n this.releaseFocus = releaseFocus;\n }\n\n setScreenText(text: string): void {\n this.rawOutput = text;\n this.renderedLines = text ? text.split(\"\\n\") : [];\n }\n\n setStatusOverride(text: string | undefined): void {\n this.statusOverride = text;\n }\n\n resize(cols: number, rows: number): void {\n const safeCols = Math.max(20, cols);\n const safeRows = Math.max(5, rows);\n this.handle?.resize(safeCols, safeRows);\n this.terminal.resize(safeCols, safeRows);\n this.renderedLines = snapshotTerminalLines(this.terminal);\n }\n\n setExpanded(_expanded: boolean): void {\n // Interactive terminals are always rendered expanded for now.\n }\n\n setRenderMode(_mode: ToolOutputMode): void {\n // Interactive terminals are always rendered expanded for now.\n }\n\n appendOutput(chunk: string): void {\n this.rawOutput += chunk;\n this.terminalWriteChain = this.terminalWriteChain.then(\n () =>\n new Promise<void>((resolve) => {\n this.terminal.write(chunk, () => {\n this.renderedLines = snapshotTerminalLines(this.terminal);\n resolve();\n });\n }),\n );\n }\n\n setComplete(exitCode: number | undefined, cancelled: boolean): void {\n this.exitCode = exitCode;\n this.status = cancelled\n ? \"cancelled\"\n : exitCode !== undefined && exitCode !== 0\n ? \"error\"\n : \"complete\";\n }\n\n getOutput(): string {\n return this.rawOutput;\n }\n\n handleInput(data: string): void {\n if (matchesKey(data, \"escape\") || matchesKey(data, \"tab\")) {\n this.releaseFocus?.();\n return;\n }\n\n const kittyPrintable = decodeKittyPrintable(data);\n if (kittyPrintable !== undefined) {\n this.handle?.write(kittyPrintable);\n return;\n }\n\n const key = parseKey(data);\n switch (key) {\n case \"enter\":\n case \"shift+enter\":\n this.handle?.write(\"\\r\");\n return;\n case \"shift+tab\":\n case \"tab\":\n this.handle?.write(\"\\t\");\n return;\n case \"backspace\":\n case \"shift+backspace\":\n this.handle?.write(\"\\x7f\");\n return;\n case \"up\":\n this.handle?.write(\"\\x1b[A\");\n return;\n case \"down\":\n this.handle?.write(\"\\x1b[B\");\n return;\n case \"right\":\n this.handle?.write(\"\\x1b[C\");\n return;\n case \"left\":\n this.handle?.write(\"\\x1b[D\");\n return;\n case \"ctrl+c\":\n this.handle?.write(\"\\x03\");\n return;\n case \"ctrl+d\":\n this.handle?.write(\"\\x04\");\n return;\n }\n\n if (data.length === 1 && data >= \" \" && data !== \"\\x7f\") {\n this.handle?.write(data);\n }\n }\n\n invalidate(): void {\n // No-op; render reads directly from current state.\n }\n\n render(width: number): string[] {\n const innerWidth = Math.max(10, width - 2);\n const frameColor = this.status === \"error\"\n ? \"error\"\n : this.focused\n ? \"success\"\n : \"success\";\n const border = (text: string) => theme.fg(frameColor, text);\n\n const lines: string[] = [];\n lines.push(border(`╭${\"─\".repeat(innerWidth)}╮`));\n\n for (const line of this.buildBodyLines(innerWidth)) {\n const content = truncateToWidth(line, innerWidth, \"\", true);\n lines.push(`${border(\"│\")}${content}${border(\"│\")}`);\n }\n\n lines.push(border(`╰${\"─\".repeat(innerWidth)}╯`));\n return lines;\n }\n\n private buildBodyLines(innerWidth: number): string[] {\n const body: string[] = [];\n body.push(this.buildHeaderText(innerWidth));\n body.push(\"\");\n\n const visibleTerminalLines = this.getVisibleTerminalLines();\n if (visibleTerminalLines.length > 0) {\n body.push(...visibleTerminalLines);\n } else if (this.status === \"running\") {\n body.push(theme.fg(\"dim\", \"Terminal waiting for output…\"));\n }\n\n body.push(\"\");\n body.push(this.buildStatusText(innerWidth));\n return body;\n }\n\n private getVisibleTerminalLines(): string[] {\n const lines = [...this.renderedLines];\n while (lines.length > 0 && lines[lines.length - 1] === \"\") {\n lines.pop();\n }\n return lines;\n }\n\n private buildHeaderText(innerWidth: number): string {\n const prefix = this.focused\n ? theme.fg(\"success\", theme.bold(\" TERMINAL \"))\n : theme.fg(\"success\", \" terminal \");\n const command = theme.bold(`$ ${this.command}`);\n const hint = this.focused\n ? theme.fg(\"muted\", \"Tab/Esc return · Shift+Tab sends Tab\")\n : theme.fg(\"muted\", `${this.focusKeyLabel} to focus`);\n\n const left = `${prefix} ${command}`;\n const leftWidth = visibleWidth(left);\n const hintWidth = visibleWidth(hint);\n if (leftWidth + 2 + hintWidth <= innerWidth) {\n return left + \" \".repeat(innerWidth - leftWidth - hintWidth) + hint;\n }\n return truncateToWidth(`${left} ${hint}`, innerWidth, \"...\");\n }\n\n private buildStatusText(innerWidth: number): string {\n let statusText: string;\n if (this.status === \"running\") {\n statusText = this.statusOverride\n ? this.statusOverride\n : this.focused\n ? theme.fg(\"success\", theme.bold(\"INPUT CAPTURED\")) + theme.fg(\"muted\", \" — typing goes to the terminal\")\n : theme.fg(\"muted\", `Press ${this.focusKeyLabel} to focus this terminal`);\n } else if (this.status === \"cancelled\") {\n statusText = theme.fg(\"warning\", \"(cancelled)\");\n } else if (this.status === \"error\") {\n statusText = theme.fg(\"error\", `(exit ${this.exitCode})`);\n } else {\n statusText = theme.fg(\"success\", \"(done)\");\n }\n return truncateToWidth(statusText, innerWidth, \"...\");\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/footer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAiC,MAAM,aAAa,CAAC;AAC5E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAC;AACxF,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,gCAAgC,CAAC;AA0BxF;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKrD;AAED;;;GAGG;AACH,qBAAa,eAAgB,YAAW,SAAS;IAK/C,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,UAAU;IALnB,OAAO,CAAC,kBAAkB,CAAQ;IAClC,OAAO,CAAC,cAAc,CAAwC;gBAGrD,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,0BAA0B;IAG/C,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAI7C,iBAAiB,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAI7C;;;OAGG;IACH,UAAU,IAAI,IAAI;IAIlB;;;OAGG;IACH,OAAO,IAAI,IAAI;IAIf,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CA8M/B"}
1
+ {"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/footer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAiC,MAAM,aAAa,CAAC;AAC5E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAC;AACxF,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,gCAAgC,CAAC;AA0BxF;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKrD;AAED;;;GAGG;AACH,qBAAa,eAAgB,YAAW,SAAS;IAK/C,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,UAAU;IALnB,OAAO,CAAC,kBAAkB,CAAQ;IAClC,OAAO,CAAC,cAAc,CAAwC;gBAGrD,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,0BAA0B;IAG/C,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAI7C,iBAAiB,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAI7C;;;OAGG;IACH,UAAU,IAAI,IAAI;IAIlB;;;OAGG;IACH,OAAO,IAAI,IAAI;IAIf,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAsN/B"}
@@ -207,8 +207,18 @@ export class FooterComponent {
207
207
  let rightSideWithoutProvider = modelName;
208
208
  if (displayModel?.reasoning) {
209
209
  const thinkingLevel = state.thinkingLevel || "off";
210
- rightSideWithoutProvider =
211
- thinkingLevel === "off" ? `${modelName} • thinking off` : `${modelName} • ${thinkingLevel}`;
210
+ if (thinkingLevel === "off") {
211
+ rightSideWithoutProvider = `${modelName} • thinking off`;
212
+ }
213
+ else if (thinkingLevel === "adaptive") {
214
+ const resolved = state.lastAdaptiveDecision?.level;
215
+ rightSideWithoutProvider = resolved
216
+ ? `${modelName} • adaptive→${resolved}`
217
+ : `${modelName} • adaptive`;
218
+ }
219
+ else {
220
+ rightSideWithoutProvider = `${modelName} • ${thinkingLevel}`;
221
+ }
212
222
  }
213
223
  // Prepend the provider in parentheses if there are multiple providers and there's enough room
214
224
  let rightSide = rightSideWithoutProvider;
@@ -1 +1 @@
1
- {"version":3,"file":"footer.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/footer.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Component, truncateToWidth, visibleWidth } from \"@gsd/pi-tui\";\nimport type { AgentSession } from \"../../../core/agent-session.js\";\nimport type { ReadonlyFooterDataProvider } from \"../../../core/footer-data-provider.js\";\nimport { getPermissionMode, type PermissionMode } from \"../../../core/tool-approval.js\";\nimport { theme } from \"../theme/theme.js\";\n\n/**\n * Sanitize text for display in a single-line status.\n * Removes newlines, tabs, carriage returns, and other control characters.\n */\nfunction sanitizeStatusText(text: string): string {\n\t// Replace newlines, tabs, carriage returns with space, then collapse multiple spaces\n\treturn text\n\t\t.replace(/[\\r\\n\\t]/g, \" \")\n\t\t.replace(/ +/g, \" \")\n\t\t.trim();\n}\n\n/**\n * Format token counts (similar to web-ui)\n */\nfunction formatTokens(count: number): string {\n\tif (count < 1000) return count.toString();\n\tif (count < 10000) return `${(count / 1000).toFixed(1)}k`;\n\tif (count < 1000000) return `${Math.round(count / 1000)}k`;\n\tif (count < 10000000) return `${(count / 1000000).toFixed(1)}M`;\n\treturn `${Math.round(count / 1000000)}M`;\n}\n\n/**\n * Format a cost value for compact display.\n * Uses fewer decimal places for larger amounts.\n * @internal Exported for testing only.\n */\nexport function formatPromptCost(cost: number): string {\n\tif (cost < 0.001) return `$${cost.toFixed(4)}`;\n\tif (cost < 0.01) return `$${cost.toFixed(3)}`;\n\tif (cost < 1) return `$${cost.toFixed(3)}`;\n\treturn `$${cost.toFixed(2)}`;\n}\n\n/**\n * Footer component that shows pwd, token stats, and context usage.\n * Computes token/context stats from session, gets git branch and extension statuses from provider.\n */\nexport class FooterComponent implements Component {\n\tprivate autoCompactEnabled = true;\n\tprivate permissionMode: PermissionMode = \"danger-full-access\";\n\n\tconstructor(\n\t\tprivate session: AgentSession,\n\t\tprivate footerData: ReadonlyFooterDataProvider,\n\t) {}\n\n\tsetAutoCompactEnabled(enabled: boolean): void {\n\t\tthis.autoCompactEnabled = enabled;\n\t}\n\n\tsetPermissionMode(mode: PermissionMode): void {\n\t\tthis.permissionMode = mode;\n\t}\n\n\t/**\n\t * No-op: git branch caching now handled by provider.\n\t * Kept for compatibility with existing call sites in interactive-mode.\n\t */\n\tinvalidate(): void {\n\t\t// No-op: git branch is cached/invalidated by provider\n\t}\n\n\t/**\n\t * Clean up resources.\n\t * Git watcher cleanup now handled by provider.\n\t */\n\tdispose(): void {\n\t\t// Git watcher cleanup handled by provider\n\t}\n\n\trender(width: number): string[] {\n\t\tconst state = this.session.state;\n\n\t\tconst usageTotals = this.session.sessionManager.getUsageTotals();\n\t\tconst totalInput = usageTotals.input;\n\t\tconst totalOutput = usageTotals.output;\n\t\tconst totalCacheRead = usageTotals.cacheRead;\n\t\tconst totalCacheWrite = usageTotals.cacheWrite;\n\t\tconst totalCost = usageTotals.cost;\n\n\t\t// Use activeInferenceModel during streaming to show the model actually\n\t\t// being used, not the configured model which may have been switched mid-turn.\n\t\tconst displayModel = state.activeInferenceModel ?? state.model;\n\n\t\t// Calculate context usage from session (handles compaction correctly).\n\t\t// After compaction, tokens are unknown until the next LLM response.\n\t\tconst contextUsage = this.session.getContextUsage();\n\t\tconst contextTokens = contextUsage?.tokens ?? null;\n\t\tconst contextWindow = contextUsage?.contextWindow ?? displayModel?.contextWindow ?? 0;\n\t\tconst contextPercentValue = contextUsage?.percent ?? 0;\n\t\tconst contextPercent = contextUsage?.percent !== null ? contextPercentValue.toFixed(1) : \"?\";\n\n\t\t// Replace home directory with ~\n\t\tlet pwd = process.cwd();\n\t\tconst home = process.env.HOME || process.env.USERPROFILE;\n\t\tif (home && pwd.startsWith(home)) {\n\t\t\tpwd = `~${pwd.slice(home.length)}`;\n\t\t}\n\n\t\t// Add git branch if available\n\t\tconst branch = this.footerData.getGitBranch();\n\t\tif (branch) {\n\t\t\tpwd = `${pwd} (${branch})`;\n\t\t}\n\n\t\t// Add session name if set\n\t\tconst sessionName = this.session.sessionManager.getSessionName();\n\t\tif (sessionName) {\n\t\t\tpwd = `${pwd} • ${sessionName}`;\n\t\t}\n\n\t\tconst extensionStatuses = this.footerData.getExtensionStatuses();\n\t\tconst cacheTimerStatusRaw = extensionStatuses.get(\"cache-timer\");\n\t\tconst cacheTimerStatus = cacheTimerStatusRaw ? sanitizeStatusText(cacheTimerStatusRaw) : \"\";\n\t\tconst hotkeysHints = [\"Ctrl+K • /hotkeys\", \"/hotkeys\", \"Ctrl+K\"];\n\t\tconst firstLineMinPadding = 2;\n\t\tconst firstLineRightParts = cacheTimerStatus ? [cacheTimerStatus] : [];\n\t\tconst firstLineRightBase = firstLineRightParts.join(\" \");\n\t\tconst hotkeysHint = hotkeysHints.find((hint) => {\n\t\t\tconst candidate = firstLineRightBase ? `${firstLineRightBase} ${hint}` : hint;\n\t\t\treturn visibleWidth(pwd) + firstLineMinPadding + visibleWidth(candidate) <= width;\n\t\t}) ?? \"\";\n\t\tif (hotkeysHint) {\n\t\t\tfirstLineRightParts.push(theme.fg(\"dim\", hotkeysHint));\n\t\t}\n\t\tconst firstLineRight = firstLineRightParts.join(\" \");\n\n\t\tlet pwdLine: string;\n\t\tif (firstLineRight) {\n\t\t\tconst rightWidth = visibleWidth(firstLineRight);\n\t\t\tconst availableForPwd = Math.max(0, width - rightWidth - firstLineMinPadding);\n\t\t\tconst truncatedPwd = truncateToWidth(theme.fg(\"dim\", pwd), availableForPwd, theme.fg(\"dim\", \"...\"));\n\t\t\tconst truncatedPwdWidth = visibleWidth(truncatedPwd);\n\t\t\tconst padding = \" \".repeat(Math.max(firstLineMinPadding, width - truncatedPwdWidth - rightWidth));\n\t\t\tpwdLine = truncatedPwd + padding + firstLineRight;\n\t\t} else {\n\t\t\tpwdLine = truncateToWidth(theme.fg(\"dim\", pwd), width, theme.fg(\"dim\", \"...\"));\n\t\t}\n\n\t\t// Build stats line\n\t\tconst statsParts = [];\n\t\tif (totalInput) statsParts.push(`↑${formatTokens(totalInput)}`);\n\t\tif (totalOutput) statsParts.push(`↓${formatTokens(totalOutput)}`);\n\t\tif (totalCacheRead) statsParts.push(`Cache ${formatTokens(totalCacheRead)}`);\n\t\tif (totalCacheWrite) statsParts.push(`W${formatTokens(totalCacheWrite)}`);\n\n\t\t// Show cost with \"(sub)\" indicator if using OAuth subscription\n\t\tconst usingSubscription = displayModel ? this.session.modelRegistry.isUsingOAuth(displayModel) : false;\n\t\tif (totalCost || usingSubscription) {\n\t\t\tconst costStr = `$${totalCost.toFixed(3)}${usingSubscription ? \" (sub)\" : \"\"}`;\n\t\t\tstatsParts.push(costStr);\n\t\t}\n\n\t\t// Per-prompt cost annotation (opt-in via show_token_cost preference, #1515)\n\t\tif (process.env.GSD_SHOW_TOKEN_COST === \"1\") {\n\t\t\tconst lastTurnCost = this.session.getLastTurnCost();\n\t\t\tif (lastTurnCost > 0) {\n\t\t\t\tstatsParts.push(`(last: ${formatPromptCost(lastTurnCost)})`);\n\t\t\t}\n\t\t}\n\n\t\t// Colorize context percentage based on usage\n\t\tlet contextPercentStr: string;\n\t\tconst contextPercentDisplay =\n\t\t\tcontextPercent === \"?\"\n\t\t\t\t? `?/${formatTokens(contextWindow)}`\n\t\t\t\t: `${contextPercent}%/${formatTokens(contextWindow)}`;\n\t\tif (contextPercentValue > 90) {\n\t\t\tcontextPercentStr = theme.fg(\"error\", contextPercentDisplay);\n\t\t} else if (contextPercentValue > 70) {\n\t\t\tcontextPercentStr = theme.fg(\"warning\", contextPercentDisplay);\n\t\t} else {\n\t\t\tcontextPercentStr = contextPercentDisplay;\n\t\t}\n\t\tstatsParts.push(contextPercentStr);\n\n\t\tconst currentPermissionMode = getPermissionMode();\n\t\tlet permissionModeLabel: string;\n\t\tif (currentPermissionMode === \"danger-full-access\") {\n\t\t\tpermissionModeLabel = theme.fg(\"error\", \"⚡ full-access\");\n\t\t} else if (currentPermissionMode === \"accept-on-edit\") {\n\t\t\tpermissionModeLabel = theme.fg(\"success\", \"✓ accept-edit\");\n\t\t} else if (currentPermissionMode === \"auto\") {\n\t\t\tpermissionModeLabel = theme.fg(\"warning\", \"🤖 auto\");\n\t\t} else {\n\t\t\tpermissionModeLabel = theme.fg(\"violet\", \"📝 plan\");\n\t\t}\n\t\tstatsParts.push(permissionModeLabel);\n\n\t\tconst sandboxStatus = this.footerData.getSandboxStatus();\n\t\tif (sandboxStatus === \"active\") {\n\t\t\tstatsParts.push(theme.fg(\"success\", \"🔒 sandboxed\"));\n\t\t} else if (sandboxStatus === \"unavailable\") {\n\t\t\tstatsParts.push(theme.fg(\"warning\", \"⚠ no sandbox\"));\n\t\t}\n\n\t\tlet statsLeft = statsParts.join(\" \");\n\n\t\t// Add model name on the right side, plus thinking level if model supports it\n\t\tconst modelName = displayModel?.id || \"no-model\";\n\n\t\tlet statsLeftWidth = visibleWidth(statsLeft);\n\n\t\t// If statsLeft is too wide, truncate it\n\t\tif (statsLeftWidth > width) {\n\t\t\tstatsLeft = truncateToWidth(statsLeft, width, \"...\");\n\t\t\tstatsLeftWidth = visibleWidth(statsLeft);\n\t\t}\n\n\t\t// Calculate available space for padding (minimum 2 spaces between stats and model)\n\t\tconst minPadding = 2;\n\n\t\t// Add thinking level indicator if model supports reasoning\n\t\tlet rightSideWithoutProvider = modelName;\n\t\tif (displayModel?.reasoning) {\n\t\t\tconst thinkingLevel = state.thinkingLevel || \"off\";\n\t\t\trightSideWithoutProvider =\n\t\t\t\tthinkingLevel === \"off\" ? `${modelName} • thinking off` : `${modelName} • ${thinkingLevel}`;\n\t\t}\n\n\t\t// Prepend the provider in parentheses if there are multiple providers and there's enough room\n\t\tlet rightSide = rightSideWithoutProvider;\n\t\tif (this.footerData.getAvailableProviderCount() > 1 && displayModel) {\n\t\t\trightSide = `(${displayModel.provider}) ${rightSideWithoutProvider}`;\n\t\t\tif (statsLeftWidth + minPadding + visibleWidth(rightSide) > width) {\n\t\t\t\t// Too wide, fall back\n\t\t\t\trightSide = rightSideWithoutProvider;\n\t\t\t}\n\t\t}\n\n\t\tconst rightSideWidth = visibleWidth(rightSide);\n\t\tconst totalNeeded = statsLeftWidth + minPadding + rightSideWidth;\n\n\t\tlet statsLine: string;\n\t\tif (totalNeeded <= width) {\n\t\t\t// Both fit - add padding to right-align model\n\t\t\tconst padding = \" \".repeat(width - statsLeftWidth - rightSideWidth);\n\t\t\tstatsLine = statsLeft + padding + rightSide;\n\t\t} else {\n\t\t\t// Need to truncate right side\n\t\t\tconst availableForRight = width - statsLeftWidth - minPadding;\n\t\t\tif (availableForRight > 0) {\n\t\t\t\tconst truncatedRight = truncateToWidth(rightSide, availableForRight, \"\");\n\t\t\t\tconst truncatedRightWidth = visibleWidth(truncatedRight);\n\t\t\t\tconst padding = \" \".repeat(Math.max(0, width - statsLeftWidth - truncatedRightWidth));\n\t\t\t\tstatsLine = statsLeft + padding + truncatedRight;\n\t\t\t} else {\n\t\t\t\t// Not enough space for right side at all\n\t\t\t\tstatsLine = statsLeft;\n\t\t\t}\n\t\t}\n\n\t\t// Apply dim to each part separately. statsLeft may contain color codes (for context %)\n\t\t// that end with a reset, which would clear an outer dim wrapper. So we dim the parts\n\t\t// before and after the colored section independently.\n\t\tconst dimStatsLeft = theme.fg(\"dim\", statsLeft);\n\t\tconst remainder = statsLine.slice(statsLeft.length); // padding + rightSide\n\t\tconst dimRemainder = theme.fg(\"dim\", remainder);\n\n\t\tconst lines = [pwdLine, dimStatsLeft + dimRemainder];\n\n\t\t// Add extension statuses on a single line, sorted by key alphabetically.\n\t\t// cache-timer is surfaced on the first line instead of this extension-status line.\n\t\tconst nonTimerStatuses = Array.from(extensionStatuses.entries()).filter(([key]) => key !== \"cache-timer\" && key !== \"usage-tips\");\n\t\tif (nonTimerStatuses.length > 0) {\n\t\t\tconst sortedStatuses = nonTimerStatuses\n\t\t\t\t.sort(([a], [b]) => a.localeCompare(b))\n\t\t\t\t.map(([, text]) => sanitizeStatusText(text));\n\t\t\tconst statusLine = sortedStatuses.join(\" \");\n\t\t\t// Match the rest of the footer styling: extension statuses should render\n\t\t\t// in the same dim color as pwd/stats, with a dim ellipsis on truncation.\n\t\t\tlines.push(truncateToWidth(theme.fg(\"dim\", statusLine), width, theme.fg(\"dim\", \"...\")));\n\t\t}\n\n\t\treturn lines;\n\t}\n}\n"]}
1
+ {"version":3,"file":"footer.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/footer.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Component, truncateToWidth, visibleWidth } from \"@gsd/pi-tui\";\nimport type { AgentSession } from \"../../../core/agent-session.js\";\nimport type { ReadonlyFooterDataProvider } from \"../../../core/footer-data-provider.js\";\nimport { getPermissionMode, type PermissionMode } from \"../../../core/tool-approval.js\";\nimport { theme } from \"../theme/theme.js\";\n\n/**\n * Sanitize text for display in a single-line status.\n * Removes newlines, tabs, carriage returns, and other control characters.\n */\nfunction sanitizeStatusText(text: string): string {\n\t// Replace newlines, tabs, carriage returns with space, then collapse multiple spaces\n\treturn text\n\t\t.replace(/[\\r\\n\\t]/g, \" \")\n\t\t.replace(/ +/g, \" \")\n\t\t.trim();\n}\n\n/**\n * Format token counts (similar to web-ui)\n */\nfunction formatTokens(count: number): string {\n\tif (count < 1000) return count.toString();\n\tif (count < 10000) return `${(count / 1000).toFixed(1)}k`;\n\tif (count < 1000000) return `${Math.round(count / 1000)}k`;\n\tif (count < 10000000) return `${(count / 1000000).toFixed(1)}M`;\n\treturn `${Math.round(count / 1000000)}M`;\n}\n\n/**\n * Format a cost value for compact display.\n * Uses fewer decimal places for larger amounts.\n * @internal Exported for testing only.\n */\nexport function formatPromptCost(cost: number): string {\n\tif (cost < 0.001) return `$${cost.toFixed(4)}`;\n\tif (cost < 0.01) return `$${cost.toFixed(3)}`;\n\tif (cost < 1) return `$${cost.toFixed(3)}`;\n\treturn `$${cost.toFixed(2)}`;\n}\n\n/**\n * Footer component that shows pwd, token stats, and context usage.\n * Computes token/context stats from session, gets git branch and extension statuses from provider.\n */\nexport class FooterComponent implements Component {\n\tprivate autoCompactEnabled = true;\n\tprivate permissionMode: PermissionMode = \"danger-full-access\";\n\n\tconstructor(\n\t\tprivate session: AgentSession,\n\t\tprivate footerData: ReadonlyFooterDataProvider,\n\t) {}\n\n\tsetAutoCompactEnabled(enabled: boolean): void {\n\t\tthis.autoCompactEnabled = enabled;\n\t}\n\n\tsetPermissionMode(mode: PermissionMode): void {\n\t\tthis.permissionMode = mode;\n\t}\n\n\t/**\n\t * No-op: git branch caching now handled by provider.\n\t * Kept for compatibility with existing call sites in interactive-mode.\n\t */\n\tinvalidate(): void {\n\t\t// No-op: git branch is cached/invalidated by provider\n\t}\n\n\t/**\n\t * Clean up resources.\n\t * Git watcher cleanup now handled by provider.\n\t */\n\tdispose(): void {\n\t\t// Git watcher cleanup handled by provider\n\t}\n\n\trender(width: number): string[] {\n\t\tconst state = this.session.state;\n\n\t\tconst usageTotals = this.session.sessionManager.getUsageTotals();\n\t\tconst totalInput = usageTotals.input;\n\t\tconst totalOutput = usageTotals.output;\n\t\tconst totalCacheRead = usageTotals.cacheRead;\n\t\tconst totalCacheWrite = usageTotals.cacheWrite;\n\t\tconst totalCost = usageTotals.cost;\n\n\t\t// Use activeInferenceModel during streaming to show the model actually\n\t\t// being used, not the configured model which may have been switched mid-turn.\n\t\tconst displayModel = state.activeInferenceModel ?? state.model;\n\n\t\t// Calculate context usage from session (handles compaction correctly).\n\t\t// After compaction, tokens are unknown until the next LLM response.\n\t\tconst contextUsage = this.session.getContextUsage();\n\t\tconst contextTokens = contextUsage?.tokens ?? null;\n\t\tconst contextWindow = contextUsage?.contextWindow ?? displayModel?.contextWindow ?? 0;\n\t\tconst contextPercentValue = contextUsage?.percent ?? 0;\n\t\tconst contextPercent = contextUsage?.percent !== null ? contextPercentValue.toFixed(1) : \"?\";\n\n\t\t// Replace home directory with ~\n\t\tlet pwd = process.cwd();\n\t\tconst home = process.env.HOME || process.env.USERPROFILE;\n\t\tif (home && pwd.startsWith(home)) {\n\t\t\tpwd = `~${pwd.slice(home.length)}`;\n\t\t}\n\n\t\t// Add git branch if available\n\t\tconst branch = this.footerData.getGitBranch();\n\t\tif (branch) {\n\t\t\tpwd = `${pwd} (${branch})`;\n\t\t}\n\n\t\t// Add session name if set\n\t\tconst sessionName = this.session.sessionManager.getSessionName();\n\t\tif (sessionName) {\n\t\t\tpwd = `${pwd} • ${sessionName}`;\n\t\t}\n\n\t\tconst extensionStatuses = this.footerData.getExtensionStatuses();\n\t\tconst cacheTimerStatusRaw = extensionStatuses.get(\"cache-timer\");\n\t\tconst cacheTimerStatus = cacheTimerStatusRaw ? sanitizeStatusText(cacheTimerStatusRaw) : \"\";\n\t\tconst hotkeysHints = [\"Ctrl+K • /hotkeys\", \"/hotkeys\", \"Ctrl+K\"];\n\t\tconst firstLineMinPadding = 2;\n\t\tconst firstLineRightParts = cacheTimerStatus ? [cacheTimerStatus] : [];\n\t\tconst firstLineRightBase = firstLineRightParts.join(\" \");\n\t\tconst hotkeysHint = hotkeysHints.find((hint) => {\n\t\t\tconst candidate = firstLineRightBase ? `${firstLineRightBase} ${hint}` : hint;\n\t\t\treturn visibleWidth(pwd) + firstLineMinPadding + visibleWidth(candidate) <= width;\n\t\t}) ?? \"\";\n\t\tif (hotkeysHint) {\n\t\t\tfirstLineRightParts.push(theme.fg(\"dim\", hotkeysHint));\n\t\t}\n\t\tconst firstLineRight = firstLineRightParts.join(\" \");\n\n\t\tlet pwdLine: string;\n\t\tif (firstLineRight) {\n\t\t\tconst rightWidth = visibleWidth(firstLineRight);\n\t\t\tconst availableForPwd = Math.max(0, width - rightWidth - firstLineMinPadding);\n\t\t\tconst truncatedPwd = truncateToWidth(theme.fg(\"dim\", pwd), availableForPwd, theme.fg(\"dim\", \"...\"));\n\t\t\tconst truncatedPwdWidth = visibleWidth(truncatedPwd);\n\t\t\tconst padding = \" \".repeat(Math.max(firstLineMinPadding, width - truncatedPwdWidth - rightWidth));\n\t\t\tpwdLine = truncatedPwd + padding + firstLineRight;\n\t\t} else {\n\t\t\tpwdLine = truncateToWidth(theme.fg(\"dim\", pwd), width, theme.fg(\"dim\", \"...\"));\n\t\t}\n\n\t\t// Build stats line\n\t\tconst statsParts = [];\n\t\tif (totalInput) statsParts.push(`↑${formatTokens(totalInput)}`);\n\t\tif (totalOutput) statsParts.push(`↓${formatTokens(totalOutput)}`);\n\t\tif (totalCacheRead) statsParts.push(`Cache ${formatTokens(totalCacheRead)}`);\n\t\tif (totalCacheWrite) statsParts.push(`W${formatTokens(totalCacheWrite)}`);\n\n\t\t// Show cost with \"(sub)\" indicator if using OAuth subscription\n\t\tconst usingSubscription = displayModel ? this.session.modelRegistry.isUsingOAuth(displayModel) : false;\n\t\tif (totalCost || usingSubscription) {\n\t\t\tconst costStr = `$${totalCost.toFixed(3)}${usingSubscription ? \" (sub)\" : \"\"}`;\n\t\t\tstatsParts.push(costStr);\n\t\t}\n\n\t\t// Per-prompt cost annotation (opt-in via show_token_cost preference, #1515)\n\t\tif (process.env.GSD_SHOW_TOKEN_COST === \"1\") {\n\t\t\tconst lastTurnCost = this.session.getLastTurnCost();\n\t\t\tif (lastTurnCost > 0) {\n\t\t\t\tstatsParts.push(`(last: ${formatPromptCost(lastTurnCost)})`);\n\t\t\t}\n\t\t}\n\n\t\t// Colorize context percentage based on usage\n\t\tlet contextPercentStr: string;\n\t\tconst contextPercentDisplay =\n\t\t\tcontextPercent === \"?\"\n\t\t\t\t? `?/${formatTokens(contextWindow)}`\n\t\t\t\t: `${contextPercent}%/${formatTokens(contextWindow)}`;\n\t\tif (contextPercentValue > 90) {\n\t\t\tcontextPercentStr = theme.fg(\"error\", contextPercentDisplay);\n\t\t} else if (contextPercentValue > 70) {\n\t\t\tcontextPercentStr = theme.fg(\"warning\", contextPercentDisplay);\n\t\t} else {\n\t\t\tcontextPercentStr = contextPercentDisplay;\n\t\t}\n\t\tstatsParts.push(contextPercentStr);\n\n\t\tconst currentPermissionMode = getPermissionMode();\n\t\tlet permissionModeLabel: string;\n\t\tif (currentPermissionMode === \"danger-full-access\") {\n\t\t\tpermissionModeLabel = theme.fg(\"error\", \"⚡ full-access\");\n\t\t} else if (currentPermissionMode === \"accept-on-edit\") {\n\t\t\tpermissionModeLabel = theme.fg(\"success\", \"✓ accept-edit\");\n\t\t} else if (currentPermissionMode === \"auto\") {\n\t\t\tpermissionModeLabel = theme.fg(\"warning\", \"🤖 auto\");\n\t\t} else {\n\t\t\tpermissionModeLabel = theme.fg(\"violet\", \"📝 plan\");\n\t\t}\n\t\tstatsParts.push(permissionModeLabel);\n\n\t\tconst sandboxStatus = this.footerData.getSandboxStatus();\n\t\tif (sandboxStatus === \"active\") {\n\t\t\tstatsParts.push(theme.fg(\"success\", \"🔒 sandboxed\"));\n\t\t} else if (sandboxStatus === \"unavailable\") {\n\t\t\tstatsParts.push(theme.fg(\"warning\", \"⚠ no sandbox\"));\n\t\t}\n\n\t\tlet statsLeft = statsParts.join(\" \");\n\n\t\t// Add model name on the right side, plus thinking level if model supports it\n\t\tconst modelName = displayModel?.id || \"no-model\";\n\n\t\tlet statsLeftWidth = visibleWidth(statsLeft);\n\n\t\t// If statsLeft is too wide, truncate it\n\t\tif (statsLeftWidth > width) {\n\t\t\tstatsLeft = truncateToWidth(statsLeft, width, \"...\");\n\t\t\tstatsLeftWidth = visibleWidth(statsLeft);\n\t\t}\n\n\t\t// Calculate available space for padding (minimum 2 spaces between stats and model)\n\t\tconst minPadding = 2;\n\n\t\t// Add thinking level indicator if model supports reasoning\n\t\tlet rightSideWithoutProvider = modelName;\n\t\tif (displayModel?.reasoning) {\n\t\t\tconst thinkingLevel = state.thinkingLevel || \"off\";\n\t\t\tif (thinkingLevel === \"off\") {\n\t\t\t\trightSideWithoutProvider = `${modelName} • thinking off`;\n\t\t\t} else if (thinkingLevel === \"adaptive\") {\n\t\t\t\tconst resolved = state.lastAdaptiveDecision?.level;\n\t\t\t\trightSideWithoutProvider = resolved\n\t\t\t\t\t? `${modelName} • adaptive→${resolved}`\n\t\t\t\t\t: `${modelName} • adaptive`;\n\t\t\t} else {\n\t\t\t\trightSideWithoutProvider = `${modelName} • ${thinkingLevel}`;\n\t\t\t}\n\t\t}\n\n\t\t// Prepend the provider in parentheses if there are multiple providers and there's enough room\n\t\tlet rightSide = rightSideWithoutProvider;\n\t\tif (this.footerData.getAvailableProviderCount() > 1 && displayModel) {\n\t\t\trightSide = `(${displayModel.provider}) ${rightSideWithoutProvider}`;\n\t\t\tif (statsLeftWidth + minPadding + visibleWidth(rightSide) > width) {\n\t\t\t\t// Too wide, fall back\n\t\t\t\trightSide = rightSideWithoutProvider;\n\t\t\t}\n\t\t}\n\n\t\tconst rightSideWidth = visibleWidth(rightSide);\n\t\tconst totalNeeded = statsLeftWidth + minPadding + rightSideWidth;\n\n\t\tlet statsLine: string;\n\t\tif (totalNeeded <= width) {\n\t\t\t// Both fit - add padding to right-align model\n\t\t\tconst padding = \" \".repeat(width - statsLeftWidth - rightSideWidth);\n\t\t\tstatsLine = statsLeft + padding + rightSide;\n\t\t} else {\n\t\t\t// Need to truncate right side\n\t\t\tconst availableForRight = width - statsLeftWidth - minPadding;\n\t\t\tif (availableForRight > 0) {\n\t\t\t\tconst truncatedRight = truncateToWidth(rightSide, availableForRight, \"\");\n\t\t\t\tconst truncatedRightWidth = visibleWidth(truncatedRight);\n\t\t\t\tconst padding = \" \".repeat(Math.max(0, width - statsLeftWidth - truncatedRightWidth));\n\t\t\t\tstatsLine = statsLeft + padding + truncatedRight;\n\t\t\t} else {\n\t\t\t\t// Not enough space for right side at all\n\t\t\t\tstatsLine = statsLeft;\n\t\t\t}\n\t\t}\n\n\t\t// Apply dim to each part separately. statsLeft may contain color codes (for context %)\n\t\t// that end with a reset, which would clear an outer dim wrapper. So we dim the parts\n\t\t// before and after the colored section independently.\n\t\tconst dimStatsLeft = theme.fg(\"dim\", statsLeft);\n\t\tconst remainder = statsLine.slice(statsLeft.length); // padding + rightSide\n\t\tconst dimRemainder = theme.fg(\"dim\", remainder);\n\n\t\tconst lines = [pwdLine, dimStatsLeft + dimRemainder];\n\n\t\t// Add extension statuses on a single line, sorted by key alphabetically.\n\t\t// cache-timer is surfaced on the first line instead of this extension-status line.\n\t\tconst nonTimerStatuses = Array.from(extensionStatuses.entries()).filter(([key]) => key !== \"cache-timer\" && key !== \"usage-tips\");\n\t\tif (nonTimerStatuses.length > 0) {\n\t\t\tconst sortedStatuses = nonTimerStatuses\n\t\t\t\t.sort(([a], [b]) => a.localeCompare(b))\n\t\t\t\t.map(([, text]) => sanitizeStatusText(text));\n\t\t\tconst statusLine = sortedStatuses.join(\" \");\n\t\t\t// Match the rest of the footer styling: extension statuses should render\n\t\t\t// in the same dim color as pwd/stats, with a dim ellipsis on truncation.\n\t\t\tlines.push(truncateToWidth(theme.fg(\"dim\", statusLine), width, theme.fg(\"dim\", \"...\")));\n\t\t}\n\n\t\treturn lines;\n\t}\n}\n"]}
@@ -7,6 +7,7 @@ export interface SettingsConfig {
7
7
  autoCompactThresholdPercent: number;
8
8
  defaultModel: string;
9
9
  classifierModel: string;
10
+ adaptiveClassifierModel: string;
10
11
  budgetSubagentModel: string;
11
12
  planModeReasoningModel: string;
12
13
  planModeReviewModel: string;
@@ -17,7 +18,7 @@ export interface SettingsConfig {
17
18
  autoResizeImages: boolean;
18
19
  blockImages: boolean;
19
20
  enableSkillCommands: boolean;
20
- toolProfile: "balanced" | "full";
21
+ toolProfile: "balanced" | "standard" | "full";
21
22
  codexRotate: boolean;
22
23
  cacheTimer: boolean;
23
24
  pinLastPrompt: boolean;
@@ -26,6 +27,7 @@ export interface SettingsConfig {
26
27
  transport: Transport;
27
28
  thinkingLevel: ThinkingLevel;
28
29
  anthropicAdaptiveByDefault: boolean;
30
+ clientAdaptiveByDefault: boolean;
29
31
  availableThinkingLevels: ThinkingLevel[];
30
32
  currentTheme: string;
31
33
  availableThemes: string[];
@@ -52,6 +54,7 @@ export interface SettingsConfig {
52
54
  sandboxNetworkMode?: "allow" | "ask" | "deny";
53
55
  defaultModelSubmenu?: (currentValue: string, done: (selectedValue?: string) => void) => Component;
54
56
  classifierModelSubmenu?: (currentValue: string, done: (selectedValue?: string) => void) => Component;
57
+ adaptiveClassifierModelSubmenu?: (currentValue: string, done: (selectedValue?: string) => void) => Component;
55
58
  budgetSubagentModelSubmenu?: (currentValue: string, done: (selectedValue?: string) => void) => Component;
56
59
  planModeReasoningModelSubmenu?: (currentValue: string, done: (selectedValue?: string) => void) => Component;
57
60
  planModeReviewModelSubmenu?: (currentValue: string, done: (selectedValue?: string) => void) => Component;
@@ -62,6 +65,7 @@ export interface SettingsCallbacks {
62
65
  onAutoCompactThresholdPercentChange: (percent: number) => void;
63
66
  onDefaultModelChange: (modelRef: string) => void;
64
67
  onClassifierModelChange: (modelRef: string) => void;
68
+ onAdaptiveClassifierModelChange: (modelRef: string) => void;
65
69
  onBudgetSubagentModelChange: (modelRef: string) => void;
66
70
  onPlanModeReasoningModelChange: (modelRef: string) => void;
67
71
  onPlanModeReviewModelChange: (modelRef: string) => void;
@@ -77,7 +81,7 @@ export interface SettingsCallbacks {
77
81
  onAutoResizeImagesChange: (enabled: boolean) => void;
78
82
  onBlockImagesChange: (blocked: boolean) => void;
79
83
  onEnableSkillCommandsChange: (enabled: boolean) => void;
80
- onToolProfileChange: (profile: "balanced" | "full") => void;
84
+ onToolProfileChange: (profile: "balanced" | "standard" | "full") => void;
81
85
  onCodexRotateChange: (enabled: boolean) => void;
82
86
  onCacheTimerChange: (enabled: boolean) => void;
83
87
  onPinLastPromptChange: (enabled: boolean) => void;
@@ -86,6 +90,7 @@ export interface SettingsCallbacks {
86
90
  onTransportChange: (transport: Transport) => void;
87
91
  onThinkingLevelChange: (level: ThinkingLevel) => void;
88
92
  onAnthropicAdaptiveByDefaultChange: (enabled: boolean) => void;
93
+ onClientAdaptiveByDefaultChange: (enabled: boolean) => void;
89
94
  onThemeChange: (theme: string) => void;
90
95
  onThemePreview?: (theme: string) => void;
91
96
  onThemeAccentChange: (accent: string) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"settings-selector.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/settings-selector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EACN,KAAK,SAAS,EACd,SAAS,EAET,KAAK,UAAU,EAGf,YAAY,EAGZ,MAAM,aAAa,CAAC;AAIrB,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAQ/D,CAAC;AAEF,MAAM,WAAW,cAAc;IAC9B,WAAW,EAAE,OAAO,CAAC;IACrB,2BAA2B,EAAE,MAAM,CAAC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,OAAO,CAAC;IACrB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,WAAW,EAAE,UAAU,GAAG,MAAM,CAAC;IACjC,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,KAAK,GAAG,eAAe,CAAC;IACtC,YAAY,EAAE,KAAK,GAAG,eAAe,CAAC;IACtC,SAAS,EAAE,SAAS,CAAC;IACrB,aAAa,EAAE,aAAa,CAAC;IAC7B,0BAA0B,EAAE,OAAO,CAAC;IACpC,uBAAuB,EAAE,aAAa,EAAE,CAAC;IACzC,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,kBAAkB,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAC7C,cAAc,EAAE,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,cAAc,GAAG,KAAK,CAAC;IAC9E,kBAAkB,EAAE,OAAO,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,wBAAwB,EAAE,OAAO,CAAC;IAClC,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,eAAe,GAAG,cAAc,CAAC;IAClD,cAAc,EAAE,SAAS,GAAG,QAAQ,CAAC;IACrC,GAAG,EAAE,OAAO,CAAC;IACb,YAAY,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,KAAK,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,CAAC;IACtF,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,4BAA4B,EAAE,OAAO,CAAC;IACtC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,kBAAkB,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;IAC9C,mBAAmB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,MAAM,KAAK,IAAI,KAAK,SAAS,CAAC;IAClG,sBAAsB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,MAAM,KAAK,IAAI,KAAK,SAAS,CAAC;IACrG,0BAA0B,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,MAAM,KAAK,IAAI,KAAK,SAAS,CAAC;IACzG,6BAA6B,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,MAAM,KAAK,IAAI,KAAK,SAAS,CAAC;IAC5G,0BAA0B,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,MAAM,KAAK,IAAI,KAAK,SAAS,CAAC;IACzG,0BAA0B,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,MAAM,KAAK,IAAI,KAAK,SAAS,CAAC;CACzG;AAED,MAAM,WAAW,iBAAiB;IACjC,mBAAmB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAChD,mCAAmC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/D,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,uBAAuB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,2BAA2B,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,8BAA8B,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3D,2BAA2B,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,2BAA2B,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,2BAA2B,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACxD,2BAA2B,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACxD,iBAAiB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C,kBAAkB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C,oCAAoC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACjE,sBAAsB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACpD,0BAA0B,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,KAAK,GAAG,MAAM,KAAK,IAAI,CAAC;IACtE,kBAAkB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C,wBAAwB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACrD,mBAAmB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAChD,2BAA2B,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACxD,mBAAmB,EAAE,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,KAAK,IAAI,CAAC;IAC5D,mBAAmB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAChD,kBAAkB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C,qBAAqB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD,oBAAoB,EAAE,CAAC,IAAI,EAAE,KAAK,GAAG,eAAe,KAAK,IAAI,CAAC;IAC9D,oBAAoB,EAAE,CAAC,IAAI,EAAE,KAAK,GAAG,eAAe,KAAK,IAAI,CAAC;IAC9D,iBAAiB,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,CAAC;IAClD,qBAAqB,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACtD,kCAAkC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/D,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,mBAAmB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,yBAAyB,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACrD,yBAAyB,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IACxD,0BAA0B,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;IACvE,sBAAsB,EAAE,CAAC,IAAI,EAAE,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,cAAc,GAAG,KAAK,KAAK,IAAI,CAAC;IACtG,0BAA0B,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACvD,sBAAsB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,8BAA8B,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7D,gCAAgC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7D,oBAAoB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACjD,qBAAqB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD,uBAAuB,EAAE,CAAC,MAAM,EAAE,eAAe,GAAG,cAAc,KAAK,IAAI,CAAC;IAC5E,sBAAsB,EAAE,CAAC,IAAI,EAAE,SAAS,GAAG,QAAQ,KAAK,IAAI,CAAC;IAC7D,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC,oBAAoB,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,KAAK,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,KAAK,IAAI,CAAC;IAChH,QAAQ,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,SAAS;IAC3C,OAAO,CAAC,UAAU,CAAa;gBAG9B,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,UAAU,EAAE,EACrB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EACjC,QAAQ,EAAE,MAAM,IAAI,EACpB,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;IA4C5C,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;CAG/B;AAED;;GAEG;AACH,qBAAa,yBAA0B,SAAQ,SAAS;IACvD,OAAO,CAAC,YAAY,CAAe;gBAEvB,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,iBAAiB;IA8jBhE,eAAe,IAAI,YAAY;CAG/B"}
1
+ {"version":3,"file":"settings-selector.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/settings-selector.ts"],"names":[],"mappings":"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"}
@@ -3,8 +3,7 @@ import { getSelectListTheme, getSettingsListTheme, getThemeAccentInfo, getThemeA
3
3
  import { DynamicBorder } from "./dynamic-border.js";
4
4
  export const THINKING_DESCRIPTIONS = {
5
5
  off: "No reasoning",
6
- adaptive: "Claude decides when and how much to think (Claude 4.6+ only)",
7
- minimal: "Very brief reasoning (~1k tokens)",
6
+ adaptive: "Automatically adapt per turn (client or provider resolved)",
8
7
  low: "Light reasoning (~2k tokens)",
9
8
  medium: "Moderate reasoning (~8k tokens)",
10
9
  high: "Deep reasoning (~16k tokens)",
@@ -86,6 +85,13 @@ export class SettingsSelectorComponent extends Container {
86
85
  currentValue: config.classifierModel,
87
86
  submenu: config.classifierModelSubmenu,
88
87
  },
88
+ {
89
+ id: "adaptive-classifier-model",
90
+ label: "Adaptive classifier model",
91
+ description: "LLM used to pick reasoning level when adaptive mode is on (required for non-Anthropic models)",
92
+ currentValue: config.adaptiveClassifierModel,
93
+ submenu: config.adaptiveClassifierModelSubmenu,
94
+ },
89
95
  {
90
96
  id: "budget-subagent-model",
91
97
  label: "Budget subagent model",
@@ -226,6 +232,13 @@ export class SettingsSelectorComponent extends Container {
226
232
  currentValue: config.anthropicAdaptiveByDefault ? "true" : "false",
227
233
  values: ["true", "false"],
228
234
  },
235
+ {
236
+ id: "client-adaptive-default",
237
+ label: "Adaptive by default",
238
+ description: "Default to adaptive thinking for all reasoning-capable models",
239
+ currentValue: config.clientAdaptiveByDefault ? "true" : "false",
240
+ values: ["true", "false"],
241
+ },
229
242
  {
230
243
  id: "theme",
231
244
  label: "Theme",
@@ -303,9 +316,9 @@ export class SettingsSelectorComponent extends Container {
303
316
  items.splice(skillCommandsIndex + 1, 0, {
304
317
  id: "tool-profile",
305
318
  label: "Tool profile",
306
- description: "Choose the default active tool set: balanced for day-to-day coding, full to enable all available tools",
319
+ description: "Choose the default active tool set: balanced for day-to-day coding, standard for broader coverage, full to enable all available tools",
307
320
  currentValue: config.toolProfile,
308
- values: ["balanced", "full"],
321
+ values: ["balanced", "standard", "full"],
309
322
  });
310
323
  // Codex rotate toggle (insert after tool-profile)
311
324
  const toolProfileIndex = items.findIndex((item) => item.id === "tool-profile");
@@ -449,6 +462,9 @@ export class SettingsSelectorComponent extends Container {
449
462
  case "classifier-model":
450
463
  callbacks.onClassifierModelChange(newValue);
451
464
  break;
465
+ case "adaptive-classifier-model":
466
+ callbacks.onAdaptiveClassifierModelChange(newValue);
467
+ break;
452
468
  case "budget-subagent-model":
453
469
  callbacks.onBudgetSubagentModelChange(newValue);
454
470
  break;
@@ -515,6 +531,9 @@ export class SettingsSelectorComponent extends Container {
515
531
  case "anthropic-adaptive-default":
516
532
  callbacks.onAnthropicAdaptiveByDefaultChange(newValue === "true");
517
533
  break;
534
+ case "client-adaptive-default":
535
+ callbacks.onClientAdaptiveByDefaultChange(newValue === "true");
536
+ break;
518
537
  case "hide-thinking":
519
538
  callbacks.onHideThinkingBlockChange(newValue === "true");
520
539
  break;