@code-yeongyu/senpi 2026.8.26 → 2026.8.28

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 (297) hide show
  1. package/CHANGELOG.md +76 -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/agent-session.d.ts.map +1 -1
  8. package/dist/core/agent-session.js +10 -1
  9. package/dist/core/agent-session.js.map +1 -1
  10. package/dist/core/bash-executor.d.ts.map +1 -1
  11. package/dist/core/bash-executor.js +67 -29
  12. package/dist/core/bash-executor.js.map +1 -1
  13. package/dist/core/credential-accounts.d.ts +31 -0
  14. package/dist/core/credential-accounts.d.ts.map +1 -0
  15. package/dist/core/credential-accounts.js +125 -0
  16. package/dist/core/credential-accounts.js.map +1 -0
  17. package/dist/core/credential-pool/classify.d.ts +42 -0
  18. package/dist/core/credential-pool/classify.d.ts.map +1 -0
  19. package/dist/core/credential-pool/classify.js +75 -0
  20. package/dist/core/credential-pool/classify.js.map +1 -0
  21. package/dist/core/credential-pool/env-slots.d.ts +22 -0
  22. package/dist/core/credential-pool/env-slots.d.ts.map +1 -0
  23. package/dist/core/credential-pool/env-slots.js +37 -0
  24. package/dist/core/credential-pool/env-slots.js.map +1 -0
  25. package/dist/core/credential-pool/failover.d.ts +54 -0
  26. package/dist/core/credential-pool/failover.d.ts.map +1 -0
  27. package/dist/core/credential-pool/failover.js +106 -0
  28. package/dist/core/credential-pool/failover.js.map +1 -0
  29. package/dist/core/credential-pool/rotation-stream.d.ts +43 -0
  30. package/dist/core/credential-pool/rotation-stream.d.ts.map +1 -0
  31. package/dist/core/credential-pool/rotation-stream.js +96 -0
  32. package/dist/core/credential-pool/rotation-stream.js.map +1 -0
  33. package/dist/core/credential-pool/state-store.d.ts +89 -0
  34. package/dist/core/credential-pool/state-store.d.ts.map +1 -0
  35. package/dist/core/credential-pool/state-store.js +166 -0
  36. package/dist/core/credential-pool/state-store.js.map +1 -0
  37. package/dist/core/extensions/builtin/account/index.d.ts +9 -0
  38. package/dist/core/extensions/builtin/account/index.d.ts.map +1 -0
  39. package/dist/core/extensions/builtin/account/index.js +69 -0
  40. package/dist/core/extensions/builtin/account/index.js.map +1 -0
  41. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  42. package/dist/core/extensions/builtin/compaction/index.js +67 -0
  43. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  44. package/dist/core/extensions/builtin/compaction/log.d.ts +1 -1
  45. package/dist/core/extensions/builtin/compaction/log.d.ts.map +1 -1
  46. package/dist/core/extensions/builtin/compaction/log.js +1 -0
  47. package/dist/core/extensions/builtin/compaction/log.js.map +1 -1
  48. package/dist/core/extensions/builtin/config-reload/index.js +14 -22
  49. package/dist/core/extensions/builtin/config-reload/index.js.map +1 -1
  50. package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts +1 -0
  51. package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts.map +1 -1
  52. package/dist/core/extensions/builtin/goal/continuation-recovery.js +2 -0
  53. package/dist/core/extensions/builtin/goal/continuation-recovery.js.map +1 -1
  54. package/dist/core/extensions/builtin/goal/continuation.d.ts +8 -1
  55. package/dist/core/extensions/builtin/goal/continuation.d.ts.map +1 -1
  56. package/dist/core/extensions/builtin/goal/continuation.js +15 -0
  57. package/dist/core/extensions/builtin/goal/continuation.js.map +1 -1
  58. package/dist/core/extensions/builtin/goal/direct-input-lifecycle.js +2 -2
  59. package/dist/core/extensions/builtin/goal/direct-input-lifecycle.js.map +1 -1
  60. package/dist/core/extensions/builtin/goal/format.d.ts +6 -1
  61. package/dist/core/extensions/builtin/goal/format.d.ts.map +1 -1
  62. package/dist/core/extensions/builtin/goal/format.js +6 -0
  63. package/dist/core/extensions/builtin/goal/format.js.map +1 -1
  64. package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts.map +1 -1
  65. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +5 -2
  66. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js.map +1 -1
  67. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
  68. package/dist/core/extensions/builtin/goal/monitor-continuation.js +31 -7
  69. package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
  70. package/dist/core/extensions/builtin/goal/persistence.js +2 -0
  71. package/dist/core/extensions/builtin/goal/persistence.js.map +1 -1
  72. package/dist/core/extensions/builtin/goal/renderers.d.ts +14 -0
  73. package/dist/core/extensions/builtin/goal/renderers.d.ts.map +1 -0
  74. package/dist/core/extensions/builtin/goal/renderers.js +153 -0
  75. package/dist/core/extensions/builtin/goal/renderers.js.map +1 -0
  76. package/dist/core/extensions/builtin/goal/store.d.ts +6 -2
  77. package/dist/core/extensions/builtin/goal/store.d.ts.map +1 -1
  78. package/dist/core/extensions/builtin/goal/store.js +8 -2
  79. package/dist/core/extensions/builtin/goal/store.js.map +1 -1
  80. package/dist/core/extensions/builtin/goal/tool-registration.d.ts.map +1 -1
  81. package/dist/core/extensions/builtin/goal/tool-registration.js +16 -6
  82. package/dist/core/extensions/builtin/goal/tool-registration.js.map +1 -1
  83. package/dist/core/extensions/builtin/goal/types.d.ts +1 -0
  84. package/dist/core/extensions/builtin/goal/types.d.ts.map +1 -1
  85. package/dist/core/extensions/builtin/goal/types.js.map +1 -1
  86. package/dist/core/extensions/builtin/imagegen/index.d.ts.map +1 -1
  87. package/dist/core/extensions/builtin/imagegen/index.js +10 -3
  88. package/dist/core/extensions/builtin/imagegen/index.js.map +1 -1
  89. package/dist/core/extensions/builtin/index.d.ts.map +1 -1
  90. package/dist/core/extensions/builtin/index.js +4 -0
  91. package/dist/core/extensions/builtin/index.js.map +1 -1
  92. package/dist/core/extensions/builtin/todotools/index.js +1 -1
  93. package/dist/core/extensions/builtin/todotools/index.js.map +1 -1
  94. package/dist/core/extensions/builtin/todotools/native-todo-mirror.d.ts +1 -1
  95. package/dist/core/extensions/builtin/todotools/native-todo-mirror.d.ts.map +1 -1
  96. package/dist/core/extensions/builtin/todotools/native-todo-mirror.js +1 -1
  97. package/dist/core/extensions/builtin/todotools/native-todo-mirror.js.map +1 -1
  98. package/dist/core/hidden-stdout-log.d.ts +10 -0
  99. package/dist/core/hidden-stdout-log.d.ts.map +1 -1
  100. package/dist/core/hidden-stdout-log.js +36 -5
  101. package/dist/core/hidden-stdout-log.js.map +1 -1
  102. package/dist/core/model-config-schema.d.ts +85 -12
  103. package/dist/core/model-config-schema.d.ts.map +1 -1
  104. package/dist/core/model-config-schema.js +25 -0
  105. package/dist/core/model-config-schema.js.map +1 -1
  106. package/dist/core/model-runtime.d.ts +34 -1
  107. package/dist/core/model-runtime.d.ts.map +1 -1
  108. package/dist/core/model-runtime.js +98 -5
  109. package/dist/core/model-runtime.js.map +1 -1
  110. package/dist/core/tools/output-accumulator.d.ts +2 -0
  111. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  112. package/dist/core/tools/output-accumulator.js +32 -7
  113. package/dist/core/tools/output-accumulator.js.map +1 -1
  114. package/dist/index.d.ts +1 -1
  115. package/dist/index.d.ts.map +1 -1
  116. package/dist/index.js +1 -1
  117. package/dist/index.js.map +1 -1
  118. package/dist/main.d.ts.map +1 -1
  119. package/dist/main.js +38 -3
  120. package/dist/main.js.map +1 -1
  121. package/dist/modes/app-server/server/account.d.ts.map +1 -1
  122. package/dist/modes/app-server/server/account.js +5 -5
  123. package/dist/modes/app-server/server/account.js.map +1 -1
  124. package/dist/modes/index.d.ts +1 -0
  125. package/dist/modes/index.d.ts.map +1 -1
  126. package/dist/modes/index.js +1 -0
  127. package/dist/modes/index.js.map +1 -1
  128. package/dist/modes/interactive/components/footer.d.ts +11 -3
  129. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  130. package/dist/modes/interactive/components/footer.js +31 -1
  131. package/dist/modes/interactive/components/footer.js.map +1 -1
  132. package/dist/modes/interactive/components/tool-execution-fallback.d.ts.map +1 -1
  133. package/dist/modes/interactive/components/tool-execution-fallback.js +82 -1
  134. package/dist/modes/interactive/components/tool-execution-fallback.js.map +1 -1
  135. package/dist/modes/interactive/grok/chrome.d.ts +4 -4
  136. package/dist/modes/interactive/grok/chrome.d.ts.map +1 -1
  137. package/dist/modes/interactive/grok/chrome.js.map +1 -1
  138. package/dist/modes/interactive/grok/footer.d.ts +3 -3
  139. package/dist/modes/interactive/grok/footer.d.ts.map +1 -1
  140. package/dist/modes/interactive/grok/footer.js.map +1 -1
  141. package/dist/modes/interactive/interactive-host-runtime.d.ts +44 -0
  142. package/dist/modes/interactive/interactive-host-runtime.d.ts.map +1 -0
  143. package/dist/modes/interactive/interactive-host-runtime.js +271 -0
  144. package/dist/modes/interactive/interactive-host-runtime.js.map +1 -0
  145. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  146. package/dist/modes/interactive/interactive-mode.js +65 -21
  147. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  148. package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
  149. package/dist/modes/rpc/connection-handler.js +19 -6
  150. package/dist/modes/rpc/connection-handler.js.map +1 -1
  151. package/dist/modes/rpc/host-ensure.d.ts +41 -0
  152. package/dist/modes/rpc/host-ensure.d.ts.map +1 -0
  153. package/dist/modes/rpc/host-ensure.js +245 -0
  154. package/dist/modes/rpc/host-ensure.js.map +1 -0
  155. package/dist/modes/rpc/host-lifecycle.d.ts +57 -0
  156. package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -0
  157. package/dist/modes/rpc/host-lifecycle.js +491 -0
  158. package/dist/modes/rpc/host-lifecycle.js.map +1 -0
  159. package/dist/modes/rpc/host-watchdog.d.ts +33 -0
  160. package/dist/modes/rpc/host-watchdog.d.ts.map +1 -0
  161. package/dist/modes/rpc/host-watchdog.js +142 -0
  162. package/dist/modes/rpc/host-watchdog.js.map +1 -0
  163. package/dist/modes/rpc/multi-session-host.d.ts +7 -1
  164. package/dist/modes/rpc/multi-session-host.d.ts.map +1 -1
  165. package/dist/modes/rpc/multi-session-host.js +206 -32
  166. package/dist/modes/rpc/multi-session-host.js.map +1 -1
  167. package/dist/modes/rpc/rpc-client.d.ts +41 -3
  168. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  169. package/dist/modes/rpc/rpc-client.js +125 -14
  170. package/dist/modes/rpc/rpc-client.js.map +1 -1
  171. package/dist/modes/rpc/rpc-mode.d.ts +1 -1
  172. package/dist/modes/rpc/rpc-mode.js +1 -1
  173. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  174. package/dist/modes/rpc/rpc-types.d.ts +6 -2
  175. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  176. package/dist/modes/rpc/rpc-types.js.map +1 -1
  177. package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
  178. package/dist/modes/rpc/session-command-router.js +24 -6
  179. package/dist/modes/rpc/session-command-router.js.map +1 -1
  180. package/dist/modes/rpc/session-event-writer.d.ts +13 -2
  181. package/dist/modes/rpc/session-event-writer.d.ts.map +1 -1
  182. package/dist/modes/rpc/session-event-writer.js +65 -25
  183. package/dist/modes/rpc/session-event-writer.js.map +1 -1
  184. package/dist/modes/rpc/session-registry.d.ts +9 -0
  185. package/dist/modes/rpc/session-registry.d.ts.map +1 -1
  186. package/dist/modes/rpc/session-registry.js +31 -3
  187. package/dist/modes/rpc/session-registry.js.map +1 -1
  188. package/docs/providers.md +48 -0
  189. package/docs/rpc.md +59 -5
  190. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +44 -0
  191. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  192. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/context-manager.ts +13 -1
  193. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/inline-worker.ts +15 -1
  194. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-indirect-eval.js +711 -1
  195. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/transport.ts +14 -1
  196. package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +10 -10
  197. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-eval-result.ts +9 -3
  198. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +6 -1
  199. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/edit.d.ts.map +1 -1
  200. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/edit.js +20 -4
  201. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/edit.js.map +1 -1
  202. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/index.d.ts +1 -1
  203. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/index.d.ts.map +1 -1
  204. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/index.js.map +1 -1
  205. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/post-mutate.d.ts +21 -0
  206. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/post-mutate.d.ts.map +1 -0
  207. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/post-mutate.js +27 -0
  208. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/post-mutate.js.map +1 -0
  209. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/tool-context.d.ts +24 -0
  210. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/tool-context.d.ts.map +1 -1
  211. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/tool-context.js.map +1 -1
  212. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/write.d.ts.map +1 -1
  213. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/write.js +7 -2
  214. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/write.js.map +1 -1
  215. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  216. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-pairs.d.ts +1 -1
  217. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-pairs.d.ts.map +1 -1
  218. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-pairs.js +46 -14
  219. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-pairs.js.map +1 -1
  220. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts +11 -0
  221. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts.map +1 -1
  222. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js +30 -16
  223. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js.map +1 -1
  224. package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.d.ts +2 -1
  225. package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.d.ts.map +1 -1
  226. package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.js +2 -1
  227. package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.js.map +1 -1
  228. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/classify.d.ts +16 -0
  229. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/classify.d.ts.map +1 -0
  230. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/classify.js +75 -0
  231. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/classify.js.map +1 -0
  232. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.d.ts +45 -0
  233. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.d.ts.map +1 -0
  234. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.js +81 -0
  235. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.js.map +1 -0
  236. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/select.d.ts +31 -0
  237. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/select.d.ts.map +1 -0
  238. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/select.js +65 -0
  239. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/select.js.map +1 -0
  240. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.d.ts +12 -0
  241. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.d.ts.map +1 -1
  242. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.js +37 -0
  243. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.js.map +1 -1
  244. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.d.ts +6 -0
  245. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.d.ts.map +1 -1
  246. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js +32 -6
  247. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js.map +1 -1
  248. package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts +3 -2
  249. package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts.map +1 -1
  250. package/node_modules/@earendil-works/pi-ai/dist/auth/types.js.map +1 -1
  251. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.d.ts +6 -0
  252. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.d.ts.map +1 -1
  253. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js +6 -1
  254. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js.map +1 -1
  255. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts +75 -0
  256. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  257. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +75 -0
  258. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
  259. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  260. package/node_modules/@earendil-works/pi-ai/dist/providers/data/alibaba-token-plan.json +1 -1
  261. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  262. package/node_modules/@earendil-works/pi-ai/dist/providers/data/baseten.json +1 -1
  263. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  264. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-workers-ai.json +1 -1
  265. package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
  266. package/node_modules/@earendil-works/pi-ai/dist/providers/data/github-copilot.json +1 -1
  267. package/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.json +1 -1
  268. package/node_modules/@earendil-works/pi-ai/dist/providers/data/minimax-cn.json +1 -1
  269. package/node_modules/@earendil-works/pi-ai/dist/providers/data/minimax.json +1 -1
  270. package/node_modules/@earendil-works/pi-ai/dist/providers/data/mistral.json +1 -1
  271. package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
  272. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai-codex.json +1 -1
  273. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai.json +1 -1
  274. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
  275. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  276. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opengateway.json +1 -1
  277. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  278. package/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan-cn.json +1 -1
  279. package/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan.json +1 -1
  280. package/node_modules/@earendil-works/pi-ai/dist/providers/data/together.json +1 -1
  281. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  282. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai-coding-cn.json +1 -1
  283. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai.json +1 -1
  284. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts.map +1 -1
  285. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +4 -0
  286. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
  287. package/node_modules/@earendil-works/pi-ai/package.json +5 -5
  288. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  289. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  290. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +5 -0
  291. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
  292. package/node_modules/@earendil-works/pi-tui/dist/terminal.js +90 -1
  293. package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
  294. package/node_modules/@earendil-works/pi-tui/dist/tui.js +1 -1
  295. package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
  296. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  297. package/package.json +7 -7
@@ -1,7 +1,7 @@
1
1
  import { join } from "node:path";
2
2
  import { getAgentDir } from "../../../config.js";
3
3
  import { AuthStorage } from "../../../core/auth-storage.js";
4
- import { getProviderAccounts, pinProviderAccount, removeProviderAccount, } from "../../../core/extensions/builtin/claude-sdk-oauth/account-management.js";
4
+ import { getCredentialAccounts, pinCredentialAccount, removeCredentialAccount, } from "../../../core/credential-accounts.js";
5
5
  import { resolvePath } from "../../../utils/paths.js";
6
6
  import { RpcHandlerError } from "../rpc/errors.js";
7
7
  const RATE_LIMITS_AUTHENTICATION_MESSAGE = "codex account authentication required to read rate limits";
@@ -23,7 +23,7 @@ export function registerAppServerAccountMethods(registry, options = {}) {
23
23
  scope: "global",
24
24
  handler: async ({ request }) => {
25
25
  const params = parseProviderAccountsPinParams(request.params);
26
- await pinProviderAccount(AuthStorage.create(join(agentDir, "auth.json")), params.provider, params.name);
26
+ await pinCredentialAccount(AuthStorage.create(join(agentDir, "auth.json")), params.provider, params.name);
27
27
  return {};
28
28
  },
29
29
  });
@@ -31,7 +31,7 @@ export function registerAppServerAccountMethods(registry, options = {}) {
31
31
  scope: "global",
32
32
  handler: async ({ request }) => {
33
33
  const params = parseProviderAccountsRemoveParams(request.params);
34
- await removeProviderAccount(AuthStorage.create(join(agentDir, "auth.json")), params.provider, params.name);
34
+ await removeCredentialAccount(AuthStorage.create(join(agentDir, "auth.json")), params.provider, params.name);
35
35
  return {};
36
36
  },
37
37
  });
@@ -64,9 +64,9 @@ function accountReadResponse(agentDir) {
64
64
  requiresOpenaiAuth: false,
65
65
  };
66
66
  }
67
- function providerAccountsResponse(agentDir, params) {
67
+ async function providerAccountsResponse(agentDir, params) {
68
68
  const storage = AuthStorage.create(join(agentDir, "auth.json"));
69
- return { provider: params.provider, accounts: getProviderAccounts(storage, params.provider) };
69
+ return { provider: params.provider, accounts: await getCredentialAccounts(storage, params.provider) };
70
70
  }
71
71
  function parseAccountReadParams(value) {
72
72
  if (value === undefined || value === null)
@@ -1 +1 @@
1
- {"version":3,"file":"account.js","sourceRoot":"","sources":["../../../../src/modes/app-server/server/account.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { getAgentDir } from \"../../../config.ts\";\nimport { AuthStorage } from \"../../../core/auth-storage.ts\";\nimport type { ProviderAccountEvent } from \"../../../core/extensions/builtin/claude-sdk-oauth/account-events.ts\";\nimport {\n\tgetProviderAccounts,\n\tpinProviderAccount,\n\tremoveProviderAccount,\n} from \"../../../core/extensions/builtin/claude-sdk-oauth/account-management.ts\";\nimport { resolvePath } from \"../../../utils/paths.ts\";\nimport type {\n\tAccountReadParams,\n\tAccountReadResponse,\n\tProviderAccountsPinParams,\n\tProviderAccountsReadParams,\n\tProviderAccountsReadResponse,\n\tProviderAccountsRemoveParams,\n} from \"../protocol/account.ts\";\nimport type { RpcNotification } from \"../rpc/envelope.ts\";\nimport { RpcHandlerError } from \"../rpc/errors.ts\";\nimport type { MethodRegistry } from \"../rpc/registry.ts\";\n\nexport interface RegisterAppServerAccountMethodsOptions {\n\treadonly agentDir?: string;\n}\n\nconst RATE_LIMITS_AUTHENTICATION_MESSAGE = \"codex account authentication required to read rate limits\";\nconst TOKEN_USAGE_AUTHENTICATION_MESSAGE = \"codex account authentication required to read token usage\";\n\nexport function registerAppServerAccountMethods(\n\tregistry: MethodRegistry,\n\toptions: RegisterAppServerAccountMethodsOptions = {},\n): void {\n\tconst agentDir = resolvePath(options.agentDir ?? getAgentDir());\n\n\tregistry.register(\"account/read\", {\n\t\tscope: \"global\",\n\t\thandler: ({ request }) => {\n\t\t\tparseAccountReadParams(request.params);\n\t\t\treturn accountReadResponse(agentDir);\n\t\t},\n\t});\n\tregistry.register(\"account/providerAccounts/read\", {\n\t\tscope: \"global\",\n\t\thandler: ({ request }) => providerAccountsResponse(agentDir, parseProviderAccountsReadParams(request.params)),\n\t});\n\tregistry.register(\"account/providerAccounts/pin\", {\n\t\tscope: \"global\",\n\t\thandler: async ({ request }) => {\n\t\t\tconst params = parseProviderAccountsPinParams(request.params);\n\t\t\tawait pinProviderAccount(AuthStorage.create(join(agentDir, \"auth.json\")), params.provider, params.name);\n\t\t\treturn {};\n\t\t},\n\t});\n\tregistry.register(\"account/providerAccounts/remove\", {\n\t\tscope: \"global\",\n\t\thandler: async ({ request }) => {\n\t\t\tconst params = parseProviderAccountsRemoveParams(request.params);\n\t\t\tawait removeProviderAccount(AuthStorage.create(join(agentDir, \"auth.json\")), params.provider, params.name);\n\t\t\treturn {};\n\t\t},\n\t});\n\tregistry.register(\"account/rateLimits/read\", {\n\t\tscope: \"global\",\n\t\thandler: () => {\n\t\t\tthrow unauthenticatedAccountReadError(RATE_LIMITS_AUTHENTICATION_MESSAGE);\n\t\t},\n\t});\n\tregistry.register(\"account/usage/read\", {\n\t\tscope: \"global\",\n\t\thandler: () => {\n\t\t\tthrow unauthenticatedAccountReadError(TOKEN_USAGE_AUTHENTICATION_MESSAGE);\n\t\t},\n\t});\n}\n\nexport function providerAccountEventNotification(event: ProviderAccountEvent): RpcNotification {\n\tif (event.type === \"accounts_changed\") {\n\t\treturn { method: \"account/providerAccounts/updated\", params: { provider: event.provider } };\n\t}\n\treturn {\n\t\tmethod: \"account/providerAccounts/failover\",\n\t\tparams: { provider: event.provider, from: event.from, to: event.to, reason: event.reason },\n\t};\n}\n\nfunction accountReadResponse(agentDir: string): AccountReadResponse {\n\tconst credentials = AuthStorage.create(join(agentDir, \"auth.json\")).getAll();\n\treturn {\n\t\taccount: Object.keys(credentials).length > 0 ? { type: \"apiKey\" } : null,\n\t\trequiresOpenaiAuth: false,\n\t};\n}\n\nfunction providerAccountsResponse(agentDir: string, params: ProviderAccountsReadParams): ProviderAccountsReadResponse {\n\tconst storage = AuthStorage.create(join(agentDir, \"auth.json\"));\n\treturn { provider: params.provider, accounts: getProviderAccounts(storage, params.provider) };\n}\n\nfunction parseAccountReadParams(value: unknown): AccountReadParams {\n\tif (value === undefined || value === null) return {};\n\tif (!isRecord(value)) {\n\t\tthrow new RpcHandlerError({ code: -32600, message: \"account/read params must be an object\" });\n\t}\n\tconst refreshToken = value.refreshToken;\n\tif (refreshToken !== undefined && typeof refreshToken !== \"boolean\") {\n\t\tthrow new RpcHandlerError({ code: -32600, message: \"account/read refreshToken must be a boolean\" });\n\t}\n\treturn refreshToken === undefined ? {} : { refreshToken };\n}\n\nfunction parseProviderAccountsReadParams(value: unknown): ProviderAccountsReadParams {\n\treturn { provider: providerFrom(value, \"account/providerAccounts/read\") };\n}\n\nfunction parseProviderAccountsPinParams(value: unknown): ProviderAccountsPinParams {\n\tconst params = requiredRecord(value, \"account/providerAccounts/pin\");\n\tif (typeof params.name !== \"string\" && params.name !== null) {\n\t\tthrow invalidParams(\"account/providerAccounts/pin name must be a string or null\");\n\t}\n\treturn { provider: requiredProvider(params, \"account/providerAccounts/pin\"), name: params.name };\n}\n\nfunction parseProviderAccountsRemoveParams(value: unknown): ProviderAccountsRemoveParams {\n\tconst params = requiredRecord(value, \"account/providerAccounts/remove\");\n\tif (typeof params.name !== \"string\" || params.name.length === 0) {\n\t\tthrow invalidParams(\"account/providerAccounts/remove name must be a non-empty string\");\n\t}\n\treturn { provider: requiredProvider(params, \"account/providerAccounts/remove\"), name: params.name };\n}\n\nfunction providerFrom(value: unknown, method: string): string {\n\treturn requiredProvider(requiredRecord(value, method), method);\n}\n\nfunction requiredProvider(params: Record<string, unknown>, method: string): string {\n\tif (typeof params.provider !== \"string\" || params.provider.length === 0) {\n\t\tthrow invalidParams(`${method} provider must be a non-empty string`);\n\t}\n\treturn params.provider;\n}\n\nfunction requiredRecord(value: unknown, method: string): Record<string, unknown> {\n\tif (!isRecord(value)) throw invalidParams(`${method} params must be an object`);\n\treturn value;\n}\n\nfunction invalidParams(message: string): RpcHandlerError {\n\treturn new RpcHandlerError({ code: -32600, message });\n}\n\nfunction unauthenticatedAccountReadError(message: string): RpcHandlerError {\n\treturn new RpcHandlerError({ code: -32600, message });\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"]}
1
+ {"version":3,"file":"account.js","sourceRoot":"","sources":["../../../../src/modes/app-server/server/account.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EACN,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,GACvB,MAAM,sCAAsC,CAAC;AAE9C,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAUtD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAOnD,MAAM,kCAAkC,GAAG,2DAA2D,CAAC;AACvG,MAAM,kCAAkC,GAAG,2DAA2D,CAAC;AAEvG,MAAM,UAAU,+BAA+B,CAC9C,QAAwB,EACxB,UAAkD,EAAE;IAEpD,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,QAAQ,IAAI,WAAW,EAAE,CAAC,CAAC;IAEhE,QAAQ,CAAC,QAAQ,CAAC,cAAc,EAAE;QACjC,KAAK,EAAE,QAAQ;QACf,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;YACxB,sBAAsB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YACvC,OAAO,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QACtC,CAAC;KACD,CAAC,CAAC;IACH,QAAQ,CAAC,QAAQ,CAAC,+BAA+B,EAAE;QAClD,KAAK,EAAE,QAAQ;QACf,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,wBAAwB,CAAC,QAAQ,EAAE,+BAA+B,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;KAC7G,CAAC,CAAC;IACH,QAAQ,CAAC,QAAQ,CAAC,8BAA8B,EAAE;QACjD,KAAK,EAAE,QAAQ;QACf,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;YAC9B,MAAM,MAAM,GAAG,8BAA8B,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC9D,MAAM,oBAAoB,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;YAC1G,OAAO,EAAE,CAAC;QACX,CAAC;KACD,CAAC,CAAC;IACH,QAAQ,CAAC,QAAQ,CAAC,iCAAiC,EAAE;QACpD,KAAK,EAAE,QAAQ;QACf,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;YAC9B,MAAM,MAAM,GAAG,iCAAiC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YACjE,MAAM,uBAAuB,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;YAC7G,OAAO,EAAE,CAAC;QACX,CAAC;KACD,CAAC,CAAC;IACH,QAAQ,CAAC,QAAQ,CAAC,yBAAyB,EAAE;QAC5C,KAAK,EAAE,QAAQ;QACf,OAAO,EAAE,GAAG,EAAE;YACb,MAAM,+BAA+B,CAAC,kCAAkC,CAAC,CAAC;QAC3E,CAAC;KACD,CAAC,CAAC;IACH,QAAQ,CAAC,QAAQ,CAAC,oBAAoB,EAAE;QACvC,KAAK,EAAE,QAAQ;QACf,OAAO,EAAE,GAAG,EAAE;YACb,MAAM,+BAA+B,CAAC,kCAAkC,CAAC,CAAC;QAC3E,CAAC;KACD,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gCAAgC,CAAC,KAA2B;IAC3E,IAAI,KAAK,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;QACvC,OAAO,EAAE,MAAM,EAAE,kCAAkC,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC;IAC7F,CAAC;IACD,OAAO;QACN,MAAM,EAAE,mCAAmC;QAC3C,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;KAC1F,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAAC,QAAgB;IAC5C,MAAM,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC7E,OAAO;QACN,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI;QACxE,kBAAkB,EAAE,KAAK;KACzB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,wBAAwB,CACtC,QAAgB,EAChB,MAAkC;IAElC,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC;IAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;AACvG,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAc;IAC7C,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC;IACrD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,uCAAuC,EAAE,CAAC,CAAC;IAC/F,CAAC;IACD,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;IACxC,IAAI,YAAY,KAAK,SAAS,IAAI,OAAO,YAAY,KAAK,SAAS,EAAE,CAAC;QACrE,MAAM,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,6CAA6C,EAAE,CAAC,CAAC;IACrG,CAAC;IACD,OAAO,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC;AAC3D,CAAC;AAED,SAAS,+BAA+B,CAAC,KAAc;IACtD,OAAO,EAAE,QAAQ,EAAE,YAAY,CAAC,KAAK,EAAE,+BAA+B,CAAC,EAAE,CAAC;AAC3E,CAAC;AAED,SAAS,8BAA8B,CAAC,KAAc;IACrD,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,8BAA8B,CAAC,CAAC;IACrE,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;QAC7D,MAAM,aAAa,CAAC,4DAA4D,CAAC,CAAC;IACnF,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,gBAAgB,CAAC,MAAM,EAAE,8BAA8B,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;AAClG,CAAC;AAED,SAAS,iCAAiC,CAAC,KAAc;IACxD,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,iCAAiC,CAAC,CAAC;IACxE,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjE,MAAM,aAAa,CAAC,iEAAiE,CAAC,CAAC;IACxF,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,gBAAgB,CAAC,MAAM,EAAE,iCAAiC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;AACrG,CAAC;AAED,SAAS,YAAY,CAAC,KAAc,EAAE,MAAc;IACnD,OAAO,gBAAgB,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,gBAAgB,CAAC,MAA+B,EAAE,MAAc;IACxE,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzE,MAAM,aAAa,CAAC,GAAG,MAAM,sCAAsC,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,CAAC;AACxB,CAAC;AAED,SAAS,cAAc,CAAC,KAAc,EAAE,MAAc;IACrD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,MAAM,aAAa,CAAC,GAAG,MAAM,2BAA2B,CAAC,CAAC;IAChF,OAAO,KAAK,CAAC;AACd,CAAC;AAED,SAAS,aAAa,CAAC,OAAe;IACrC,OAAO,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,+BAA+B,CAAC,OAAe;IACvD,OAAO,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC/B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC7E,CAAC","sourcesContent":["import { join } from \"node:path\";\nimport { getAgentDir } from \"../../../config.ts\";\nimport { AuthStorage } from \"../../../core/auth-storage.ts\";\nimport {\n\tgetCredentialAccounts,\n\tpinCredentialAccount,\n\tremoveCredentialAccount,\n} from \"../../../core/credential-accounts.ts\";\nimport type { ProviderAccountEvent } from \"../../../core/extensions/builtin/claude-sdk-oauth/account-events.ts\";\nimport { resolvePath } from \"../../../utils/paths.ts\";\nimport type {\n\tAccountReadParams,\n\tAccountReadResponse,\n\tProviderAccountsPinParams,\n\tProviderAccountsReadParams,\n\tProviderAccountsReadResponse,\n\tProviderAccountsRemoveParams,\n} from \"../protocol/account.ts\";\nimport type { RpcNotification } from \"../rpc/envelope.ts\";\nimport { RpcHandlerError } from \"../rpc/errors.ts\";\nimport type { MethodRegistry } from \"../rpc/registry.ts\";\n\nexport interface RegisterAppServerAccountMethodsOptions {\n\treadonly agentDir?: string;\n}\n\nconst RATE_LIMITS_AUTHENTICATION_MESSAGE = \"codex account authentication required to read rate limits\";\nconst TOKEN_USAGE_AUTHENTICATION_MESSAGE = \"codex account authentication required to read token usage\";\n\nexport function registerAppServerAccountMethods(\n\tregistry: MethodRegistry,\n\toptions: RegisterAppServerAccountMethodsOptions = {},\n): void {\n\tconst agentDir = resolvePath(options.agentDir ?? getAgentDir());\n\n\tregistry.register(\"account/read\", {\n\t\tscope: \"global\",\n\t\thandler: ({ request }) => {\n\t\t\tparseAccountReadParams(request.params);\n\t\t\treturn accountReadResponse(agentDir);\n\t\t},\n\t});\n\tregistry.register(\"account/providerAccounts/read\", {\n\t\tscope: \"global\",\n\t\thandler: ({ request }) => providerAccountsResponse(agentDir, parseProviderAccountsReadParams(request.params)),\n\t});\n\tregistry.register(\"account/providerAccounts/pin\", {\n\t\tscope: \"global\",\n\t\thandler: async ({ request }) => {\n\t\t\tconst params = parseProviderAccountsPinParams(request.params);\n\t\t\tawait pinCredentialAccount(AuthStorage.create(join(agentDir, \"auth.json\")), params.provider, params.name);\n\t\t\treturn {};\n\t\t},\n\t});\n\tregistry.register(\"account/providerAccounts/remove\", {\n\t\tscope: \"global\",\n\t\thandler: async ({ request }) => {\n\t\t\tconst params = parseProviderAccountsRemoveParams(request.params);\n\t\t\tawait removeCredentialAccount(AuthStorage.create(join(agentDir, \"auth.json\")), params.provider, params.name);\n\t\t\treturn {};\n\t\t},\n\t});\n\tregistry.register(\"account/rateLimits/read\", {\n\t\tscope: \"global\",\n\t\thandler: () => {\n\t\t\tthrow unauthenticatedAccountReadError(RATE_LIMITS_AUTHENTICATION_MESSAGE);\n\t\t},\n\t});\n\tregistry.register(\"account/usage/read\", {\n\t\tscope: \"global\",\n\t\thandler: () => {\n\t\t\tthrow unauthenticatedAccountReadError(TOKEN_USAGE_AUTHENTICATION_MESSAGE);\n\t\t},\n\t});\n}\n\nexport function providerAccountEventNotification(event: ProviderAccountEvent): RpcNotification {\n\tif (event.type === \"accounts_changed\") {\n\t\treturn { method: \"account/providerAccounts/updated\", params: { provider: event.provider } };\n\t}\n\treturn {\n\t\tmethod: \"account/providerAccounts/failover\",\n\t\tparams: { provider: event.provider, from: event.from, to: event.to, reason: event.reason },\n\t};\n}\n\nfunction accountReadResponse(agentDir: string): AccountReadResponse {\n\tconst credentials = AuthStorage.create(join(agentDir, \"auth.json\")).getAll();\n\treturn {\n\t\taccount: Object.keys(credentials).length > 0 ? { type: \"apiKey\" } : null,\n\t\trequiresOpenaiAuth: false,\n\t};\n}\n\nasync function providerAccountsResponse(\n\tagentDir: string,\n\tparams: ProviderAccountsReadParams,\n): Promise<ProviderAccountsReadResponse> {\n\tconst storage = AuthStorage.create(join(agentDir, \"auth.json\"));\n\treturn { provider: params.provider, accounts: await getCredentialAccounts(storage, params.provider) };\n}\n\nfunction parseAccountReadParams(value: unknown): AccountReadParams {\n\tif (value === undefined || value === null) return {};\n\tif (!isRecord(value)) {\n\t\tthrow new RpcHandlerError({ code: -32600, message: \"account/read params must be an object\" });\n\t}\n\tconst refreshToken = value.refreshToken;\n\tif (refreshToken !== undefined && typeof refreshToken !== \"boolean\") {\n\t\tthrow new RpcHandlerError({ code: -32600, message: \"account/read refreshToken must be a boolean\" });\n\t}\n\treturn refreshToken === undefined ? {} : { refreshToken };\n}\n\nfunction parseProviderAccountsReadParams(value: unknown): ProviderAccountsReadParams {\n\treturn { provider: providerFrom(value, \"account/providerAccounts/read\") };\n}\n\nfunction parseProviderAccountsPinParams(value: unknown): ProviderAccountsPinParams {\n\tconst params = requiredRecord(value, \"account/providerAccounts/pin\");\n\tif (typeof params.name !== \"string\" && params.name !== null) {\n\t\tthrow invalidParams(\"account/providerAccounts/pin name must be a string or null\");\n\t}\n\treturn { provider: requiredProvider(params, \"account/providerAccounts/pin\"), name: params.name };\n}\n\nfunction parseProviderAccountsRemoveParams(value: unknown): ProviderAccountsRemoveParams {\n\tconst params = requiredRecord(value, \"account/providerAccounts/remove\");\n\tif (typeof params.name !== \"string\" || params.name.length === 0) {\n\t\tthrow invalidParams(\"account/providerAccounts/remove name must be a non-empty string\");\n\t}\n\treturn { provider: requiredProvider(params, \"account/providerAccounts/remove\"), name: params.name };\n}\n\nfunction providerFrom(value: unknown, method: string): string {\n\treturn requiredProvider(requiredRecord(value, method), method);\n}\n\nfunction requiredProvider(params: Record<string, unknown>, method: string): string {\n\tif (typeof params.provider !== \"string\" || params.provider.length === 0) {\n\t\tthrow invalidParams(`${method} provider must be a non-empty string`);\n\t}\n\treturn params.provider;\n}\n\nfunction requiredRecord(value: unknown, method: string): Record<string, unknown> {\n\tif (!isRecord(value)) throw invalidParams(`${method} params must be an object`);\n\treturn value;\n}\n\nfunction invalidParams(message: string): RpcHandlerError {\n\treturn new RpcHandlerError({ code: -32600, message });\n}\n\nfunction unauthenticatedAccountReadError(message: string): RpcHandlerError {\n\treturn new RpcHandlerError({ code: -32600, message });\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"]}
@@ -4,6 +4,7 @@
4
4
  export { InteractiveMode, type InteractiveModeOptions } from "./interactive/interactive-mode.ts";
5
5
  export type { JsonAgentSessionEvent } from "./json-event.ts";
6
6
  export { type PrintModeOptions, runPrintMode } from "./print-mode.ts";
7
+ export { createHostDaemonPaths, type EnsuredHost, type EnsureHostOptions, ensureHost, type HostDaemonPaths, PINNED_HOST_CLIENT_CAPABILITIES, } from "./rpc/host-ensure.ts";
7
8
  export { type ModelInfo, RpcClient, type RpcClientEvent, type RpcClientOptions, type RpcEventListener, } from "./rpc/rpc-client.ts";
8
9
  export { runRpcMode } from "./rpc/rpc-mode.ts";
9
10
  export type { RpcCommand, RpcExtensionEvent, RpcExtensionUIRequest, RpcExtensionUIResponse, RpcResponse, RpcSessionState, } from "./rpc/rpc-types.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/modes/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AACjG,YAAY,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,KAAK,gBAAgB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EACN,KAAK,SAAS,EACd,SAAS,EACT,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,YAAY,EACX,UAAU,EACV,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,WAAW,EACX,eAAe,GACf,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/modes/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AACjG,YAAY,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,KAAK,gBAAgB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EACN,qBAAqB,EACrB,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,UAAU,EACV,KAAK,eAAe,EACpB,+BAA+B,GAC/B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACN,KAAK,SAAS,EACd,SAAS,EACT,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,YAAY,EACX,UAAU,EACV,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,WAAW,EACX,eAAe,GACf,MAAM,oBAAoB,CAAC"}
@@ -3,6 +3,7 @@
3
3
  */
4
4
  export { InteractiveMode } from "./interactive/interactive-mode.js";
5
5
  export { runPrintMode } from "./print-mode.js";
6
+ export { createHostDaemonPaths, ensureHost, PINNED_HOST_CLIENT_CAPABILITIES, } from "./rpc/host-ensure.js";
6
7
  export { RpcClient, } from "./rpc/rpc-client.js";
7
8
  export { runRpcMode } from "./rpc/rpc-mode.js";
8
9
  //# sourceMappingURL=index.js.map
@@ -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,11 +1,19 @@
1
+ import type { Credential } from "@earendil-works/pi-ai";
1
2
  import { type Component } from "@earendil-works/pi-tui";
2
- import type { AgentSession } from "../../../core/agent-session.ts";
3
3
  import type { ReadonlyFooterDataProvider } from "../../../core/footer-data-provider.ts";
4
+ import type { InteractiveSession } from "../interactive-host-runtime.ts";
4
5
  /**
5
6
  * Format token counts for footer display using oh-my-pi-style K/M/B abbreviation.
6
7
  * Examples: "999", "6.8K", "546K", "1M", "1.5M", "2B".
7
8
  */
8
9
  export declare function formatTokens(count: number): string;
10
+ /**
11
+ * Mirrors the provider-shown-only-when->1 rule for accounts: the active account
12
+ * name appears only when the provider actually pools more than one slot. The
13
+ * pick shown is the pin when present, else the session's HRW winner - the same
14
+ * hash the rotation engine uses, so the footer names the slot that will serve.
15
+ */
16
+ export declare function accountFooterSuffix(credential: Credential | undefined, sessionId: string): string;
9
17
  export declare function formatCwdForFooter(cwd: string, home: string | undefined): string;
10
18
  /**
11
19
  * Footer component that shows pwd, token stats, and context usage.
@@ -15,8 +23,8 @@ export declare class FooterComponent implements Component {
15
23
  private session;
16
24
  private footerData;
17
25
  private autoCompactEnabled;
18
- constructor(session: AgentSession, footerData: ReadonlyFooterDataProvider);
19
- setSession(session: AgentSession): void;
26
+ constructor(session: InteractiveSession, footerData: ReadonlyFooterDataProvider);
27
+ setSession(session: InteractiveSession): void;
20
28
  setAutoCompactEnabled(enabled: boolean): void;
21
29
  /**
22
30
  * No-op: git branch caching now handled by provider.
@@ -1 +1 @@
1
- {"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/footer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAiC,MAAM,wBAAwB,CAAC;AACvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAC;AAkBxF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CASlD;AAQD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAYhF;AAkBD;;;GAGG;AACH,qBAAa,eAAgB,YAAW,SAAS;IAChD,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,kBAAkB,CAAQ;gBAEtB,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,0BAA0B;IAKzE,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAIvC,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAI7C;;;OAGG;IACH,UAAU,IAAI,IAAI;IAIlB;;;OAGG;IACH,OAAO,IAAI,IAAI;IAIf,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAsJ/B"}
1
+ {"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/footer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,EAAE,KAAK,SAAS,EAAiC,MAAM,wBAAwB,CAAC;AACvF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAC;AACxF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAkBzE;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CASlD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CASjG;AAQD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAYhF;AAkBD;;;GAGG;AACH,qBAAa,eAAgB,YAAW,SAAS;IAChD,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,kBAAkB,CAAQ;gBAEtB,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,0BAA0B;IAK/E,UAAU,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI;IAI7C,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAI7C;;;OAGG;IACH,UAAU,IAAI,IAAI;IAIlB;;;OAGG;IACH,OAAO,IAAI,IAAI;IAIf,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAmK/B"}
@@ -1,4 +1,7 @@
1
+ import { createHash } from "node:crypto";
1
2
  import { isAbsolute, relative, resolve, sep } from "node:path";
3
+ import { rendezvousOrder } from "@earendil-works/pi-ai/auth/pool/select";
4
+ import { listSlots } from "@earendil-works/pi-ai/auth/pool/slots";
2
5
  import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
3
6
  import { theme } from "../theme/theme.js";
4
7
  import { planFooterLayout } from "./footer-layout.js";
@@ -34,6 +37,22 @@ export function formatTokens(count) {
34
37
  return `${trim1(n / 1_000_000_000)}B`;
35
38
  return `${Math.round(n / 1_000_000_000)}B`;
36
39
  }
40
+ /**
41
+ * Mirrors the provider-shown-only-when->1 rule for accounts: the active account
42
+ * name appears only when the provider actually pools more than one slot. The
43
+ * pick shown is the pin when present, else the session's HRW winner - the same
44
+ * hash the rotation engine uses, so the footer names the slot that will serve.
45
+ */
46
+ export function accountFooterSuffix(credential, sessionId) {
47
+ const slots = listSlots(credential);
48
+ if (slots.length < 2)
49
+ return "";
50
+ const pinned = Object.entries(credential ?? {}).find(([key]) => key === "pinned")?.[1];
51
+ if (typeof pinned === "string" && slots.some((slot) => slot.name === pinned))
52
+ return `@${pinned}`;
53
+ const winner = rendezvousOrder(sessionId, slots, (input) => createHash("sha256").update(input).digest().readBigUInt64BE(0))[0];
54
+ return winner === undefined ? "" : `@${winner.name}`;
55
+ }
37
56
  /** Format with up to 1 decimal place, dropping trailing `.0`. */
38
57
  function trim1(n) {
39
58
  const s = n.toFixed(1);
@@ -165,7 +184,18 @@ export class FooterComponent {
165
184
  minimalRight = thinkingLevel === "off" ? `${minimalRight}:off` : `${minimalRight}:${thinkingLevel}`;
166
185
  }
167
186
  const minimal = { plain: minimalRight, colored: colorRightSide(minimalRight) };
168
- const providerPrefix = this.footerData.getAvailableProviderCount() > 1 && state.model ? `(${state.model.provider}) ` : "";
187
+ let accountSuffix = "";
188
+ if (state.model) {
189
+ try {
190
+ accountSuffix = accountFooterSuffix(this.session.modelRegistry.authStorage.get(state.model.provider), this.session.sessionManager.getSessionId());
191
+ }
192
+ catch {
193
+ // The footer must render even when credential storage is unreadable.
194
+ }
195
+ }
196
+ const providerPrefix = (this.footerData.getAvailableProviderCount() > 1 || accountSuffix !== "") && state.model
197
+ ? `(${state.model.provider}${accountSuffix}) `
198
+ : "";
169
199
  const full = providerPrefix
170
200
  ? { plain: `${providerPrefix}${minimalRight}`, colored: colorRightSide(`${providerPrefix}${minimalRight}`) }
171
201
  : undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"footer.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/footer.ts"],"names":[],"mappings":"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","sourcesContent":["import { isAbsolute, relative, resolve, sep } from \"node:path\";\nimport { type Component, truncateToWidth, visibleWidth } from \"@earendil-works/pi-tui\";\nimport type { AgentSession } from \"../../../core/agent-session.ts\";\nimport type { ReadonlyFooterDataProvider } from \"../../../core/footer-data-provider.ts\";\nimport { theme } from \"../theme/theme.ts\";\nimport { type FooterSegment, planFooterLayout } from \"./footer-layout.ts\";\n\nconst FAST_MODE_INDICATOR = \"\\u26a1 \";\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 for footer display using oh-my-pi-style K/M/B abbreviation.\n * Examples: \"999\", \"6.8K\", \"546K\", \"1M\", \"1.5M\", \"2B\".\n */\nexport function formatTokens(count: number): string {\n\tconst n = Math.round(count);\n\tif (n < 1_000) return n.toString();\n\tif (n < 10_000) return `${trim1(n / 1_000)}K`;\n\tif (n < 1_000_000) return `${Math.round(n / 1_000)}K`;\n\tif (n < 10_000_000) return `${trim1(n / 1_000_000)}M`;\n\tif (n < 1_000_000_000) return `${Math.round(n / 1_000_000)}M`;\n\tif (n < 10_000_000_000) return `${trim1(n / 1_000_000_000)}B`;\n\treturn `${Math.round(n / 1_000_000_000)}B`;\n}\n\n/** Format with up to 1 decimal place, dropping trailing `.0`. */\nfunction trim1(n: number): string {\n\tconst s = n.toFixed(1);\n\treturn s.endsWith(\".0\") ? s.slice(0, -2) : s;\n}\n\nexport function formatCwdForFooter(cwd: string, home: string | undefined): string {\n\tif (!home) return cwd;\n\n\tconst resolvedCwd = resolve(cwd);\n\tconst resolvedHome = resolve(home);\n\tconst relativeToHome = relative(resolvedHome, resolvedCwd);\n\tconst isInsideHome =\n\t\trelativeToHome === \"\" ||\n\t\t(relativeToHome !== \"..\" && !relativeToHome.startsWith(`..${sep}`) && !isAbsolute(relativeToHome));\n\n\tif (!isInsideHome) return cwd;\n\treturn relativeToHome === \"\" ? \"~\" : `~${sep}${relativeToHome}`;\n}\n\n/**\n * Color the right side of the footer: (provider) muted, model accent, :thinking dim.\n * The text is the plain (uncolored) right-aligned segment from the layout pass.\n */\nfunction colorRightSide(text: string): string {\n\tif (!text) return \"\";\n\tconst providerMatch = text.match(/^\\(([^)]+)\\) (.*)$/);\n\tconst afterProvider = providerMatch ? providerMatch[2] : text;\n\tconst providerPrefix = providerMatch ? theme.fg(\"muted\", `(${providerMatch[1]}) `) : \"\";\n\tconst fastPrefix = afterProvider.startsWith(FAST_MODE_INDICATOR) ? theme.fg(\"warning\", FAST_MODE_INDICATOR) : \"\";\n\tconst body = fastPrefix ? afterProvider.slice(FAST_MODE_INDICATOR.length) : afterProvider;\n\tconst thinkingMatch = body.match(/^(.+):([^:]+)$/);\n\tif (!thinkingMatch) return providerPrefix + fastPrefix + theme.fg(\"accent\", body);\n\treturn `${providerPrefix}${fastPrefix}${theme.fg(\"accent\", thinkingMatch[1])}${theme.fg(\"dim\", `:${thinkingMatch[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 session: AgentSession;\n\tprivate footerData: ReadonlyFooterDataProvider;\n\tprivate autoCompactEnabled = true;\n\n\tconstructor(session: AgentSession, footerData: ReadonlyFooterDataProvider) {\n\t\tthis.session = session;\n\t\tthis.footerData = footerData;\n\t}\n\n\tsetSession(session: AgentSession): void {\n\t\tthis.session = session;\n\t}\n\n\tsetAutoCompactEnabled(enabled: boolean): void {\n\t\tthis.autoCompactEnabled = enabled;\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\t// O(1) running totals maintained by SessionManager (identical to summing\n\t\t// usage over all entries; totals are not branch-scoped).\n\t\tconst usageTotals = this.session.sessionManager.getUsageTotals();\n\t\tconst totalCacheRead = usageTotals.cacheRead;\n\t\tconst totalCacheWrite = usageTotals.cacheWrite;\n\t\tconst totalCost = usageTotals.cost;\n\t\tconst latestCacheHitRate = usageTotals.latestCacheHitRate;\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 contextWindow = contextUsage?.contextWindow ?? state.model?.contextWindow ?? 0;\n\t\tconst contextPercentValue = contextUsage?.percent ?? 0;\n\t\tconst contextPercent = contextUsage?.percent !== null ? contextPercentValue.toFixed(1) : \"?\";\n\t\tconst contextTokens =\n\t\t\ttypeof contextUsage?.tokens === \"number\"\n\t\t\t\t? formatTokens(contextUsage.tokens)\n\t\t\t\t: typeof contextUsage?.percent === \"number\"\n\t\t\t\t\t? formatTokens(Math.round((contextWindow * contextUsage.percent) / 100))\n\t\t\t\t\t: \"?\";\n\n\t\t// Segments in priority order: anchors (pwd, branch, context) and the model\n\t\t// label always stay; middle stats elide from the right when space runs out.\n\t\t// The width ladder itself lives in ./footer-layout.ts.\n\t\tconst separator = \" • \";\n\t\tconst sepColored = theme.fg(\"borderMuted\", separator);\n\t\tconst pwdRaw = formatCwdForFooter(\n\t\t\tthis.session.sessionManager.getCwd(),\n\t\t\tprocess.env.HOME || process.env.USERPROFILE,\n\t\t);\n\t\tconst branch = this.footerData.getGitBranch();\n\t\tconst sessionName = this.session.sessionManager.getSessionName();\n\n\t\tconst anchor: [FooterSegment, ...FooterSegment[]] = [{ plain: pwdRaw, colored: theme.fg(\"accent\", pwdRaw) }];\n\t\tif (branch) anchor.push({ plain: branch, colored: theme.fg(\"warning\", branch) });\n\t\tconst pwdIndex = 0;\n\n\t\tconst dim = (plain: string): FooterSegment => ({ plain, colored: theme.fg(\"dim\", plain) });\n\t\tconst middle: FooterSegment[] = [];\n\t\tif (sessionName) middle.push({ plain: sessionName, colored: theme.fg(\"muted\", sessionName) });\n\t\tif ((totalCacheRead > 0 || totalCacheWrite > 0) && latestCacheHitRate !== undefined && latestCacheHitRate >= 10) {\n\t\t\tmiddle.push(dim(`CH${latestCacheHitRate.toFixed(1)}%`));\n\t\t}\n\n\t\t// Kimi Coding is subscription-backed despite using API-key authentication.\n\t\tconst usingSubscription = state.model\n\t\t\t? state.model.provider === \"kimi-coding\" || this.session.modelRuntime.isUsingSubscription(state.model.provider)\n\t\t\t: false;\n\t\tif (totalCost || usingSubscription) {\n\t\t\tconst costStr = `$${totalCost.toFixed(3)}${usingSubscription ? \" (sub)\" : \"\"}`;\n\t\t\tmiddle.push({ plain: costStr, colored: theme.fg(\"success\", costStr) });\n\t\t}\n\n\t\tconst autoIndicator = this.autoCompactEnabled ? \" (auto)\" : \"\";\n\t\tconst ctxDisplay =\n\t\t\tcontextPercent === \"?\"\n\t\t\t\t? `${contextTokens}/${formatTokens(contextWindow)} (?)${autoIndicator}`\n\t\t\t\t: `${contextTokens}/${formatTokens(contextWindow)} (${contextPercent}%)${autoIndicator}`;\n\t\tconst ctxColored =\n\t\t\tcontextPercentValue > 90\n\t\t\t\t? theme.fg(\"error\", ctxDisplay)\n\t\t\t\t: contextPercentValue > 70\n\t\t\t\t\t? theme.fg(\"warning\", ctxDisplay)\n\t\t\t\t\t: theme.fg(\"muted\", ctxDisplay);\n\t\tconst tail: FooterSegment = { plain: ctxDisplay, colored: ctxColored };\n\n\t\t// Model label pinned to the right edge; the provider prefix stays only when\n\t\t// the full line fits.\n\t\tconst modelName = state.model?.id || \"no-model\";\n\t\tconst fastIndicator = this.session.isFastModeActive() ? FAST_MODE_INDICATOR : \"\";\n\t\tlet minimalRight = `${fastIndicator}${modelName}`;\n\t\tif (state.model?.reasoning) {\n\t\t\tconst thinkingLevel = state.thinkingLevel || \"off\";\n\t\t\tminimalRight = thinkingLevel === \"off\" ? `${minimalRight}:off` : `${minimalRight}:${thinkingLevel}`;\n\t\t}\n\t\tconst minimal: FooterSegment = { plain: minimalRight, colored: colorRightSide(minimalRight) };\n\t\tconst providerPrefix =\n\t\t\tthis.footerData.getAvailableProviderCount() > 1 && state.model ? `(${state.model.provider}) ` : \"\";\n\t\tconst full: FooterSegment | undefined = providerPrefix\n\t\t\t? { plain: `${providerPrefix}${minimalRight}`, colored: colorRightSide(`${providerPrefix}${minimalRight}`) }\n\t\t\t: undefined;\n\n\t\tconst marker: FooterSegment = { plain: \"…\", colored: theme.fg(\"dim\", \"…\") };\n\t\tconst plan = planFooterLayout({\n\t\t\twidth,\n\t\t\tanchor,\n\t\t\tpwdIndex,\n\t\t\tmiddle,\n\t\t\ttail,\n\t\t\tright: { minimal, full },\n\t\t\tseparator,\n\t\t\tminPadding: 2,\n\t\t\tellipsisMarker: marker,\n\t\t});\n\n\t\tconst joinSegments = (segments: readonly FooterSegment[]): { colored: string; width: number } => ({\n\t\t\tcolored: segments.map((segment) => segment.colored).join(sepColored),\n\t\t\twidth: visibleWidth(segments.map((segment) => segment.plain).join(separator)),\n\t\t});\n\n\t\tlet left: { colored: string; width: number };\n\t\tlet right: FooterSegment;\n\t\tif (plan.kind === \"full\") {\n\t\t\tright = plan.useFullRight && full ? full : minimal;\n\t\t\tleft = joinSegments([...anchor, ...middle, tail]);\n\t\t} else if (plan.kind === \"middle-elided\") {\n\t\t\tright = plan.useFullRight && full ? full : minimal;\n\t\t\tconst segments = [...anchor, ...middle.slice(0, plan.keptMiddleCount)];\n\t\t\tif (plan.showMarker) segments.push(marker);\n\t\t\tsegments.push(tail);\n\t\t\tleft = joinSegments(segments);\n\t\t} else if (plan.kind === \"pwd-elided\") {\n\t\t\tright = plan.useFullRight && full ? full : minimal;\n\t\t\tconst segments: FooterSegment[] = [\n\t\t\t\t...anchor.map((segment, index) =>\n\t\t\t\t\tindex === pwdIndex ? { plain: plan.pwdPlain, colored: theme.fg(\"accent\", plan.pwdPlain) } : segment,\n\t\t\t\t),\n\t\t\t\t...middle.slice(0, plan.keptMiddleCount),\n\t\t\t];\n\t\t\tif (plan.showMarker) segments.push(marker);\n\t\t\tsegments.push(tail);\n\t\t\tleft = joinSegments(segments);\n\t\t} else if (plan.kind === \"left-elided\") {\n\t\t\tright = minimal;\n\t\t\tleft = { colored: theme.fg(\"muted\", plan.leftPlain), width: visibleWidth(plan.leftPlain) };\n\t\t} else {\n\t\t\tleft = { colored: \"\", width: 0 };\n\t\t\tright = { plain: plan.rightPlain, colored: colorRightSide(plan.rightPlain) };\n\t\t}\n\n\t\tconst rightWidth = visibleWidth(right.plain);\n\t\tconst padding = \" \".repeat(Math.max(0, width - left.width - rightWidth));\n\t\tconst lines = [left.colored + padding + right.colored];\n\n\t\t// Add extension statuses on a single line, sorted by key alphabetically\n\t\tconst extensionStatuses = this.footerData.getExtensionStatuses();\n\t\tif (extensionStatuses.size > 0) {\n\t\t\tconst sortedStatuses = Array.from(extensionStatuses.entries())\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// Truncate to terminal width with dim ellipsis for consistency with footer style\n\t\t\tlines.push(truncateToWidth(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":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAE/D,OAAO,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,MAAM,uCAAuC,CAAC;AAClE,OAAO,EAAkB,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAGvF,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAsB,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE1E,MAAM,mBAAmB,GAAG,SAAS,CAAC;AAEtC;;;GAGG;AACH,SAAS,kBAAkB,CAAC,IAAY;IACvC,qFAAqF;IACrF,OAAO,IAAI;SACT,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC;SACzB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,IAAI,EAAE,CAAC;AACV,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa;IACzC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC5B,IAAI,CAAC,GAAG,KAAK;QAAE,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC;IACnC,IAAI,CAAC,GAAG,MAAM;QAAE,OAAO,GAAG,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC;IAC9C,IAAI,CAAC,GAAG,SAAS;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC;IACtD,IAAI,CAAC,GAAG,UAAU;QAAE,OAAO,GAAG,KAAK,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC;IACtD,IAAI,CAAC,GAAG,aAAa;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC;IAC9D,IAAI,CAAC,GAAG,cAAc;QAAE,OAAO,GAAG,KAAK,CAAC,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC;IAC9D,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC;AAC5C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,UAAkC,EAAE,SAAiB;IACxF,MAAM,KAAK,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;IACpC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACvF,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;QAAE,OAAO,IAAI,MAAM,EAAE,CAAC;IAClG,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAC1D,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAC9D,CAAC,CAAC,CAAC,CAAC;IACL,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;AACtD,CAAC;AAED,iEAAiE;AACjE,SAAS,KAAK,CAAC,CAAS;IACvB,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACvB,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAW,EAAE,IAAwB;IACvE,IAAI,CAAC,IAAI;QAAE,OAAO,GAAG,CAAC;IAEtB,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,cAAc,GAAG,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IAC3D,MAAM,YAAY,GACjB,cAAc,KAAK,EAAE;QACrB,CAAC,cAAc,KAAK,IAAI,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC;IAEpG,IAAI,CAAC,YAAY;QAAE,OAAO,GAAG,CAAC;IAC9B,OAAO,cAAc,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,cAAc,EAAE,CAAC;AACjE,CAAC;AAED;;;GAGG;AACH,SAAS,cAAc,CAAC,IAAY;IACnC,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACvD,MAAM,aAAa,GAAG,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9D,MAAM,cAAc,GAAG,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACxF,MAAM,UAAU,GAAG,aAAa,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACjH,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;IAC1F,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACnD,IAAI,CAAC,aAAa;QAAE,OAAO,cAAc,GAAG,UAAU,GAAG,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAClF,OAAO,GAAG,cAAc,GAAG,UAAU,GAAG,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AAC1H,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,eAAe;IAK3B,YAAY,OAA2B,EAAE,UAAsC;QAFvE,uBAAkB,GAAG,IAAI,CAAC;QAGjC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC9B,CAAC;IAED,UAAU,CAAC,OAA2B;QACrC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACxB,CAAC;IAED,qBAAqB,CAAC,OAAgB;QACrC,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC;IACnC,CAAC;IAED;;;OAGG;IACH,UAAU;QACT,sDAAsD;IACvD,CAAC;IAED;;;OAGG;IACH,OAAO;QACN,0CAA0C;IAC3C,CAAC;IAED,MAAM,CAAC,KAAa;QACnB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QAEjC,yEAAyE;QACzE,yDAAyD;QACzD,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,cAAc,EAAE,CAAC;QACjE,MAAM,cAAc,GAAG,WAAW,CAAC,SAAS,CAAC;QAC7C,MAAM,eAAe,GAAG,WAAW,CAAC,UAAU,CAAC;QAC/C,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC;QACnC,MAAM,kBAAkB,GAAG,WAAW,CAAC,kBAAkB,CAAC;QAE1D,uEAAuE;QACvE,oEAAoE;QACpE,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;QACpD,MAAM,aAAa,GAAG,YAAY,EAAE,aAAa,IAAI,KAAK,CAAC,KAAK,EAAE,aAAa,IAAI,CAAC,CAAC;QACrF,MAAM,mBAAmB,GAAG,YAAY,EAAE,OAAO,IAAI,CAAC,CAAC;QACvD,MAAM,cAAc,GAAG,YAAY,EAAE,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAC7F,MAAM,aAAa,GAClB,OAAO,YAAY,EAAE,MAAM,KAAK,QAAQ;YACvC,CAAC,CAAC,YAAY,CAAC,YAAY,CAAC,MAAM,CAAC;YACnC,CAAC,CAAC,OAAO,YAAY,EAAE,OAAO,KAAK,QAAQ;gBAC1C,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,aAAa,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;gBACxE,CAAC,CAAC,GAAG,CAAC;QAET,2EAA2E;QAC3E,4EAA4E;QAC5E,uDAAuD;QACvD,MAAM,SAAS,GAAG,KAAK,CAAC;QACxB,MAAM,UAAU,GAAG,KAAK,CAAC,EAAE,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,kBAAkB,CAChC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,EACpC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAC3C,CAAC;QACF,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC;QAC9C,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,cAAc,EAAE,CAAC;QAEjE,MAAM,MAAM,GAAwC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QAC7G,IAAI,MAAM;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QACjF,MAAM,QAAQ,GAAG,CAAC,CAAC;QAEnB,MAAM,GAAG,GAAG,CAAC,KAAa,EAAiB,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;QAC3F,MAAM,MAAM,GAAoB,EAAE,CAAC;QACnC,IAAI,WAAW;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;QAC9F,IAAI,CAAC,cAAc,GAAG,CAAC,IAAI,eAAe,GAAG,CAAC,CAAC,IAAI,kBAAkB,KAAK,SAAS,IAAI,kBAAkB,IAAI,EAAE,EAAE,CAAC;YACjH,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACzD,CAAC;QAED,2EAA2E;QAC3E,MAAM,iBAAiB,GAAG,KAAK,CAAC,KAAK;YACpC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,KAAK,aAAa,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,mBAAmB,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC;YAC/G,CAAC,CAAC,KAAK,CAAC;QACT,IAAI,SAAS,IAAI,iBAAiB,EAAE,CAAC;YACpC,MAAM,OAAO,GAAG,IAAI,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YAC/E,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QACxE,CAAC;QAED,MAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,MAAM,UAAU,GACf,cAAc,KAAK,GAAG;YACrB,CAAC,CAAC,GAAG,aAAa,IAAI,YAAY,CAAC,aAAa,CAAC,OAAO,aAAa,EAAE;YACvE,CAAC,CAAC,GAAG,aAAa,IAAI,YAAY,CAAC,aAAa,CAAC,KAAK,cAAc,KAAK,aAAa,EAAE,CAAC;QAC3F,MAAM,UAAU,GACf,mBAAmB,GAAG,EAAE;YACvB,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC;YAC/B,CAAC,CAAC,mBAAmB,GAAG,EAAE;gBACzB,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC;gBACjC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QACnC,MAAM,IAAI,GAAkB,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;QAEvE,4EAA4E;QAC5E,sBAAsB;QACtB,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,EAAE,EAAE,IAAI,UAAU,CAAC;QAChD,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC;QACjF,IAAI,YAAY,GAAG,GAAG,aAAa,GAAG,SAAS,EAAE,CAAC;QAClD,IAAI,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC;YAC5B,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC;YACnD,YAAY,GAAG,aAAa,KAAK,KAAK,CAAC,CAAC,CAAC,GAAG,YAAY,MAAM,CAAC,CAAC,CAAC,GAAG,YAAY,IAAI,aAAa,EAAE,CAAC;QACrG,CAAC;QACD,MAAM,OAAO,GAAkB,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9F,IAAI,aAAa,GAAG,EAAE,CAAC;QACvB,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YACjB,IAAI,CAAC;gBACJ,aAAa,GAAG,mBAAmB,CAClC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,EAChE,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,YAAY,EAAE,CAC1C,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACR,qEAAqE;YACtE,CAAC;QACF,CAAC;QACD,MAAM,cAAc,GACnB,CAAC,IAAI,CAAC,UAAU,CAAC,yBAAyB,EAAE,GAAG,CAAC,IAAI,aAAa,KAAK,EAAE,CAAC,IAAI,KAAK,CAAC,KAAK;YACvF,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,aAAa,IAAI;YAC9C,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,IAAI,GAA8B,cAAc;YACrD,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,cAAc,GAAG,YAAY,EAAE,EAAE,OAAO,EAAE,cAAc,CAAC,GAAG,cAAc,GAAG,YAAY,EAAE,CAAC,EAAE;YAC5G,CAAC,CAAC,SAAS,CAAC;QAEb,MAAM,MAAM,GAAkB,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC;QAC5E,MAAM,IAAI,GAAG,gBAAgB,CAAC;YAC7B,KAAK;YACL,MAAM;YACN,QAAQ;YACR,MAAM;YACN,IAAI;YACJ,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;YACxB,SAAS;YACT,UAAU,EAAE,CAAC;YACb,cAAc,EAAE,MAAM;SACtB,CAAC,CAAC;QAEH,MAAM,YAAY,GAAG,CAAC,QAAkC,EAAsC,EAAE,CAAC,CAAC;YACjG,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;YACpE,KAAK,EAAE,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;SAC7E,CAAC,CAAC;QAEH,IAAI,IAAwC,CAAC;QAC7C,IAAI,KAAoB,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC1B,KAAK,GAAG,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;YACnD,IAAI,GAAG,YAAY,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;QACnD,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;YAC1C,KAAK,GAAG,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;YACnD,MAAM,QAAQ,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;YACvE,IAAI,IAAI,CAAC,UAAU;gBAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC3C,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpB,IAAI,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QAC/B,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YACvC,KAAK,GAAG,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;YACnD,MAAM,QAAQ,GAAoB;gBACjC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAChC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CACnG;gBACD,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC;aACxC,CAAC;YACF,IAAI,IAAI,CAAC,UAAU;gBAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC3C,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpB,IAAI,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QAC/B,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YACxC,KAAK,GAAG,OAAO,CAAC;YAChB,IAAI,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QAC5F,CAAC;aAAM,CAAC;YACP,IAAI,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;YACjC,KAAK,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9E,CAAC;QAED,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC;QACzE,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;QAEvD,wEAAwE;QACxE,MAAM,iBAAiB,GAAG,IAAI,CAAC,UAAU,CAAC,oBAAoB,EAAE,CAAC;QACjE,IAAI,iBAAiB,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,CAAC;iBAC5D,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;iBACtC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC;YAC9C,MAAM,UAAU,GAAG,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC5C,iFAAiF;YACjF,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;QACxE,CAAC;QAED,OAAO,KAAK,CAAC;IACd,CAAC;CACD","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { isAbsolute, relative, resolve, sep } from \"node:path\";\nimport type { Credential } from \"@earendil-works/pi-ai\";\nimport { rendezvousOrder } from \"@earendil-works/pi-ai/auth/pool/select\";\nimport { listSlots } from \"@earendil-works/pi-ai/auth/pool/slots\";\nimport { type Component, truncateToWidth, visibleWidth } from \"@earendil-works/pi-tui\";\nimport type { ReadonlyFooterDataProvider } from \"../../../core/footer-data-provider.ts\";\nimport type { InteractiveSession } from \"../interactive-host-runtime.ts\";\nimport { theme } from \"../theme/theme.ts\";\nimport { type FooterSegment, planFooterLayout } from \"./footer-layout.ts\";\n\nconst FAST_MODE_INDICATOR = \"\\u26a1 \";\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 for footer display using oh-my-pi-style K/M/B abbreviation.\n * Examples: \"999\", \"6.8K\", \"546K\", \"1M\", \"1.5M\", \"2B\".\n */\nexport function formatTokens(count: number): string {\n\tconst n = Math.round(count);\n\tif (n < 1_000) return n.toString();\n\tif (n < 10_000) return `${trim1(n / 1_000)}K`;\n\tif (n < 1_000_000) return `${Math.round(n / 1_000)}K`;\n\tif (n < 10_000_000) return `${trim1(n / 1_000_000)}M`;\n\tif (n < 1_000_000_000) return `${Math.round(n / 1_000_000)}M`;\n\tif (n < 10_000_000_000) return `${trim1(n / 1_000_000_000)}B`;\n\treturn `${Math.round(n / 1_000_000_000)}B`;\n}\n\n/**\n * Mirrors the provider-shown-only-when->1 rule for accounts: the active account\n * name appears only when the provider actually pools more than one slot. The\n * pick shown is the pin when present, else the session's HRW winner - the same\n * hash the rotation engine uses, so the footer names the slot that will serve.\n */\nexport function accountFooterSuffix(credential: Credential | undefined, sessionId: string): string {\n\tconst slots = listSlots(credential);\n\tif (slots.length < 2) return \"\";\n\tconst pinned = Object.entries(credential ?? {}).find(([key]) => key === \"pinned\")?.[1];\n\tif (typeof pinned === \"string\" && slots.some((slot) => slot.name === pinned)) return `@${pinned}`;\n\tconst winner = rendezvousOrder(sessionId, slots, (input) =>\n\t\tcreateHash(\"sha256\").update(input).digest().readBigUInt64BE(0),\n\t)[0];\n\treturn winner === undefined ? \"\" : `@${winner.name}`;\n}\n\n/** Format with up to 1 decimal place, dropping trailing `.0`. */\nfunction trim1(n: number): string {\n\tconst s = n.toFixed(1);\n\treturn s.endsWith(\".0\") ? s.slice(0, -2) : s;\n}\n\nexport function formatCwdForFooter(cwd: string, home: string | undefined): string {\n\tif (!home) return cwd;\n\n\tconst resolvedCwd = resolve(cwd);\n\tconst resolvedHome = resolve(home);\n\tconst relativeToHome = relative(resolvedHome, resolvedCwd);\n\tconst isInsideHome =\n\t\trelativeToHome === \"\" ||\n\t\t(relativeToHome !== \"..\" && !relativeToHome.startsWith(`..${sep}`) && !isAbsolute(relativeToHome));\n\n\tif (!isInsideHome) return cwd;\n\treturn relativeToHome === \"\" ? \"~\" : `~${sep}${relativeToHome}`;\n}\n\n/**\n * Color the right side of the footer: (provider) muted, model accent, :thinking dim.\n * The text is the plain (uncolored) right-aligned segment from the layout pass.\n */\nfunction colorRightSide(text: string): string {\n\tif (!text) return \"\";\n\tconst providerMatch = text.match(/^\\(([^)]+)\\) (.*)$/);\n\tconst afterProvider = providerMatch ? providerMatch[2] : text;\n\tconst providerPrefix = providerMatch ? theme.fg(\"muted\", `(${providerMatch[1]}) `) : \"\";\n\tconst fastPrefix = afterProvider.startsWith(FAST_MODE_INDICATOR) ? theme.fg(\"warning\", FAST_MODE_INDICATOR) : \"\";\n\tconst body = fastPrefix ? afterProvider.slice(FAST_MODE_INDICATOR.length) : afterProvider;\n\tconst thinkingMatch = body.match(/^(.+):([^:]+)$/);\n\tif (!thinkingMatch) return providerPrefix + fastPrefix + theme.fg(\"accent\", body);\n\treturn `${providerPrefix}${fastPrefix}${theme.fg(\"accent\", thinkingMatch[1])}${theme.fg(\"dim\", `:${thinkingMatch[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 session: InteractiveSession;\n\tprivate footerData: ReadonlyFooterDataProvider;\n\tprivate autoCompactEnabled = true;\n\n\tconstructor(session: InteractiveSession, footerData: ReadonlyFooterDataProvider) {\n\t\tthis.session = session;\n\t\tthis.footerData = footerData;\n\t}\n\n\tsetSession(session: InteractiveSession): void {\n\t\tthis.session = session;\n\t}\n\n\tsetAutoCompactEnabled(enabled: boolean): void {\n\t\tthis.autoCompactEnabled = enabled;\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\t// O(1) running totals maintained by SessionManager (identical to summing\n\t\t// usage over all entries; totals are not branch-scoped).\n\t\tconst usageTotals = this.session.sessionManager.getUsageTotals();\n\t\tconst totalCacheRead = usageTotals.cacheRead;\n\t\tconst totalCacheWrite = usageTotals.cacheWrite;\n\t\tconst totalCost = usageTotals.cost;\n\t\tconst latestCacheHitRate = usageTotals.latestCacheHitRate;\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 contextWindow = contextUsage?.contextWindow ?? state.model?.contextWindow ?? 0;\n\t\tconst contextPercentValue = contextUsage?.percent ?? 0;\n\t\tconst contextPercent = contextUsage?.percent !== null ? contextPercentValue.toFixed(1) : \"?\";\n\t\tconst contextTokens =\n\t\t\ttypeof contextUsage?.tokens === \"number\"\n\t\t\t\t? formatTokens(contextUsage.tokens)\n\t\t\t\t: typeof contextUsage?.percent === \"number\"\n\t\t\t\t\t? formatTokens(Math.round((contextWindow * contextUsage.percent) / 100))\n\t\t\t\t\t: \"?\";\n\n\t\t// Segments in priority order: anchors (pwd, branch, context) and the model\n\t\t// label always stay; middle stats elide from the right when space runs out.\n\t\t// The width ladder itself lives in ./footer-layout.ts.\n\t\tconst separator = \" • \";\n\t\tconst sepColored = theme.fg(\"borderMuted\", separator);\n\t\tconst pwdRaw = formatCwdForFooter(\n\t\t\tthis.session.sessionManager.getCwd(),\n\t\t\tprocess.env.HOME || process.env.USERPROFILE,\n\t\t);\n\t\tconst branch = this.footerData.getGitBranch();\n\t\tconst sessionName = this.session.sessionManager.getSessionName();\n\n\t\tconst anchor: [FooterSegment, ...FooterSegment[]] = [{ plain: pwdRaw, colored: theme.fg(\"accent\", pwdRaw) }];\n\t\tif (branch) anchor.push({ plain: branch, colored: theme.fg(\"warning\", branch) });\n\t\tconst pwdIndex = 0;\n\n\t\tconst dim = (plain: string): FooterSegment => ({ plain, colored: theme.fg(\"dim\", plain) });\n\t\tconst middle: FooterSegment[] = [];\n\t\tif (sessionName) middle.push({ plain: sessionName, colored: theme.fg(\"muted\", sessionName) });\n\t\tif ((totalCacheRead > 0 || totalCacheWrite > 0) && latestCacheHitRate !== undefined && latestCacheHitRate >= 10) {\n\t\t\tmiddle.push(dim(`CH${latestCacheHitRate.toFixed(1)}%`));\n\t\t}\n\n\t\t// Kimi Coding is subscription-backed despite using API-key authentication.\n\t\tconst usingSubscription = state.model\n\t\t\t? state.model.provider === \"kimi-coding\" || this.session.modelRuntime.isUsingSubscription(state.model.provider)\n\t\t\t: false;\n\t\tif (totalCost || usingSubscription) {\n\t\t\tconst costStr = `$${totalCost.toFixed(3)}${usingSubscription ? \" (sub)\" : \"\"}`;\n\t\t\tmiddle.push({ plain: costStr, colored: theme.fg(\"success\", costStr) });\n\t\t}\n\n\t\tconst autoIndicator = this.autoCompactEnabled ? \" (auto)\" : \"\";\n\t\tconst ctxDisplay =\n\t\t\tcontextPercent === \"?\"\n\t\t\t\t? `${contextTokens}/${formatTokens(contextWindow)} (?)${autoIndicator}`\n\t\t\t\t: `${contextTokens}/${formatTokens(contextWindow)} (${contextPercent}%)${autoIndicator}`;\n\t\tconst ctxColored =\n\t\t\tcontextPercentValue > 90\n\t\t\t\t? theme.fg(\"error\", ctxDisplay)\n\t\t\t\t: contextPercentValue > 70\n\t\t\t\t\t? theme.fg(\"warning\", ctxDisplay)\n\t\t\t\t\t: theme.fg(\"muted\", ctxDisplay);\n\t\tconst tail: FooterSegment = { plain: ctxDisplay, colored: ctxColored };\n\n\t\t// Model label pinned to the right edge; the provider prefix stays only when\n\t\t// the full line fits.\n\t\tconst modelName = state.model?.id || \"no-model\";\n\t\tconst fastIndicator = this.session.isFastModeActive() ? FAST_MODE_INDICATOR : \"\";\n\t\tlet minimalRight = `${fastIndicator}${modelName}`;\n\t\tif (state.model?.reasoning) {\n\t\t\tconst thinkingLevel = state.thinkingLevel || \"off\";\n\t\t\tminimalRight = thinkingLevel === \"off\" ? `${minimalRight}:off` : `${minimalRight}:${thinkingLevel}`;\n\t\t}\n\t\tconst minimal: FooterSegment = { plain: minimalRight, colored: colorRightSide(minimalRight) };\n\t\tlet accountSuffix = \"\";\n\t\tif (state.model) {\n\t\t\ttry {\n\t\t\t\taccountSuffix = accountFooterSuffix(\n\t\t\t\t\tthis.session.modelRegistry.authStorage.get(state.model.provider),\n\t\t\t\t\tthis.session.sessionManager.getSessionId(),\n\t\t\t\t);\n\t\t\t} catch {\n\t\t\t\t// The footer must render even when credential storage is unreadable.\n\t\t\t}\n\t\t}\n\t\tconst providerPrefix =\n\t\t\t(this.footerData.getAvailableProviderCount() > 1 || accountSuffix !== \"\") && state.model\n\t\t\t\t? `(${state.model.provider}${accountSuffix}) `\n\t\t\t\t: \"\";\n\t\tconst full: FooterSegment | undefined = providerPrefix\n\t\t\t? { plain: `${providerPrefix}${minimalRight}`, colored: colorRightSide(`${providerPrefix}${minimalRight}`) }\n\t\t\t: undefined;\n\n\t\tconst marker: FooterSegment = { plain: \"…\", colored: theme.fg(\"dim\", \"…\") };\n\t\tconst plan = planFooterLayout({\n\t\t\twidth,\n\t\t\tanchor,\n\t\t\tpwdIndex,\n\t\t\tmiddle,\n\t\t\ttail,\n\t\t\tright: { minimal, full },\n\t\t\tseparator,\n\t\t\tminPadding: 2,\n\t\t\tellipsisMarker: marker,\n\t\t});\n\n\t\tconst joinSegments = (segments: readonly FooterSegment[]): { colored: string; width: number } => ({\n\t\t\tcolored: segments.map((segment) => segment.colored).join(sepColored),\n\t\t\twidth: visibleWidth(segments.map((segment) => segment.plain).join(separator)),\n\t\t});\n\n\t\tlet left: { colored: string; width: number };\n\t\tlet right: FooterSegment;\n\t\tif (plan.kind === \"full\") {\n\t\t\tright = plan.useFullRight && full ? full : minimal;\n\t\t\tleft = joinSegments([...anchor, ...middle, tail]);\n\t\t} else if (plan.kind === \"middle-elided\") {\n\t\t\tright = plan.useFullRight && full ? full : minimal;\n\t\t\tconst segments = [...anchor, ...middle.slice(0, plan.keptMiddleCount)];\n\t\t\tif (plan.showMarker) segments.push(marker);\n\t\t\tsegments.push(tail);\n\t\t\tleft = joinSegments(segments);\n\t\t} else if (plan.kind === \"pwd-elided\") {\n\t\t\tright = plan.useFullRight && full ? full : minimal;\n\t\t\tconst segments: FooterSegment[] = [\n\t\t\t\t...anchor.map((segment, index) =>\n\t\t\t\t\tindex === pwdIndex ? { plain: plan.pwdPlain, colored: theme.fg(\"accent\", plan.pwdPlain) } : segment,\n\t\t\t\t),\n\t\t\t\t...middle.slice(0, plan.keptMiddleCount),\n\t\t\t];\n\t\t\tif (plan.showMarker) segments.push(marker);\n\t\t\tsegments.push(tail);\n\t\t\tleft = joinSegments(segments);\n\t\t} else if (plan.kind === \"left-elided\") {\n\t\t\tright = minimal;\n\t\t\tleft = { colored: theme.fg(\"muted\", plan.leftPlain), width: visibleWidth(plan.leftPlain) };\n\t\t} else {\n\t\t\tleft = { colored: \"\", width: 0 };\n\t\t\tright = { plain: plan.rightPlain, colored: colorRightSide(plan.rightPlain) };\n\t\t}\n\n\t\tconst rightWidth = visibleWidth(right.plain);\n\t\tconst padding = \" \".repeat(Math.max(0, width - left.width - rightWidth));\n\t\tconst lines = [left.colored + padding + right.colored];\n\n\t\t// Add extension statuses on a single line, sorted by key alphabetically\n\t\tconst extensionStatuses = this.footerData.getExtensionStatuses();\n\t\tif (extensionStatuses.size > 0) {\n\t\t\tconst sortedStatuses = Array.from(extensionStatuses.entries())\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// Truncate to terminal width with dim ellipsis for consistency with footer style\n\t\t\tlines.push(truncateToWidth(statusLine, width, theme.fg(\"dim\", \"...\")));\n\t\t}\n\n\t\treturn lines;\n\t}\n}\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"]}
@@ -1,13 +1,13 @@
1
1
  import type { Component, EditorOptions, EditorTheme, TUI } from "@earendil-works/pi-tui";
2
- import type { AgentSession } from "../../../core/agent-session.ts";
3
2
  import type { WorkingIndicatorOptions } from "../../../core/extensions/index.ts";
4
3
  import type { ReadonlyFooterDataProvider } from "../../../core/footer-data-provider.ts";
5
4
  import type { KeybindingsManager } from "../../../core/keybindings.ts";
6
5
  import { CustomEditor } from "../components/custom-editor.ts";
7
6
  import { WorkingStatusIndicator } from "../components/status-indicator.ts";
8
7
  import type { ToolExecutionPresentation } from "../components/tool-execution.ts";
8
+ import type { InteractiveSession } from "../interactive-host-runtime.ts";
9
9
  export interface InteractiveFooter extends Component {
10
- setSession(session: AgentSession): void;
10
+ setSession(session: InteractiveSession): void;
11
11
  setAutoCompactEnabled(enabled: boolean): void;
12
12
  invalidate(): void;
13
13
  dispose(): void;
@@ -28,7 +28,7 @@ export interface InteractiveChrome {
28
28
  editorOptions: EditorOptions;
29
29
  }): CustomEditor;
30
30
  getEditorTheme(): EditorTheme;
31
- createFooter(session: AgentSession, footerData: ReadonlyFooterDataProvider): InteractiveFooter;
31
+ createFooter(session: InteractiveSession, footerData: ReadonlyFooterDataProvider): InteractiveFooter;
32
32
  createWelcomeContent(appName: string, version: string): Component;
33
33
  createWorkingIndicator(ui: TUI, message: string, indicator?: WorkingIndicatorOptions): WorkingStatusIndicator;
34
34
  getEditorBorderColor(context: EditorBorderContext): (text: string) => string;
@@ -42,7 +42,7 @@ export declare class GrokChrome implements InteractiveChrome {
42
42
  editorOptions: EditorOptions;
43
43
  }): CustomEditor;
44
44
  getEditorTheme(): EditorTheme;
45
- createFooter(session: AgentSession, footerData: ReadonlyFooterDataProvider): InteractiveFooter;
45
+ createFooter(session: InteractiveSession, footerData: ReadonlyFooterDataProvider): InteractiveFooter;
46
46
  createWelcomeContent(appName: string, version: string): Component;
47
47
  createWorkingIndicator(ui: TUI, message: string, indicator?: WorkingIndicatorOptions): WorkingStatusIndicator;
48
48
  getEditorBorderColor(_context: EditorBorderContext): (text: string) => string;
@@ -1 +1 @@
1
- {"version":3,"file":"chrome.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/grok/chrome.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AACzF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAC;AACxF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAQjF,MAAM,WAAW,iBAAkB,SAAQ,SAAS;IACnD,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;IACxC,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9C,UAAU,IAAI,IAAI,CAAC;IACnB,OAAO,IAAI,IAAI,CAAC;CAChB;AAED,MAAM,MAAM,mBAAmB,GAAG;IACjC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAC/B,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,gBAAgB,EAAE,yBAAyB,CAAC;IACrD,gBAAgB,CAAC,OAAO,EAAE;QAAE,EAAE,EAAE,GAAG,CAAC;QAAC,WAAW,EAAE,kBAAkB,CAAC;QAAC,aAAa,EAAE,aAAa,CAAA;KAAE,GAAG,YAAY,CAAC;IACpH,cAAc,IAAI,WAAW,CAAC;IAC9B,YAAY,CAAC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,0BAA0B,GAAG,iBAAiB,CAAC;IAC/F,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAClE,sBAAsB,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,uBAAuB,GAAG,sBAAsB,CAAC;IAC9G,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7E,WAAW,CAAC,QAAQ,EAAE,SAAS,SAAS,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,GAAG,SAAS,EAAE,CAAC;CACnE;AA8DD,qBAAa,UAAW,YAAW,iBAAiB;IACnD,QAAQ,CAAC,gBAAgB,EAAG,MAAM,CAAU;IAE5C,gBAAgB,CAAC,EAChB,EAAE,EACF,WAAW,EACX,aAAa,GACb,EAAE;QACF,EAAE,EAAE,GAAG,CAAC;QACR,WAAW,EAAE,kBAAkB,CAAC;QAChC,aAAa,EAAE,aAAa,CAAC;KAC7B,GAAG,YAAY;IAIhB,cAAc,IAAI,WAAW;IAkB7B,YAAY,CAAC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,0BAA0B,GAAG,iBAAiB;IAI9F,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS;IAIjE,sBAAsB,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,uBAAuB,GAAG,sBAAsB;IAQ7G,oBAAoB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM;IAI7E,WAAW,CAAC,QAAQ,EAAE,SAAS,SAAS,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,GAAG,SAAS,EAAE;CAYlE"}
1
+ {"version":3,"file":"chrome.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/grok/chrome.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AACzF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAC;AACxF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AACjF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAQzE,MAAM,WAAW,iBAAkB,SAAQ,SAAS;IACnD,UAAU,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC9C,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9C,UAAU,IAAI,IAAI,CAAC;IACnB,OAAO,IAAI,IAAI,CAAC;CAChB;AAED,MAAM,MAAM,mBAAmB,GAAG;IACjC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAC/B,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,gBAAgB,EAAE,yBAAyB,CAAC;IACrD,gBAAgB,CAAC,OAAO,EAAE;QAAE,EAAE,EAAE,GAAG,CAAC;QAAC,WAAW,EAAE,kBAAkB,CAAC;QAAC,aAAa,EAAE,aAAa,CAAA;KAAE,GAAG,YAAY,CAAC;IACpH,cAAc,IAAI,WAAW,CAAC;IAC9B,YAAY,CAAC,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,0BAA0B,GAAG,iBAAiB,CAAC;IACrG,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAClE,sBAAsB,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,uBAAuB,GAAG,sBAAsB,CAAC;IAC9G,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7E,WAAW,CAAC,QAAQ,EAAE,SAAS,SAAS,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,GAAG,SAAS,EAAE,CAAC;CACnE;AA8DD,qBAAa,UAAW,YAAW,iBAAiB;IACnD,QAAQ,CAAC,gBAAgB,EAAG,MAAM,CAAU;IAE5C,gBAAgB,CAAC,EAChB,EAAE,EACF,WAAW,EACX,aAAa,GACb,EAAE;QACF,EAAE,EAAE,GAAG,CAAC;QACR,WAAW,EAAE,kBAAkB,CAAC;QAChC,aAAa,EAAE,aAAa,CAAC;KAC7B,GAAG,YAAY;IAIhB,cAAc,IAAI,WAAW;IAkB7B,YAAY,CAAC,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,0BAA0B,GAAG,iBAAiB;IAIpG,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS;IAIjE,sBAAsB,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,uBAAuB,GAAG,sBAAsB;IAQ7G,oBAAoB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM;IAI7E,WAAW,CAAC,QAAQ,EAAE,SAAS,SAAS,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,GAAG,SAAS,EAAE;CAYlE"}
@@ -1 +1 @@
1
- {"version":3,"file":"chrome.js","sourceRoot":"","sources":["../../../../src/modes/interactive/grok/chrome.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Component, EditorOptions, EditorTheme, TUI } from \"@earendil-works/pi-tui\";\nimport type { AgentSession } from \"../../../core/agent-session.ts\";\nimport type { WorkingIndicatorOptions } from \"../../../core/extensions/index.ts\";\nimport type { ReadonlyFooterDataProvider } from \"../../../core/footer-data-provider.ts\";\nimport type { KeybindingsManager } from \"../../../core/keybindings.ts\";\nimport { CustomEditor } from \"../components/custom-editor.ts\";\nimport { WorkingStatusIndicator } from \"../components/status-indicator.ts\";\nimport type { ToolExecutionPresentation } from \"../components/tool-execution.ts\";\nimport { theme } from \"../theme/theme.ts\";\nimport { getGrokChromeTokens } from \"./chrome-tokens.ts\";\nimport { GrokFooter } from \"./footer.ts\";\nimport { GrokInputCard } from \"./input-card.ts\";\nimport { GROK_GLYPHS } from \"./palette.ts\";\nimport { GrokWelcomeCard } from \"./welcome-card.ts\";\n\nexport interface InteractiveFooter extends Component {\n\tsetSession(session: AgentSession): void;\n\tsetAutoCompactEnabled(enabled: boolean): void;\n\tinvalidate(): void;\n\tdispose(): void;\n}\n\nexport type EditorBorderContext = {\n\treadonly isBashMode: boolean;\n\treadonly thinkingLevel: string;\n};\n\n/**\n * Mode-owned chrome seam for InteractiveMode. Extensions continue to own their\n * editor factory; this strategy only creates and decorates the base editor.\n */\nexport interface InteractiveChrome {\n\treadonly toolPresentation: ToolExecutionPresentation;\n\tcreateBaseEditor(context: { ui: TUI; keybindings: KeybindingsManager; editorOptions: EditorOptions }): CustomEditor;\n\tgetEditorTheme(): EditorTheme;\n\tcreateFooter(session: AgentSession, footerData: ReadonlyFooterDataProvider): InteractiveFooter;\n\tcreateWelcomeContent(appName: string, version: string): Component;\n\tcreateWorkingIndicator(ui: TUI, message: string, indicator?: WorkingIndicatorOptions): WorkingStatusIndicator;\n\tgetEditorBorderColor(context: EditorBorderContext): (text: string) => string;\n\tarrangeRoot(children: readonly Component[], ui?: TUI): Component[];\n}\n\nclass GrokFooterSurface implements Component {\n\tprivate readonly content: Component;\n\n\tconstructor(content: Component) {\n\t\tthis.content = content;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.content.invalidate();\n\t}\n\n\trender(width: number): string[] {\n\t\tconst surface = getGrokChromeTokens().surface;\n\t\treturn this.content.render(width).map(surface);\n\t}\n\n\tdispose(): void {\n\t\tthis.content.dispose?.();\n\t}\n}\n\nclass GrokRootSpacer implements Component {\n\tprivate readonly ui: TUI;\n\tprivate readonly content: readonly Component[];\n\n\tconstructor(ui: TUI, content: readonly Component[]) {\n\t\tthis.ui = ui;\n\t\tthis.content = content;\n\t}\n\n\tinvalidate(): void {\n\t\t// The spacer derives its height from the current terminal dimensions.\n\t}\n\n\trender(width: number): string[] {\n\t\tconst contentHeight = this.content.reduce((height, component) => height + component.render(width).length, 0);\n\t\treturn Array.from({ length: Math.max(0, this.ui.terminal.rows - contentHeight) }, () => \"\");\n\t}\n}\n\nclass GrokEditor extends CustomEditor {\n\tprivate readonly card: GrokInputCard;\n\n\tconstructor(ui: TUI, editorTheme: EditorTheme, keybindings: KeybindingsManager, options: EditorOptions) {\n\t\tsuper(ui, editorTheme, keybindings, options);\n\t\tthis.card = new GrokInputCard({\n\t\t\trender: (width) => this.renderBase(width),\n\t\t\tinvalidate: () => super.invalidate(),\n\t\t});\n\t}\n\n\toverride render(width: number): string[] {\n\t\treturn this.card.render(width);\n\t}\n\n\tprivate renderBase(width: number): string[] {\n\t\treturn super.render(width);\n\t}\n}\n\nexport class GrokChrome implements InteractiveChrome {\n\treadonly toolPresentation = \"grok\" as const;\n\n\tcreateBaseEditor({\n\t\tui,\n\t\tkeybindings,\n\t\teditorOptions,\n\t}: {\n\t\tui: TUI;\n\t\tkeybindings: KeybindingsManager;\n\t\teditorOptions: EditorOptions;\n\t}): CustomEditor {\n\t\treturn new GrokEditor(ui, this.getEditorTheme(), keybindings, editorOptions);\n\t}\n\n\tgetEditorTheme(): EditorTheme {\n\t\tconst tokens = getGrokChromeTokens();\n\t\treturn {\n\t\t\tborderColor: tokens.inputBorder,\n\t\t\tselectList: {\n\t\t\t\tselectedPrefix: (text) => theme.fg(\"accent\", text),\n\t\t\t\tselectedText: (text) => tokens.primaryText(text),\n\t\t\t\tdescription: (text) => tokens.mutedText(text),\n\t\t\t\tscrollInfo: (text) => tokens.mutedText(text),\n\t\t\t\tnoMatch: (text) => tokens.mutedText(text),\n\t\t\t\trenderRow: ({ prefix, primary, description, isSelected }) => {\n\t\t\t\t\tconst row = `${prefix}${tokens.primaryText(primary)}${description ? tokens.mutedText(description) : \"\"}`;\n\t\t\t\t\treturn isSelected ? theme.bg(\"selectedBg\", row) : row;\n\t\t\t\t},\n\t\t\t},\n\t\t};\n\t}\n\n\tcreateFooter(session: AgentSession, footerData: ReadonlyFooterDataProvider): InteractiveFooter {\n\t\treturn new GrokFooter(session, footerData);\n\t}\n\n\tcreateWelcomeContent(appName: string, version: string): Component {\n\t\treturn new GrokWelcomeCard(appName, version);\n\t}\n\n\tcreateWorkingIndicator(ui: TUI, message: string, indicator?: WorkingIndicatorOptions): WorkingStatusIndicator {\n\t\treturn new WorkingStatusIndicator(ui, message, {\n\t\t\t...indicator,\n\t\t\tframes: [GROK_GLYPHS.spinner],\n\t\t\tindicatorFormatter: (frame) => theme.fg(\"accent\", frame),\n\t\t});\n\t}\n\n\tgetEditorBorderColor(_context: EditorBorderContext): (text: string) => string {\n\t\treturn getGrokChromeTokens().inputBorder;\n\t}\n\n\tarrangeRoot(children: readonly Component[], ui?: TUI): Component[] {\n\t\t// pi-tui concatenates root children without a layout pass. Keep transcript\n\t\t// content first and calculate the remaining rows at render time from the TUI's\n\t\t// terminal height, so the input tail is truly bottom-anchored when it fits.\n\t\tconst inputTailStart = Math.max(0, children.length - 3);\n\t\tconst content = children.slice(0, inputTailStart);\n\t\tconst inputTail = children.slice(inputTailStart);\n\t\tconst footer = inputTail.at(-1);\n\t\tconst tail = footer ? [...inputTail.slice(0, -1), new GrokFooterSurface(footer)] : [...inputTail];\n\t\tconst arranged = [...content, ...tail];\n\t\treturn ui ? [...content, new GrokRootSpacer(ui, arranged), ...tail] : arranged;\n\t}\n}\n"]}
1
+ {"version":3,"file":"chrome.js","sourceRoot":"","sources":["../../../../src/modes/interactive/grok/chrome.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Component, EditorOptions, EditorTheme, TUI } from \"@earendil-works/pi-tui\";\nimport type { WorkingIndicatorOptions } from \"../../../core/extensions/index.ts\";\nimport type { ReadonlyFooterDataProvider } from \"../../../core/footer-data-provider.ts\";\nimport type { KeybindingsManager } from \"../../../core/keybindings.ts\";\nimport { CustomEditor } from \"../components/custom-editor.ts\";\nimport { WorkingStatusIndicator } from \"../components/status-indicator.ts\";\nimport type { ToolExecutionPresentation } from \"../components/tool-execution.ts\";\nimport type { InteractiveSession } from \"../interactive-host-runtime.ts\";\nimport { theme } from \"../theme/theme.ts\";\nimport { getGrokChromeTokens } from \"./chrome-tokens.ts\";\nimport { GrokFooter } from \"./footer.ts\";\nimport { GrokInputCard } from \"./input-card.ts\";\nimport { GROK_GLYPHS } from \"./palette.ts\";\nimport { GrokWelcomeCard } from \"./welcome-card.ts\";\n\nexport interface InteractiveFooter extends Component {\n\tsetSession(session: InteractiveSession): void;\n\tsetAutoCompactEnabled(enabled: boolean): void;\n\tinvalidate(): void;\n\tdispose(): void;\n}\n\nexport type EditorBorderContext = {\n\treadonly isBashMode: boolean;\n\treadonly thinkingLevel: string;\n};\n\n/**\n * Mode-owned chrome seam for InteractiveMode. Extensions continue to own their\n * editor factory; this strategy only creates and decorates the base editor.\n */\nexport interface InteractiveChrome {\n\treadonly toolPresentation: ToolExecutionPresentation;\n\tcreateBaseEditor(context: { ui: TUI; keybindings: KeybindingsManager; editorOptions: EditorOptions }): CustomEditor;\n\tgetEditorTheme(): EditorTheme;\n\tcreateFooter(session: InteractiveSession, footerData: ReadonlyFooterDataProvider): InteractiveFooter;\n\tcreateWelcomeContent(appName: string, version: string): Component;\n\tcreateWorkingIndicator(ui: TUI, message: string, indicator?: WorkingIndicatorOptions): WorkingStatusIndicator;\n\tgetEditorBorderColor(context: EditorBorderContext): (text: string) => string;\n\tarrangeRoot(children: readonly Component[], ui?: TUI): Component[];\n}\n\nclass GrokFooterSurface implements Component {\n\tprivate readonly content: Component;\n\n\tconstructor(content: Component) {\n\t\tthis.content = content;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.content.invalidate();\n\t}\n\n\trender(width: number): string[] {\n\t\tconst surface = getGrokChromeTokens().surface;\n\t\treturn this.content.render(width).map(surface);\n\t}\n\n\tdispose(): void {\n\t\tthis.content.dispose?.();\n\t}\n}\n\nclass GrokRootSpacer implements Component {\n\tprivate readonly ui: TUI;\n\tprivate readonly content: readonly Component[];\n\n\tconstructor(ui: TUI, content: readonly Component[]) {\n\t\tthis.ui = ui;\n\t\tthis.content = content;\n\t}\n\n\tinvalidate(): void {\n\t\t// The spacer derives its height from the current terminal dimensions.\n\t}\n\n\trender(width: number): string[] {\n\t\tconst contentHeight = this.content.reduce((height, component) => height + component.render(width).length, 0);\n\t\treturn Array.from({ length: Math.max(0, this.ui.terminal.rows - contentHeight) }, () => \"\");\n\t}\n}\n\nclass GrokEditor extends CustomEditor {\n\tprivate readonly card: GrokInputCard;\n\n\tconstructor(ui: TUI, editorTheme: EditorTheme, keybindings: KeybindingsManager, options: EditorOptions) {\n\t\tsuper(ui, editorTheme, keybindings, options);\n\t\tthis.card = new GrokInputCard({\n\t\t\trender: (width) => this.renderBase(width),\n\t\t\tinvalidate: () => super.invalidate(),\n\t\t});\n\t}\n\n\toverride render(width: number): string[] {\n\t\treturn this.card.render(width);\n\t}\n\n\tprivate renderBase(width: number): string[] {\n\t\treturn super.render(width);\n\t}\n}\n\nexport class GrokChrome implements InteractiveChrome {\n\treadonly toolPresentation = \"grok\" as const;\n\n\tcreateBaseEditor({\n\t\tui,\n\t\tkeybindings,\n\t\teditorOptions,\n\t}: {\n\t\tui: TUI;\n\t\tkeybindings: KeybindingsManager;\n\t\teditorOptions: EditorOptions;\n\t}): CustomEditor {\n\t\treturn new GrokEditor(ui, this.getEditorTheme(), keybindings, editorOptions);\n\t}\n\n\tgetEditorTheme(): EditorTheme {\n\t\tconst tokens = getGrokChromeTokens();\n\t\treturn {\n\t\t\tborderColor: tokens.inputBorder,\n\t\t\tselectList: {\n\t\t\t\tselectedPrefix: (text) => theme.fg(\"accent\", text),\n\t\t\t\tselectedText: (text) => tokens.primaryText(text),\n\t\t\t\tdescription: (text) => tokens.mutedText(text),\n\t\t\t\tscrollInfo: (text) => tokens.mutedText(text),\n\t\t\t\tnoMatch: (text) => tokens.mutedText(text),\n\t\t\t\trenderRow: ({ prefix, primary, description, isSelected }) => {\n\t\t\t\t\tconst row = `${prefix}${tokens.primaryText(primary)}${description ? tokens.mutedText(description) : \"\"}`;\n\t\t\t\t\treturn isSelected ? theme.bg(\"selectedBg\", row) : row;\n\t\t\t\t},\n\t\t\t},\n\t\t};\n\t}\n\n\tcreateFooter(session: InteractiveSession, footerData: ReadonlyFooterDataProvider): InteractiveFooter {\n\t\treturn new GrokFooter(session, footerData);\n\t}\n\n\tcreateWelcomeContent(appName: string, version: string): Component {\n\t\treturn new GrokWelcomeCard(appName, version);\n\t}\n\n\tcreateWorkingIndicator(ui: TUI, message: string, indicator?: WorkingIndicatorOptions): WorkingStatusIndicator {\n\t\treturn new WorkingStatusIndicator(ui, message, {\n\t\t\t...indicator,\n\t\t\tframes: [GROK_GLYPHS.spinner],\n\t\t\tindicatorFormatter: (frame) => theme.fg(\"accent\", frame),\n\t\t});\n\t}\n\n\tgetEditorBorderColor(_context: EditorBorderContext): (text: string) => string {\n\t\treturn getGrokChromeTokens().inputBorder;\n\t}\n\n\tarrangeRoot(children: readonly Component[], ui?: TUI): Component[] {\n\t\t// pi-tui concatenates root children without a layout pass. Keep transcript\n\t\t// content first and calculate the remaining rows at render time from the TUI's\n\t\t// terminal height, so the input tail is truly bottom-anchored when it fits.\n\t\tconst inputTailStart = Math.max(0, children.length - 3);\n\t\tconst content = children.slice(0, inputTailStart);\n\t\tconst inputTail = children.slice(inputTailStart);\n\t\tconst footer = inputTail.at(-1);\n\t\tconst tail = footer ? [...inputTail.slice(0, -1), new GrokFooterSurface(footer)] : [...inputTail];\n\t\tconst arranged = [...content, ...tail];\n\t\treturn ui ? [...content, new GrokRootSpacer(ui, arranged), ...tail] : arranged;\n\t}\n}\n"]}
@@ -1,11 +1,11 @@
1
1
  import { type Component } from "@earendil-works/pi-tui";
2
- import type { AgentSession } from "../../../core/agent-session.ts";
3
2
  import type { ReadonlyFooterDataProvider } from "../../../core/footer-data-provider.ts";
3
+ import type { InteractiveSession } from "../interactive-host-runtime.ts";
4
4
  /** Compact status footer for grok chrome. */
5
5
  export declare class GrokFooter implements Component {
6
6
  private session;
7
- constructor(session: AgentSession, _footerData: ReadonlyFooterDataProvider);
8
- setSession(session: AgentSession): void;
7
+ constructor(session: InteractiveSession, _footerData: ReadonlyFooterDataProvider);
8
+ setSession(session: InteractiveSession): void;
9
9
  setAutoCompactEnabled(_enabled: boolean): void;
10
10
  invalidate(): void;
11
11
  dispose(): void;