@code-yeongyu/senpi 2026.8.26-2 → 2026.8.27

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 (204) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +3 -3
  3. package/dist/cli/args.d.ts +3 -1
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +14 -1
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/core/bash-executor.d.ts.map +1 -1
  8. package/dist/core/bash-executor.js +67 -29
  9. package/dist/core/bash-executor.js.map +1 -1
  10. package/dist/core/credential-pool/classify.d.ts +42 -0
  11. package/dist/core/credential-pool/classify.d.ts.map +1 -0
  12. package/dist/core/credential-pool/classify.js +75 -0
  13. package/dist/core/credential-pool/classify.js.map +1 -0
  14. package/dist/core/credential-pool/env-slots.d.ts +22 -0
  15. package/dist/core/credential-pool/env-slots.d.ts.map +1 -0
  16. package/dist/core/credential-pool/env-slots.js +37 -0
  17. package/dist/core/credential-pool/env-slots.js.map +1 -0
  18. package/dist/core/credential-pool/failover.d.ts +54 -0
  19. package/dist/core/credential-pool/failover.d.ts.map +1 -0
  20. package/dist/core/credential-pool/failover.js +106 -0
  21. package/dist/core/credential-pool/failover.js.map +1 -0
  22. package/dist/core/credential-pool/rotation-stream.d.ts +43 -0
  23. package/dist/core/credential-pool/rotation-stream.d.ts.map +1 -0
  24. package/dist/core/credential-pool/rotation-stream.js +96 -0
  25. package/dist/core/credential-pool/rotation-stream.js.map +1 -0
  26. package/dist/core/credential-pool/state-store.d.ts +89 -0
  27. package/dist/core/credential-pool/state-store.d.ts.map +1 -0
  28. package/dist/core/credential-pool/state-store.js +166 -0
  29. package/dist/core/credential-pool/state-store.js.map +1 -0
  30. package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts +1 -0
  31. package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts.map +1 -1
  32. package/dist/core/extensions/builtin/goal/continuation-recovery.js +2 -0
  33. package/dist/core/extensions/builtin/goal/continuation-recovery.js.map +1 -1
  34. package/dist/core/extensions/builtin/goal/continuation.d.ts +8 -1
  35. package/dist/core/extensions/builtin/goal/continuation.d.ts.map +1 -1
  36. package/dist/core/extensions/builtin/goal/continuation.js +15 -0
  37. package/dist/core/extensions/builtin/goal/continuation.js.map +1 -1
  38. package/dist/core/extensions/builtin/goal/direct-input-lifecycle.js +2 -2
  39. package/dist/core/extensions/builtin/goal/direct-input-lifecycle.js.map +1 -1
  40. package/dist/core/extensions/builtin/goal/format.d.ts +6 -1
  41. package/dist/core/extensions/builtin/goal/format.d.ts.map +1 -1
  42. package/dist/core/extensions/builtin/goal/format.js +6 -0
  43. package/dist/core/extensions/builtin/goal/format.js.map +1 -1
  44. package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts.map +1 -1
  45. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +5 -2
  46. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js.map +1 -1
  47. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
  48. package/dist/core/extensions/builtin/goal/monitor-continuation.js +2 -1
  49. package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
  50. package/dist/core/extensions/builtin/goal/persistence.js +2 -0
  51. package/dist/core/extensions/builtin/goal/persistence.js.map +1 -1
  52. package/dist/core/extensions/builtin/goal/renderers.d.ts +14 -0
  53. package/dist/core/extensions/builtin/goal/renderers.d.ts.map +1 -0
  54. package/dist/core/extensions/builtin/goal/renderers.js +153 -0
  55. package/dist/core/extensions/builtin/goal/renderers.js.map +1 -0
  56. package/dist/core/extensions/builtin/goal/store.d.ts +6 -2
  57. package/dist/core/extensions/builtin/goal/store.d.ts.map +1 -1
  58. package/dist/core/extensions/builtin/goal/store.js +8 -2
  59. package/dist/core/extensions/builtin/goal/store.js.map +1 -1
  60. package/dist/core/extensions/builtin/goal/tool-registration.d.ts.map +1 -1
  61. package/dist/core/extensions/builtin/goal/tool-registration.js +16 -6
  62. package/dist/core/extensions/builtin/goal/tool-registration.js.map +1 -1
  63. package/dist/core/extensions/builtin/goal/types.d.ts +1 -0
  64. package/dist/core/extensions/builtin/goal/types.d.ts.map +1 -1
  65. package/dist/core/extensions/builtin/goal/types.js.map +1 -1
  66. package/dist/core/extensions/builtin/todotools/index.js +1 -1
  67. package/dist/core/extensions/builtin/todotools/index.js.map +1 -1
  68. package/dist/core/extensions/builtin/todotools/native-todo-mirror.d.ts +1 -1
  69. package/dist/core/extensions/builtin/todotools/native-todo-mirror.d.ts.map +1 -1
  70. package/dist/core/extensions/builtin/todotools/native-todo-mirror.js +1 -1
  71. package/dist/core/extensions/builtin/todotools/native-todo-mirror.js.map +1 -1
  72. package/dist/core/model-config-schema.d.ts +85 -12
  73. package/dist/core/model-config-schema.d.ts.map +1 -1
  74. package/dist/core/model-config-schema.js +25 -0
  75. package/dist/core/model-config-schema.js.map +1 -1
  76. package/dist/core/model-runtime.d.ts +34 -1
  77. package/dist/core/model-runtime.d.ts.map +1 -1
  78. package/dist/core/model-runtime.js +98 -5
  79. package/dist/core/model-runtime.js.map +1 -1
  80. package/dist/core/tools/output-accumulator.d.ts +2 -0
  81. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  82. package/dist/core/tools/output-accumulator.js +32 -7
  83. package/dist/core/tools/output-accumulator.js.map +1 -1
  84. package/dist/index.d.ts +1 -1
  85. package/dist/index.d.ts.map +1 -1
  86. package/dist/index.js +1 -1
  87. package/dist/index.js.map +1 -1
  88. package/dist/main.d.ts.map +1 -1
  89. package/dist/main.js +26 -2
  90. package/dist/main.js.map +1 -1
  91. package/dist/modes/index.d.ts +1 -0
  92. package/dist/modes/index.d.ts.map +1 -1
  93. package/dist/modes/index.js +1 -0
  94. package/dist/modes/index.js.map +1 -1
  95. package/dist/modes/interactive/components/tool-execution-fallback.d.ts.map +1 -1
  96. package/dist/modes/interactive/components/tool-execution-fallback.js +82 -1
  97. package/dist/modes/interactive/components/tool-execution-fallback.js.map +1 -1
  98. package/dist/modes/interactive/interactive-host-runtime.d.ts +29 -0
  99. package/dist/modes/interactive/interactive-host-runtime.d.ts.map +1 -0
  100. package/dist/modes/interactive/interactive-host-runtime.js +244 -0
  101. package/dist/modes/interactive/interactive-host-runtime.js.map +1 -0
  102. package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
  103. package/dist/modes/rpc/connection-handler.js +7 -1
  104. package/dist/modes/rpc/connection-handler.js.map +1 -1
  105. package/dist/modes/rpc/host-ensure.d.ts +41 -0
  106. package/dist/modes/rpc/host-ensure.d.ts.map +1 -0
  107. package/dist/modes/rpc/host-ensure.js +245 -0
  108. package/dist/modes/rpc/host-ensure.js.map +1 -0
  109. package/dist/modes/rpc/host-lifecycle.d.ts +57 -0
  110. package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -0
  111. package/dist/modes/rpc/host-lifecycle.js +491 -0
  112. package/dist/modes/rpc/host-lifecycle.js.map +1 -0
  113. package/dist/modes/rpc/host-watchdog.d.ts +33 -0
  114. package/dist/modes/rpc/host-watchdog.d.ts.map +1 -0
  115. package/dist/modes/rpc/host-watchdog.js +142 -0
  116. package/dist/modes/rpc/host-watchdog.js.map +1 -0
  117. package/dist/modes/rpc/multi-session-host.d.ts +7 -1
  118. package/dist/modes/rpc/multi-session-host.d.ts.map +1 -1
  119. package/dist/modes/rpc/multi-session-host.js +206 -32
  120. package/dist/modes/rpc/multi-session-host.js.map +1 -1
  121. package/dist/modes/rpc/rpc-client.d.ts +25 -0
  122. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  123. package/dist/modes/rpc/rpc-client.js +83 -10
  124. package/dist/modes/rpc/rpc-client.js.map +1 -1
  125. package/dist/modes/rpc/rpc-mode.d.ts +1 -1
  126. package/dist/modes/rpc/rpc-mode.js +1 -1
  127. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  128. package/dist/modes/rpc/rpc-types.d.ts +2 -1
  129. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  130. package/dist/modes/rpc/rpc-types.js.map +1 -1
  131. package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
  132. package/dist/modes/rpc/session-command-router.js +12 -2
  133. package/dist/modes/rpc/session-command-router.js.map +1 -1
  134. package/dist/modes/rpc/session-event-writer.d.ts +13 -2
  135. package/dist/modes/rpc/session-event-writer.d.ts.map +1 -1
  136. package/dist/modes/rpc/session-event-writer.js +65 -25
  137. package/dist/modes/rpc/session-event-writer.js.map +1 -1
  138. package/docs/rpc.md +53 -1
  139. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +18 -0
  140. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  141. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-indirect-eval.js +711 -1
  142. package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +10 -10
  143. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-eval-result.ts +9 -3
  144. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +6 -1
  145. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  146. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-pairs.d.ts +1 -1
  147. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-pairs.d.ts.map +1 -1
  148. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-pairs.js +46 -14
  149. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-pairs.js.map +1 -1
  150. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts +11 -0
  151. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts.map +1 -1
  152. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js +30 -16
  153. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js.map +1 -1
  154. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/classify.d.ts +16 -0
  155. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/classify.d.ts.map +1 -0
  156. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/classify.js +75 -0
  157. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/classify.js.map +1 -0
  158. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.d.ts +45 -0
  159. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.d.ts.map +1 -0
  160. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.js +81 -0
  161. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.js.map +1 -0
  162. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/select.d.ts +31 -0
  163. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/select.d.ts.map +1 -0
  164. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/select.js +65 -0
  165. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/select.js.map +1 -0
  166. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.d.ts +12 -0
  167. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.d.ts.map +1 -1
  168. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.js +37 -0
  169. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.js.map +1 -1
  170. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.d.ts +6 -0
  171. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.d.ts.map +1 -1
  172. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js +32 -6
  173. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js.map +1 -1
  174. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.d.ts +6 -0
  175. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.d.ts.map +1 -1
  176. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js +6 -1
  177. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js.map +1 -1
  178. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts +45 -0
  179. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  180. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +45 -0
  181. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
  182. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  183. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  184. package/node_modules/@earendil-works/pi-ai/dist/providers/data/baseten.json +1 -1
  185. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  186. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-workers-ai.json +1 -1
  187. package/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.json +1 -1
  188. package/node_modules/@earendil-works/pi-ai/dist/providers/data/minimax-cn.json +1 -1
  189. package/node_modules/@earendil-works/pi-ai/dist/providers/data/minimax.json +1 -1
  190. package/node_modules/@earendil-works/pi-ai/dist/providers/data/mistral.json +1 -1
  191. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
  192. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  193. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opengateway.json +1 -1
  194. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  195. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  196. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai-coding-cn.json +1 -1
  197. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai.json +1 -1
  198. package/node_modules/@earendil-works/pi-ai/package.json +5 -5
  199. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  200. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  201. package/node_modules/@earendil-works/pi-tui/dist/tui.js +1 -1
  202. package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
  203. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  204. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/modes/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAA+B,MAAM,mCAAmC,CAAC;AAEjG,OAAO,EAAyB,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAEN,SAAS,GAIT,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC","sourcesContent":["/**\n * Run modes for the coding agent.\n */\n\nexport { InteractiveMode, type InteractiveModeOptions } from \"./interactive/interactive-mode.ts\";\nexport type { JsonAgentSessionEvent } from \"./json-event.ts\";\nexport { type PrintModeOptions, runPrintMode } from \"./print-mode.ts\";\nexport {\n\ttype ModelInfo,\n\tRpcClient,\n\ttype RpcClientEvent,\n\ttype RpcClientOptions,\n\ttype RpcEventListener,\n} from \"./rpc/rpc-client.ts\";\nexport { runRpcMode } from \"./rpc/rpc-mode.ts\";\nexport type {\n\tRpcCommand,\n\tRpcExtensionEvent,\n\tRpcExtensionUIRequest,\n\tRpcExtensionUIResponse,\n\tRpcResponse,\n\tRpcSessionState,\n} from \"./rpc/rpc-types.ts\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/modes/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAA+B,MAAM,mCAAmC,CAAC;AAEjG,OAAO,EAAyB,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EACN,qBAAqB,EAGrB,UAAU,EAEV,+BAA+B,GAC/B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEN,SAAS,GAIT,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC","sourcesContent":["/**\n * Run modes for the coding agent.\n */\n\nexport { InteractiveMode, type InteractiveModeOptions } from \"./interactive/interactive-mode.ts\";\nexport type { JsonAgentSessionEvent } from \"./json-event.ts\";\nexport { type PrintModeOptions, runPrintMode } from \"./print-mode.ts\";\nexport {\n\tcreateHostDaemonPaths,\n\ttype EnsuredHost,\n\ttype EnsureHostOptions,\n\tensureHost,\n\ttype HostDaemonPaths,\n\tPINNED_HOST_CLIENT_CAPABILITIES,\n} from \"./rpc/host-ensure.ts\";\nexport {\n\ttype ModelInfo,\n\tRpcClient,\n\ttype RpcClientEvent,\n\ttype RpcClientOptions,\n\ttype RpcEventListener,\n} from \"./rpc/rpc-client.ts\";\nexport { runRpcMode } from \"./rpc/rpc-mode.ts\";\nexport type {\n\tRpcCommand,\n\tRpcExtensionEvent,\n\tRpcExtensionUIRequest,\n\tRpcExtensionUIResponse,\n\tRpcResponse,\n\tRpcSessionState,\n} from \"./rpc/rpc-types.ts\";\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"tool-execution-fallback.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-execution-fallback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAQ,MAAM,wBAAwB,CAAC;AAI9D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAoBrE,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAElE;AAED,wBAAgB,wBAAwB,CACvC,MAAM,EAAE,mBAAmB,GAAG,SAAS,EACvC,UAAU,EAAE,OAAO,GACjB,SAAS,GAAG,SAAS,CAGvB;AAED,wBAAgB,2BAA2B,CAC1C,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,mBAAmB,GAAG,SAAS,EACvC,UAAU,EAAE,OAAO,GACjB,MAAM,CAaR"}
1
+ {"version":3,"file":"tool-execution-fallback.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-execution-fallback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAQ,MAAM,wBAAwB,CAAC;AAI9D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAoGrE,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAElE;AAED,wBAAgB,wBAAwB,CACvC,MAAM,EAAE,mBAAmB,GAAG,SAAS,EACvC,UAAU,EAAE,OAAO,GACjB,SAAS,GAAG,SAAS,CAMvB;AAED,wBAAgB,2BAA2B,CAC1C,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,mBAAmB,GAAG,SAAS,EACvC,UAAU,EAAE,OAAO,GACjB,MAAM,CAaR"}
@@ -4,6 +4,9 @@ import { stripAnsi } from "../../../utils/ansi.js";
4
4
  import { theme } from "../theme/theme.js";
5
5
  const FALLBACK_STRING_MAX_LENGTH = 160;
6
6
  const FALLBACK_JSON_MAX_LENGTH = 2000;
7
+ const JSON_VIEW_MAX_DEPTH = 3;
8
+ const JSON_VIEW_MAX_ROWS = 24;
9
+ const JSON_VIEW_MAX_VALUE_LENGTH = 100;
7
10
  function sanitizeFallbackString(value, maxLength = FALLBACK_STRING_MAX_LENGTH) {
8
11
  const sanitized = stripAnsi(value)
9
12
  .replace(/[\u0000-\u001f\u007f-\u009f]+/g, " ")
@@ -17,12 +20,90 @@ function sanitizeFallbackString(value, maxLength = FALLBACK_STRING_MAX_LENGTH) {
17
20
  function sanitizeFallbackJsonValue(_key, value) {
18
21
  return typeof value === "string" ? sanitizeFallbackString(value) : value;
19
22
  }
23
+ function parseRenderableJson(text) {
24
+ const trimmed = text.trim();
25
+ if (!trimmed.startsWith("{") && !trimmed.startsWith("["))
26
+ return undefined;
27
+ try {
28
+ const parsed = JSON.parse(trimmed);
29
+ if (typeof parsed !== "object" || parsed === null)
30
+ return undefined;
31
+ return parsed;
32
+ }
33
+ catch {
34
+ return undefined;
35
+ }
36
+ }
37
+ function truncateJsonViewValue(value) {
38
+ return value.length > JSON_VIEW_MAX_VALUE_LENGTH ? `${value.slice(0, JSON_VIEW_MAX_VALUE_LENGTH)}\u2026` : value;
39
+ }
40
+ function styleJsonPrimitive(value) {
41
+ if (typeof value === "string")
42
+ return theme.fg("toolOutput", truncateJsonViewValue(value));
43
+ if (typeof value === "number" || typeof value === "boolean")
44
+ return theme.fg("accent", String(value));
45
+ if (value === null)
46
+ return theme.fg("dim", "null");
47
+ return theme.fg("toolOutput", truncateJsonViewValue(String(value)));
48
+ }
49
+ function styleJsonCompact(value) {
50
+ return theme.fg("toolOutput", truncateJsonViewValue(JSON.stringify(value) ?? String(value)));
51
+ }
52
+ function isJsonContainer(value) {
53
+ return typeof value === "object" && value !== null;
54
+ }
55
+ /**
56
+ * Flattens a parsed JSON value into bounded `key: value` rows. Returns the rendered rows plus the
57
+ * number of entries that were dropped so the caller can append a single truncation line.
58
+ */
59
+ function collectJsonViewRows(value) {
60
+ const rows = [];
61
+ let omitted = 0;
62
+ const walk = (node, depth) => {
63
+ const entries = Array.isArray(node)
64
+ ? node.map((item, index) => [String(index), item])
65
+ : Object.entries(node);
66
+ const indent = " ".repeat(depth);
67
+ for (const [key, entryValue] of entries) {
68
+ if (rows.length >= JSON_VIEW_MAX_ROWS) {
69
+ omitted += 1;
70
+ continue;
71
+ }
72
+ const label = `${indent}${theme.fg("muted", `${key}:`)}`;
73
+ if (isJsonContainer(entryValue)) {
74
+ if (depth + 1 >= JSON_VIEW_MAX_DEPTH) {
75
+ rows.push(`${label} ${styleJsonCompact(entryValue)}`);
76
+ continue;
77
+ }
78
+ rows.push(label);
79
+ walk(entryValue, depth + 1);
80
+ continue;
81
+ }
82
+ rows.push(`${label} ${styleJsonPrimitive(entryValue)}`);
83
+ }
84
+ };
85
+ walk(value, 0);
86
+ return { rows, omitted };
87
+ }
88
+ function renderJsonView(value) {
89
+ const { rows, omitted } = collectJsonViewRows(value);
90
+ if (rows.length === 0)
91
+ return theme.fg("dim", "(empty)");
92
+ if (omitted > 0)
93
+ rows.push(theme.fg("dim", `\u2026 ${omitted} more`));
94
+ return rows.join("\n");
95
+ }
20
96
  export function createToolCallFallback(toolName) {
21
97
  return new Text(theme.fg("toolTitle", theme.bold(toolName)), 0, 0);
22
98
  }
23
99
  export function createToolResultFallback(result, showImages) {
24
100
  const output = getRenderedTextOutput(result, showImages);
25
- return output ? new Text(theme.fg("toolOutput", output), 0, 0) : undefined;
101
+ if (!output)
102
+ return undefined;
103
+ const parsed = parseRenderableJson(output);
104
+ if (parsed)
105
+ return new Text(renderJsonView(parsed), 0, 0);
106
+ return new Text(theme.fg("toolOutput", output), 0, 0);
26
107
  }
27
108
  export function formatToolExecutionFallback(toolName, args, result, showImages) {
28
109
  let text = theme.fg("toolTitle", theme.bold(sanitizeFallbackString(toolName)));
@@ -1 +1 @@
1
- {"version":3,"file":"tool-execution-fallback.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-execution-fallback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,aAAa,IAAI,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAC7F,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAG1C,MAAM,0BAA0B,GAAG,GAAG,CAAC;AACvC,MAAM,wBAAwB,GAAG,IAAI,CAAC;AAEtC,SAAS,sBAAsB,CAAC,KAAa,EAAE,SAAS,GAAG,0BAA0B;IACpF,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC;SAChC,OAAO,CAAC,gCAAgC,EAAE,GAAG,CAAC;SAC9C,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;IACT,IAAI,SAAS,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC;QACnC,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;AAC/D,CAAC;AAED,SAAS,yBAAyB,CAAC,IAAY,EAAE,KAAc;IAC9D,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,QAAgB;IACtD,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,wBAAwB,CACvC,MAAuC,EACvC,UAAmB;IAEnB,MAAM,MAAM,GAAG,qBAAqB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACzD,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,2BAA2B,CAC1C,QAAgB,EAChB,IAAa,EACb,MAAuC,EACvC,UAAmB;IAEnB,IAAI,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC/E,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,yBAAyB,EAAE,CAAC,CAAC,CAAC;IACnE,IAAI,OAAO,EAAE,CAAC;QACb,MAAM,cAAc,GACnB,OAAO,CAAC,MAAM,GAAG,wBAAwB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC;QAC9G,IAAI,IAAI,OAAO,cAAc,EAAE,CAAC;IACjC,CAAC;IACD,MAAM,MAAM,GAAG,qBAAqB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACzD,IAAI,MAAM,EAAE,CAAC;QACZ,IAAI,IAAI,KAAK,sBAAsB,CAAC,MAAM,EAAE,wBAAwB,CAAC,EAAE,CAAC;IACzE,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC","sourcesContent":["import { type Component, Text } from \"@earendil-works/pi-tui\";\nimport { getTextOutput as getRenderedTextOutput } from \"../../../core/tools/render-utils.ts\";\nimport { stripAnsi } from \"../../../utils/ansi.ts\";\nimport { theme } from \"../theme/theme.ts\";\nimport type { ToolExecutionResult } from \"./tool-execution-types.ts\";\n\nconst FALLBACK_STRING_MAX_LENGTH = 160;\nconst FALLBACK_JSON_MAX_LENGTH = 2000;\n\nfunction sanitizeFallbackString(value: string, maxLength = FALLBACK_STRING_MAX_LENGTH): string {\n\tconst sanitized = stripAnsi(value)\n\t\t.replace(/[\\u0000-\\u001f\\u007f-\\u009f]+/g, \" \")\n\t\t.replace(/\\s+/g, \" \")\n\t\t.trim();\n\tif (sanitized.length <= maxLength) {\n\t\treturn sanitized;\n\t}\n\treturn `${sanitized.slice(0, Math.max(0, maxLength - 3))}...`;\n}\n\nfunction sanitizeFallbackJsonValue(_key: string, value: unknown): unknown {\n\treturn typeof value === \"string\" ? sanitizeFallbackString(value) : value;\n}\n\nexport function createToolCallFallback(toolName: string): Component {\n\treturn new Text(theme.fg(\"toolTitle\", theme.bold(toolName)), 0, 0);\n}\n\nexport function createToolResultFallback(\n\tresult: ToolExecutionResult | undefined,\n\tshowImages: boolean,\n): Component | undefined {\n\tconst output = getRenderedTextOutput(result, showImages);\n\treturn output ? new Text(theme.fg(\"toolOutput\", output), 0, 0) : undefined;\n}\n\nexport function formatToolExecutionFallback(\n\ttoolName: string,\n\targs: unknown,\n\tresult: ToolExecutionResult | undefined,\n\tshowImages: boolean,\n): string {\n\tlet text = theme.fg(\"toolTitle\", theme.bold(sanitizeFallbackString(toolName)));\n\tconst content = JSON.stringify(args, sanitizeFallbackJsonValue, 2);\n\tif (content) {\n\t\tconst boundedContent =\n\t\t\tcontent.length > FALLBACK_JSON_MAX_LENGTH ? `${content.slice(0, FALLBACK_JSON_MAX_LENGTH - 3)}...` : content;\n\t\ttext += `\\n\\n${boundedContent}`;\n\t}\n\tconst output = getRenderedTextOutput(result, showImages);\n\tif (output) {\n\t\ttext += `\\n${sanitizeFallbackString(output, FALLBACK_JSON_MAX_LENGTH)}`;\n\t}\n\treturn text;\n}\n"]}
1
+ {"version":3,"file":"tool-execution-fallback.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-execution-fallback.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Component, Text } from \"@earendil-works/pi-tui\";\nimport { getTextOutput as getRenderedTextOutput } from \"../../../core/tools/render-utils.ts\";\nimport { stripAnsi } from \"../../../utils/ansi.ts\";\nimport { theme } from \"../theme/theme.ts\";\nimport type { ToolExecutionResult } from \"./tool-execution-types.ts\";\n\nconst FALLBACK_STRING_MAX_LENGTH = 160;\nconst FALLBACK_JSON_MAX_LENGTH = 2000;\nconst JSON_VIEW_MAX_DEPTH = 3;\nconst JSON_VIEW_MAX_ROWS = 24;\nconst JSON_VIEW_MAX_VALUE_LENGTH = 100;\n\nfunction sanitizeFallbackString(value: string, maxLength = FALLBACK_STRING_MAX_LENGTH): string {\n\tconst sanitized = stripAnsi(value)\n\t\t.replace(/[\\u0000-\\u001f\\u007f-\\u009f]+/g, \" \")\n\t\t.replace(/\\s+/g, \" \")\n\t\t.trim();\n\tif (sanitized.length <= maxLength) {\n\t\treturn sanitized;\n\t}\n\treturn `${sanitized.slice(0, Math.max(0, maxLength - 3))}...`;\n}\n\nfunction sanitizeFallbackJsonValue(_key: string, value: unknown): unknown {\n\treturn typeof value === \"string\" ? sanitizeFallbackString(value) : value;\n}\n\ntype JsonRecord = Record<string, unknown>;\n\nfunction parseRenderableJson(text: string): JsonRecord | unknown[] | undefined {\n\tconst trimmed = text.trim();\n\tif (!trimmed.startsWith(\"{\") && !trimmed.startsWith(\"[\")) return undefined;\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(trimmed);\n\t\tif (typeof parsed !== \"object\" || parsed === null) return undefined;\n\t\treturn parsed as JsonRecord | unknown[];\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction truncateJsonViewValue(value: string): string {\n\treturn value.length > JSON_VIEW_MAX_VALUE_LENGTH ? `${value.slice(0, JSON_VIEW_MAX_VALUE_LENGTH)}\\u2026` : value;\n}\n\nfunction styleJsonPrimitive(value: unknown): string {\n\tif (typeof value === \"string\") return theme.fg(\"toolOutput\", truncateJsonViewValue(value));\n\tif (typeof value === \"number\" || typeof value === \"boolean\") return theme.fg(\"accent\", String(value));\n\tif (value === null) return theme.fg(\"dim\", \"null\");\n\treturn theme.fg(\"toolOutput\", truncateJsonViewValue(String(value)));\n}\n\nfunction styleJsonCompact(value: unknown): string {\n\treturn theme.fg(\"toolOutput\", truncateJsonViewValue(JSON.stringify(value) ?? String(value)));\n}\n\nfunction isJsonContainer(value: unknown): value is JsonRecord | unknown[] {\n\treturn typeof value === \"object\" && value !== null;\n}\n\n/**\n * Flattens a parsed JSON value into bounded `key: value` rows. Returns the rendered rows plus the\n * number of entries that were dropped so the caller can append a single truncation line.\n */\nfunction collectJsonViewRows(value: JsonRecord | unknown[]): { rows: string[]; omitted: number } {\n\tconst rows: string[] = [];\n\tlet omitted = 0;\n\n\tconst walk = (node: JsonRecord | unknown[], depth: number): void => {\n\t\tconst entries: Array<[string, unknown]> = Array.isArray(node)\n\t\t\t? node.map((item, index) => [String(index), item])\n\t\t\t: Object.entries(node);\n\t\tconst indent = \" \".repeat(depth);\n\n\t\tfor (const [key, entryValue] of entries) {\n\t\t\tif (rows.length >= JSON_VIEW_MAX_ROWS) {\n\t\t\t\tomitted += 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst label = `${indent}${theme.fg(\"muted\", `${key}:`)}`;\n\t\t\tif (isJsonContainer(entryValue)) {\n\t\t\t\tif (depth + 1 >= JSON_VIEW_MAX_DEPTH) {\n\t\t\t\t\trows.push(`${label} ${styleJsonCompact(entryValue)}`);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\trows.push(label);\n\t\t\t\twalk(entryValue, depth + 1);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\trows.push(`${label} ${styleJsonPrimitive(entryValue)}`);\n\t\t}\n\t};\n\n\twalk(value, 0);\n\treturn { rows, omitted };\n}\n\nfunction renderJsonView(value: JsonRecord | unknown[]): string {\n\tconst { rows, omitted } = collectJsonViewRows(value);\n\tif (rows.length === 0) return theme.fg(\"dim\", \"(empty)\");\n\tif (omitted > 0) rows.push(theme.fg(\"dim\", `\\u2026 ${omitted} more`));\n\treturn rows.join(\"\\n\");\n}\n\nexport function createToolCallFallback(toolName: string): Component {\n\treturn new Text(theme.fg(\"toolTitle\", theme.bold(toolName)), 0, 0);\n}\n\nexport function createToolResultFallback(\n\tresult: ToolExecutionResult | undefined,\n\tshowImages: boolean,\n): Component | undefined {\n\tconst output = getRenderedTextOutput(result, showImages);\n\tif (!output) return undefined;\n\tconst parsed = parseRenderableJson(output);\n\tif (parsed) return new Text(renderJsonView(parsed), 0, 0);\n\treturn new Text(theme.fg(\"toolOutput\", output), 0, 0);\n}\n\nexport function formatToolExecutionFallback(\n\ttoolName: string,\n\targs: unknown,\n\tresult: ToolExecutionResult | undefined,\n\tshowImages: boolean,\n): string {\n\tlet text = theme.fg(\"toolTitle\", theme.bold(sanitizeFallbackString(toolName)));\n\tconst content = JSON.stringify(args, sanitizeFallbackJsonValue, 2);\n\tif (content) {\n\t\tconst boundedContent =\n\t\t\tcontent.length > FALLBACK_JSON_MAX_LENGTH ? `${content.slice(0, FALLBACK_JSON_MAX_LENGTH - 3)}...` : content;\n\t\ttext += `\\n\\n${boundedContent}`;\n\t}\n\tconst output = getRenderedTextOutput(result, showImages);\n\tif (output) {\n\t\ttext += `\\n${sanitizeFallbackString(output, FALLBACK_JSON_MAX_LENGTH)}`;\n\t}\n\treturn text;\n}\n"]}
@@ -0,0 +1,29 @@
1
+ import type { AgentSessionRuntime } from "../../core/agent-session-runtime.ts";
2
+ import { type EnsuredHost } from "../rpc/host-ensure.ts";
3
+ import { type RpcClientEvent } from "../rpc/rpc-client.ts";
4
+ export declare const INTERACTIVE_HOST_FALLBACK_WARNING = "Warning: shared interactive host unavailable; continuing locally";
5
+ export interface InteractiveHostWarning {
6
+ readonly type: "interactive_host_fallback";
7
+ readonly message: string;
8
+ readonly cause: unknown;
9
+ }
10
+ export interface InteractiveHostRuntimeOptions {
11
+ readonly socket: string;
12
+ readonly agentDir?: string;
13
+ readonly ensureHost?: (options: {
14
+ socket: string;
15
+ agentDir?: string;
16
+ }) => Promise<EnsuredHost | undefined>;
17
+ onWarning?: (warning: InteractiveHostWarning) => void;
18
+ }
19
+ /**
20
+ * Replace only the transport-facing session operations. The object returned is
21
+ * deliberately still an AgentSessionRuntime: InteractiveMode and extensions
22
+ * retain their existing runtime seam, while the authoritative prompt/session
23
+ * state is hosted by the shared RPC process.
24
+ */
25
+ export declare function createInteractiveHostRuntime(localRuntime: AgentSessionRuntime, options: InteractiveHostRuntimeOptions): Promise<AgentSessionRuntime>;
26
+ export declare function isInteractiveHostEvent(event: RpcClientEvent): event is Extract<RpcClientEvent, {
27
+ type: string;
28
+ }>;
29
+ //# sourceMappingURL=interactive-host-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive-host-runtime.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-host-runtime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAE/E,OAAO,EAAE,KAAK,WAAW,EAAc,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtE,eAAO,MAAM,iCAAiC,qEAAqE,CAAC;AAEpH,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,IAAI,EAAE,2BAA2B,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,6BAA6B;IAC7C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;IAC3G,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,IAAI,CAAC;CACtD;AAED;;;;;GAKG;AACH,wBAAsB,4BAA4B,CACjD,YAAY,EAAE,mBAAmB,EACjC,OAAO,EAAE,6BAA6B,GACpC,OAAO,CAAC,mBAAmB,CAAC,CA0B9B;AAmMD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,GAAG,KAAK,IAAI,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAEhH"}
@@ -0,0 +1,244 @@
1
+ import { ensureHost } from "../rpc/host-ensure.js";
2
+ import { RpcClient } from "../rpc/rpc-client.js";
3
+ export const INTERACTIVE_HOST_FALLBACK_WARNING = "Warning: shared interactive host unavailable; continuing locally";
4
+ /**
5
+ * Replace only the transport-facing session operations. The object returned is
6
+ * deliberately still an AgentSessionRuntime: InteractiveMode and extensions
7
+ * retain their existing runtime seam, while the authoritative prompt/session
8
+ * state is hosted by the shared RPC process.
9
+ */
10
+ export async function createInteractiveHostRuntime(localRuntime, options) {
11
+ const sessionPath = localRuntime.session.sessionFile;
12
+ if (!sessionPath)
13
+ return localRuntime;
14
+ const startHost = options.ensureHost ?? ((hostOptions) => ensureHost(hostOptions));
15
+ const client = new RpcClient({ socketPath: options.socket });
16
+ try {
17
+ await startHost({ socket: options.socket, agentDir: options.agentDir });
18
+ await client.start();
19
+ const opened = await client.openSession({
20
+ sessionPath,
21
+ cwd: localRuntime.cwd,
22
+ provider: localRuntime.session.model?.provider,
23
+ modelId: localRuntime.session.model?.id,
24
+ thinkingLevel: localRuntime.session.thinkingLevel,
25
+ });
26
+ const remoteSession = createRemoteSessionProxy(localRuntime.session, client, opened.state);
27
+ return new RemoteInteractiveRuntime(localRuntime, remoteSession, client);
28
+ }
29
+ catch (cause) {
30
+ await client.stop().catch(() => { });
31
+ options.onWarning?.({
32
+ type: "interactive_host_fallback",
33
+ message: `${INTERACTIVE_HOST_FALLBACK_WARNING}: ${cause instanceof Error ? cause.message : String(cause)}`,
34
+ cause,
35
+ });
36
+ return localRuntime;
37
+ }
38
+ }
39
+ class RemoteInteractiveRuntime {
40
+ #local;
41
+ #session;
42
+ #client;
43
+ #rebindSession;
44
+ #beforeSessionInvalidate;
45
+ constructor(local, session, client) {
46
+ this.#local = local;
47
+ this.#session = session;
48
+ this.#client = client;
49
+ }
50
+ get session() {
51
+ return this.#session;
52
+ }
53
+ get services() {
54
+ return this.#local.services;
55
+ }
56
+ get cwd() {
57
+ return this.#local.cwd;
58
+ }
59
+ get diagnostics() {
60
+ return this.#local.diagnostics;
61
+ }
62
+ get modelFallbackMessage() {
63
+ return this.#local.modelFallbackMessage;
64
+ }
65
+ get launchProfile() {
66
+ return this.#local.launchProfile;
67
+ }
68
+ setBeforeSessionInvalidate(callback) {
69
+ this.#beforeSessionInvalidate = callback;
70
+ }
71
+ setRebindSession(callback) {
72
+ this.#rebindSession = callback;
73
+ }
74
+ async dispose() {
75
+ await this.#client.closeSession();
76
+ await this.#client.stop();
77
+ await this.#local.dispose();
78
+ }
79
+ async newSession() {
80
+ this.#beforeSessionInvalidate?.();
81
+ const result = await this.#client.newSession();
82
+ if (!result.cancelled)
83
+ await this.#rebindSession?.();
84
+ return result;
85
+ }
86
+ async switchSession(sessionPath) {
87
+ this.#beforeSessionInvalidate?.();
88
+ const result = await this.#client.switchSession(sessionPath);
89
+ if (!result.cancelled)
90
+ await this.#rebindSession?.();
91
+ return result;
92
+ }
93
+ async fork(entryId) {
94
+ this.#beforeSessionInvalidate?.();
95
+ const result = await this.#client.fork(entryId);
96
+ if (!result.cancelled)
97
+ await this.#rebindSession?.();
98
+ return { cancelled: result.cancelled, selectedText: result.text };
99
+ }
100
+ async importFromJsonl() {
101
+ throw new Error("Session import is not available while connected to the shared host");
102
+ }
103
+ }
104
+ function createRemoteSessionProxy(local, client, initialState) {
105
+ let state = initialState;
106
+ let streamingAssistant;
107
+ const listeners = new Set();
108
+ client.onEvent((wireEvent) => {
109
+ if (wireEvent.type === "agent_settled")
110
+ state = { ...state, isStreaming: false };
111
+ if (wireEvent.type === "agent_start")
112
+ state = { ...state, isStreaming: true };
113
+ if (wireEvent.type === "model_changed") {
114
+ state = { ...state, model: wireEvent.model, thinkingLevel: wireEvent.thinkingLevel };
115
+ }
116
+ if (wireEvent.type === "thinking_level_changed")
117
+ state = { ...state, thinkingLevel: wireEvent.level };
118
+ if (wireEvent.type === "message_start") {
119
+ if (wireEvent.message.role === "assistant")
120
+ streamingAssistant = structuredClone(wireEvent.message);
121
+ local.agent.state.messages.push(structuredClone(wireEvent.message));
122
+ }
123
+ if (wireEvent.type === "message_end") {
124
+ if (wireEvent.message.role === "assistant")
125
+ streamingAssistant = structuredClone(wireEvent.message);
126
+ const messages = local.agent.state.messages;
127
+ const previous = messages.at(-1);
128
+ if (previous?.role === wireEvent.message.role)
129
+ messages[messages.length - 1] = structuredClone(wireEvent.message);
130
+ }
131
+ const event = hydrateMessageUpdate(wireEvent, streamingAssistant);
132
+ for (const listener of listeners)
133
+ listener(event);
134
+ });
135
+ const session = new Proxy(local, {
136
+ get(target, property, receiver) {
137
+ if (property === "prompt")
138
+ return (message, options) => client.prompt(message, options?.images);
139
+ if (property === "abort")
140
+ return () => client.abort();
141
+ if (property === "steer")
142
+ return (message, images) => client.steer(message, images);
143
+ if (property === "followUp")
144
+ return (message, images) => client.followUp(message, images);
145
+ if (property === "waitForIdle")
146
+ return () => client.waitForIdle();
147
+ if (property === "getLastAssistantText")
148
+ return () => target.getLastAssistantText();
149
+ if (property === "setModel")
150
+ return async (model) => {
151
+ await client.setModel(model.provider, model.id);
152
+ };
153
+ if (property === "cycleModel")
154
+ return () => client.cycleModel();
155
+ if (property === "setThinkingLevel")
156
+ return (level) => void client.setThinkingLevel(level);
157
+ if (property === "cycleThinkingLevel")
158
+ return () => client.cycleThinkingLevel().then((result) => result?.level);
159
+ if (property === "getAvailableThinkingLevels")
160
+ return () => client.getAvailableThinkingLevels();
161
+ if (property === "setSteeringMode")
162
+ return (mode) => void client.setSteeringMode(mode);
163
+ if (property === "setFollowUpMode")
164
+ return (mode) => void client.setFollowUpMode(mode);
165
+ if (property === "compact")
166
+ return (instructions) => client.compact(instructions);
167
+ if (property === "setAutoCompactionEnabled")
168
+ return (enabled) => void client.setAutoCompaction(enabled);
169
+ if (property === "executeBash")
170
+ return (command) => client.bash(command);
171
+ if (property === "abortBash")
172
+ return () => void client.abortBash();
173
+ if (property === "getSessionStats")
174
+ return () => client.getSessionStats();
175
+ if (property === "exportToHtml")
176
+ return (outputPath) => client.exportHtml(outputPath).then((result) => result.path);
177
+ if (property === "setSessionName")
178
+ return (name) => void client.setSessionName(name);
179
+ if (property === "getUserMessagesForForking")
180
+ return () => client.getForkMessages();
181
+ if (property === "subscribe")
182
+ return (listener) => {
183
+ listeners.add(listener);
184
+ const localUnsubscribe = target.subscribe(listener);
185
+ return () => {
186
+ listeners.delete(listener);
187
+ localUnsubscribe();
188
+ };
189
+ };
190
+ if (property === "isStreaming")
191
+ return state.isStreaming;
192
+ if (property === "sessionFile")
193
+ return state.sessionFile;
194
+ if (property === "sessionId")
195
+ return state.sessionId;
196
+ if (property === "messages")
197
+ return target.messages;
198
+ if (property === "model")
199
+ return state.model ?? target.model;
200
+ if (property === "thinkingLevel")
201
+ return state.thinkingLevel;
202
+ return Reflect.get(target, property, receiver);
203
+ },
204
+ });
205
+ return session;
206
+ }
207
+ function hydrateMessageUpdate(event, streamingAssistant) {
208
+ if (event.type !== "message_update" || !streamingAssistant)
209
+ return event;
210
+ const update = event.assistantMessageEvent;
211
+ if (update.type !== "text_delta" && update.type !== "thinking_delta" && update.type !== "toolcall_delta") {
212
+ return event;
213
+ }
214
+ const content = streamingAssistant.content[update.contentIndex];
215
+ if (update.type === "text_delta" && content?.type === "text")
216
+ content.text += update.delta;
217
+ if (update.type === "thinking_delta" && content?.type === "thinking")
218
+ content.thinking += update.delta;
219
+ if (update.type === "toolcall_delta" && content?.type === "toolCall") {
220
+ const raw = JSON.stringify(content.arguments) + update.delta;
221
+ try {
222
+ const parsed = JSON.parse(raw);
223
+ if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
224
+ content.arguments = parsed;
225
+ }
226
+ }
227
+ catch {
228
+ // Keep the last valid arguments until the next complete update.
229
+ }
230
+ }
231
+ streamingAssistant.usage = event.usage;
232
+ return {
233
+ type: "message_update",
234
+ message: structuredClone(streamingAssistant),
235
+ assistantMessageEvent: { ...update, partial: structuredClone(streamingAssistant) },
236
+ };
237
+ }
238
+ function stateFromRpc(state) {
239
+ return state;
240
+ }
241
+ export function isInteractiveHostEvent(event) {
242
+ return typeof event === "object" && event !== null && "type" in event;
243
+ }
244
+ //# sourceMappingURL=interactive-host-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive-host-runtime.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-host-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentSession, AgentSessionEvent, AgentSessionEventListener } from \"../../core/agent-session.ts\";\nimport type { AgentSessionRuntime } from \"../../core/agent-session-runtime.ts\";\nimport type { AgentSessionRuntimeDiagnostic } from \"../../core/agent-session-services.ts\";\nimport { type EnsuredHost, ensureHost } from \"../rpc/host-ensure.ts\";\nimport { RpcClient, type RpcClientEvent } from \"../rpc/rpc-client.ts\";\n\nexport const INTERACTIVE_HOST_FALLBACK_WARNING = \"Warning: shared interactive host unavailable; continuing locally\";\n\nexport interface InteractiveHostWarning {\n\treadonly type: \"interactive_host_fallback\";\n\treadonly message: string;\n\treadonly cause: unknown;\n}\n\nexport interface InteractiveHostRuntimeOptions {\n\treadonly socket: string;\n\treadonly agentDir?: string;\n\treadonly ensureHost?: (options: { socket: string; agentDir?: string }) => Promise<EnsuredHost | undefined>;\n\tonWarning?: (warning: InteractiveHostWarning) => void;\n}\n\n/**\n * Replace only the transport-facing session operations. The object returned is\n * deliberately still an AgentSessionRuntime: InteractiveMode and extensions\n * retain their existing runtime seam, while the authoritative prompt/session\n * state is hosted by the shared RPC process.\n */\nexport async function createInteractiveHostRuntime(\n\tlocalRuntime: AgentSessionRuntime,\n\toptions: InteractiveHostRuntimeOptions,\n): Promise<AgentSessionRuntime> {\n\tconst sessionPath = localRuntime.session.sessionFile;\n\tif (!sessionPath) return localRuntime;\n\tconst startHost = options.ensureHost ?? ((hostOptions) => ensureHost(hostOptions));\n\tconst client = new RpcClient({ socketPath: options.socket });\n\ttry {\n\t\tawait startHost({ socket: options.socket, agentDir: options.agentDir });\n\t\tawait client.start();\n\t\tconst opened = await client.openSession({\n\t\t\tsessionPath,\n\t\t\tcwd: localRuntime.cwd,\n\t\t\tprovider: localRuntime.session.model?.provider,\n\t\t\tmodelId: localRuntime.session.model?.id,\n\t\t\tthinkingLevel: localRuntime.session.thinkingLevel,\n\t\t});\n\t\tconst remoteSession = createRemoteSessionProxy(localRuntime.session, client, opened.state);\n\t\treturn new RemoteInteractiveRuntime(localRuntime, remoteSession, client) as unknown as AgentSessionRuntime;\n\t} catch (cause) {\n\t\tawait client.stop().catch(() => {});\n\t\toptions.onWarning?.({\n\t\t\ttype: \"interactive_host_fallback\",\n\t\t\tmessage: `${INTERACTIVE_HOST_FALLBACK_WARNING}: ${cause instanceof Error ? cause.message : String(cause)}`,\n\t\t\tcause,\n\t\t});\n\t\treturn localRuntime;\n\t}\n}\n\nclass RemoteInteractiveRuntime {\n\treadonly #local: AgentSessionRuntime;\n\treadonly #session: AgentSession;\n\treadonly #client: RpcClient;\n\t#rebindSession: (() => Promise<void>) | undefined;\n\t#beforeSessionInvalidate: (() => void) | undefined;\n\n\tconstructor(local: AgentSessionRuntime, session: AgentSession, client: RpcClient) {\n\t\tthis.#local = local;\n\t\tthis.#session = session;\n\t\tthis.#client = client;\n\t}\n\n\tget session(): AgentSession {\n\t\treturn this.#session;\n\t}\n\tget services(): AgentSessionRuntime[\"services\"] {\n\t\treturn this.#local.services;\n\t}\n\tget cwd(): string {\n\t\treturn this.#local.cwd;\n\t}\n\tget diagnostics(): readonly AgentSessionRuntimeDiagnostic[] {\n\t\treturn this.#local.diagnostics;\n\t}\n\tget modelFallbackMessage(): string | undefined {\n\t\treturn this.#local.modelFallbackMessage;\n\t}\n\tget launchProfile(): AgentSessionRuntime[\"launchProfile\"] {\n\t\treturn this.#local.launchProfile;\n\t}\n\tsetBeforeSessionInvalidate(callback?: () => void): void {\n\t\tthis.#beforeSessionInvalidate = callback;\n\t}\n\tsetRebindSession(callback?: () => Promise<void>): void {\n\t\tthis.#rebindSession = callback;\n\t}\n\tasync dispose(): Promise<void> {\n\t\tawait this.#client.closeSession();\n\t\tawait this.#client.stop();\n\t\tawait this.#local.dispose();\n\t}\n\tasync newSession(): Promise<{ cancelled: boolean }> {\n\t\tthis.#beforeSessionInvalidate?.();\n\t\tconst result = await this.#client.newSession();\n\t\tif (!result.cancelled) await this.#rebindSession?.();\n\t\treturn result;\n\t}\n\tasync switchSession(sessionPath: string): Promise<{ cancelled: boolean }> {\n\t\tthis.#beforeSessionInvalidate?.();\n\t\tconst result = await this.#client.switchSession(sessionPath);\n\t\tif (!result.cancelled) await this.#rebindSession?.();\n\t\treturn result;\n\t}\n\tasync fork(entryId: string): Promise<{ cancelled: boolean; selectedText?: string }> {\n\t\tthis.#beforeSessionInvalidate?.();\n\t\tconst result = await this.#client.fork(entryId);\n\t\tif (!result.cancelled) await this.#rebindSession?.();\n\t\treturn { cancelled: result.cancelled, selectedText: result.text };\n\t}\n\tasync importFromJsonl(): Promise<{ cancelled: boolean }> {\n\t\tthrow new Error(\"Session import is not available while connected to the shared host\");\n\t}\n}\n\nfunction createRemoteSessionProxy(\n\tlocal: AgentSession,\n\tclient: RpcClient,\n\tinitialState: ReturnType<typeof stateFromRpc>,\n): AgentSession {\n\tlet state = initialState;\n\tlet streamingAssistant: Extract<AgentSession[\"messages\"][number], { role: \"assistant\" }> | undefined;\n\tconst listeners = new Set<AgentSessionEventListener>();\n\tclient.onEvent((wireEvent) => {\n\t\tif (wireEvent.type === \"agent_settled\") state = { ...state, isStreaming: false };\n\t\tif (wireEvent.type === \"agent_start\") state = { ...state, isStreaming: true };\n\t\tif (wireEvent.type === \"model_changed\") {\n\t\t\tstate = { ...state, model: wireEvent.model, thinkingLevel: wireEvent.thinkingLevel };\n\t\t}\n\t\tif (wireEvent.type === \"thinking_level_changed\") state = { ...state, thinkingLevel: wireEvent.level };\n\t\tif (wireEvent.type === \"message_start\") {\n\t\t\tif (wireEvent.message.role === \"assistant\") streamingAssistant = structuredClone(wireEvent.message);\n\t\t\tlocal.agent.state.messages.push(structuredClone(wireEvent.message));\n\t\t}\n\t\tif (wireEvent.type === \"message_end\") {\n\t\t\tif (wireEvent.message.role === \"assistant\") streamingAssistant = structuredClone(wireEvent.message);\n\t\t\tconst messages = local.agent.state.messages;\n\t\t\tconst previous = messages.at(-1);\n\t\t\tif (previous?.role === wireEvent.message.role)\n\t\t\t\tmessages[messages.length - 1] = structuredClone(wireEvent.message);\n\t\t}\n\t\tconst event = hydrateMessageUpdate(wireEvent, streamingAssistant);\n\t\tfor (const listener of listeners) listener(event);\n\t});\n\tconst session = new Proxy(local, {\n\t\tget(target, property, receiver) {\n\t\t\tif (property === \"prompt\")\n\t\t\t\treturn (message: string, options?: Parameters<AgentSession[\"prompt\"]>[1]) =>\n\t\t\t\t\tclient.prompt(message, options?.images);\n\t\t\tif (property === \"abort\") return () => client.abort();\n\t\t\tif (property === \"steer\")\n\t\t\t\treturn (message: string, images?: Parameters<AgentSession[\"steer\"]>[1]) => client.steer(message, images);\n\t\t\tif (property === \"followUp\")\n\t\t\t\treturn (message: string, images?: Parameters<AgentSession[\"followUp\"]>[1]) =>\n\t\t\t\t\tclient.followUp(message, images);\n\t\t\tif (property === \"waitForIdle\") return () => client.waitForIdle();\n\t\t\tif (property === \"getLastAssistantText\") return () => target.getLastAssistantText();\n\t\t\tif (property === \"setModel\")\n\t\t\t\treturn async (model: NonNullable<AgentSession[\"model\"]>) => {\n\t\t\t\t\tawait client.setModel(model.provider, model.id);\n\t\t\t\t};\n\t\t\tif (property === \"cycleModel\") return () => client.cycleModel();\n\t\t\tif (property === \"setThinkingLevel\")\n\t\t\t\treturn (level: AgentSession[\"thinkingLevel\"]) => void client.setThinkingLevel(level);\n\t\t\tif (property === \"cycleThinkingLevel\")\n\t\t\t\treturn () => client.cycleThinkingLevel().then((result) => result?.level);\n\t\t\tif (property === \"getAvailableThinkingLevels\") return () => client.getAvailableThinkingLevels();\n\t\t\tif (property === \"setSteeringMode\")\n\t\t\t\treturn (mode: AgentSession[\"steeringMode\"]) => void client.setSteeringMode(mode);\n\t\t\tif (property === \"setFollowUpMode\")\n\t\t\t\treturn (mode: AgentSession[\"followUpMode\"]) => void client.setFollowUpMode(mode);\n\t\t\tif (property === \"compact\") return (instructions?: string) => client.compact(instructions);\n\t\t\tif (property === \"setAutoCompactionEnabled\")\n\t\t\t\treturn (enabled: boolean) => void client.setAutoCompaction(enabled);\n\t\t\tif (property === \"executeBash\") return (command: string) => client.bash(command);\n\t\t\tif (property === \"abortBash\") return () => void client.abortBash();\n\t\t\tif (property === \"getSessionStats\") return () => client.getSessionStats();\n\t\t\tif (property === \"exportToHtml\")\n\t\t\t\treturn (outputPath?: string) => client.exportHtml(outputPath).then((result) => result.path);\n\t\t\tif (property === \"setSessionName\") return (name: string) => void client.setSessionName(name);\n\t\t\tif (property === \"getUserMessagesForForking\") return () => client.getForkMessages();\n\t\t\tif (property === \"subscribe\")\n\t\t\t\treturn (listener: AgentSessionEventListener) => {\n\t\t\t\t\tlisteners.add(listener);\n\t\t\t\t\tconst localUnsubscribe = target.subscribe(listener);\n\t\t\t\t\treturn () => {\n\t\t\t\t\t\tlisteners.delete(listener);\n\t\t\t\t\t\tlocalUnsubscribe();\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\tif (property === \"isStreaming\") return state.isStreaming;\n\t\t\tif (property === \"sessionFile\") return state.sessionFile;\n\t\t\tif (property === \"sessionId\") return state.sessionId;\n\t\t\tif (property === \"messages\") return target.messages;\n\t\t\tif (property === \"model\") return state.model ?? target.model;\n\t\t\tif (property === \"thinkingLevel\") return state.thinkingLevel;\n\t\t\treturn Reflect.get(target, property, receiver);\n\t\t},\n\t});\n\treturn session;\n}\n\nfunction hydrateMessageUpdate(\n\tevent: RpcClientEvent,\n\tstreamingAssistant: Extract<AgentSession[\"messages\"][number], { role: \"assistant\" }> | undefined,\n): AgentSessionEvent {\n\tif (event.type !== \"message_update\" || !streamingAssistant) return event as unknown as AgentSessionEvent;\n\tconst update = event.assistantMessageEvent;\n\tif (update.type !== \"text_delta\" && update.type !== \"thinking_delta\" && update.type !== \"toolcall_delta\") {\n\t\treturn event as unknown as AgentSessionEvent;\n\t}\n\tconst content = streamingAssistant.content[update.contentIndex];\n\tif (update.type === \"text_delta\" && content?.type === \"text\") content.text += update.delta;\n\tif (update.type === \"thinking_delta\" && content?.type === \"thinking\") content.thinking += update.delta;\n\tif (update.type === \"toolcall_delta\" && content?.type === \"toolCall\") {\n\t\tconst raw = JSON.stringify(content.arguments) + update.delta;\n\t\ttry {\n\t\t\tconst parsed: unknown = JSON.parse(raw);\n\t\t\tif (typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)) {\n\t\t\t\tcontent.arguments = parsed as Record<string, unknown>;\n\t\t\t}\n\t\t} catch {\n\t\t\t// Keep the last valid arguments until the next complete update.\n\t\t}\n\t}\n\tstreamingAssistant.usage = event.usage;\n\treturn {\n\t\ttype: \"message_update\",\n\t\tmessage: structuredClone(streamingAssistant),\n\t\tassistantMessageEvent: { ...update, partial: structuredClone(streamingAssistant) },\n\t} as AgentSessionEvent;\n}\n\nfunction stateFromRpc(state: {\n\tmodel?: AgentSession[\"model\"];\n\tthinkingLevel: AgentSession[\"thinkingLevel\"];\n\tisStreaming: boolean;\n\tsessionFile?: string;\n\tsessionId: string;\n}) {\n\treturn state;\n}\n\nexport function isInteractiveHostEvent(event: RpcClientEvent): event is Extract<RpcClientEvent, { type: string }> {\n\treturn typeof event === \"object\" && event !== null && \"type\" in event;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"connection-handler.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/connection-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAwC/E,OAAO,KAAK,EAWX,eAAe,EAEf,MAAM,gBAAgB,CAAC;AAGxB,kFAAkF;AAClF,MAAM,WAAW,oBAAoB;IACpC,mFAAmF;IACnF,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,iFAAiF;IACjF,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,0DAA0D;IAC1D,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,oBAAoB;IACpC;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,sEAAsE;IACtE,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C;;;OAGG;IACH,mBAAmB,IAAI,OAAO,CAAC;IAC/B,iFAAiF;IACjF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AA4BD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,GAAG,eAAe,CAiB3E;AA4BD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACzC,WAAW,EAAE,mBAAmB,EAChC,IAAI,EAAE,iBAAiB,EACvB,OAAO,GAAE,oBAAyB,GAChC,oBAAoB,CA8hCtB"}
1
+ {"version":3,"file":"connection-handler.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/connection-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAwC/E,OAAO,KAAK,EAWX,eAAe,EAEf,MAAM,gBAAgB,CAAC;AAGxB,kFAAkF;AAClF,MAAM,WAAW,oBAAoB;IACpC,mFAAmF;IACnF,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,iFAAiF;IACjF,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,0DAA0D;IAC1D,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,oBAAoB;IACpC;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,sEAAsE;IACtE,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C;;;OAGG;IACH,mBAAmB,IAAI,OAAO,CAAC;IAC/B,iFAAiF;IACjF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AA4BD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,GAAG,eAAe,CAiB3E;AA4BD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACzC,WAAW,EAAE,mBAAmB,EAChC,IAAI,EAAE,iBAAiB,EACvB,OAAO,GAAE,oBAAyB,GAChC,oBAAoB,CAmiCtB"}
@@ -16,6 +16,7 @@
16
16
  */
17
17
  import * as crypto from "node:crypto";
18
18
  import { basename, dirname, extname } from "node:path";
19
+ import { VERSION } from "../../config.js";
19
20
  import { buildLoginProviderInfos } from "../../core/auth-providers.js";
20
21
  import { emitProviderAccountsChanged, subscribeProviderAccountEvents, } from "../../core/extensions/builtin/claude-sdk-oauth/account-events.js";
21
22
  import { CLAUDE_SDK_OAUTH_PROVIDER_ID, getProviderAccounts, pinProviderAccount, removeProviderAccount, } from "../../core/extensions/builtin/claude-sdk-oauth/account-management.js";
@@ -568,7 +569,12 @@ export function createRpcConnectionHandler(runtimeHost, sink, options = {}) {
568
569
  type: "response",
569
570
  command: "get_protocol_info",
570
571
  success: true,
571
- data: { protocolVersion: 1, capabilities: ["multi_session"], mode: "classic" },
572
+ data: {
573
+ protocolVersion: 1,
574
+ serverVersion: VERSION,
575
+ capabilities: [...new Set(["multi_session", ...(options.capabilities ?? [])])],
576
+ mode: "classic",
577
+ },
572
578
  };
573
579
  case "open_session":
574
580
  return error(id, "open_session", "multi_session_disabled");