@astralyn/pi 0.99.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (512) hide show
  1. package/CHANGELOG.md +39 -3
  2. package/dist/bundle/chunks/anthropic-messages-CG2BSDQS.js +6 -0
  3. package/dist/bundle/chunks/anthropic.js +2 -2
  4. package/dist/bundle/chunks/{azure-openai-responses-RPBERDXD.js → azure-openai-responses-PBA4QKCM.js} +1 -1
  5. package/dist/bundle/chunks/bedrock-converse-stream.js +2 -2
  6. package/dist/bundle/chunks/{chunk-ABVRAYXT.js → chunk-6UFFVA7M.js} +2 -2
  7. package/dist/bundle/chunks/chunk-GIG5IHES.js +2 -0
  8. package/dist/bundle/chunks/{chunk-VW2P3X6P.js → chunk-HESRDUKO.js} +414 -666
  9. package/dist/bundle/chunks/{chunk-A576H74Y.js → chunk-PFZKRUMO.js} +1 -1
  10. package/dist/bundle/chunks/chunk-SGLYRVQL.js +2 -0
  11. package/dist/bundle/chunks/chunk-TRHTWM3C.js +2 -0
  12. package/dist/bundle/chunks/{chunk-DEWXBB6W.js → chunk-V66VGGOM.js} +1 -1
  13. package/dist/bundle/chunks/chunk-Z2RKSI3O.js +2 -0
  14. package/dist/bundle/chunks/{cloudflare-workers-ai-system-one-ZYSAFXXL.js → cloudflare-workers-ai-system-one-YB7XPPP4.js} +1 -1
  15. package/dist/bundle/chunks/codemode-worker.js +67 -8
  16. package/dist/bundle/chunks/github-copilot.js +1 -1
  17. package/dist/bundle/chunks/{google-generative-ai-SDNQVVXA.js → google-generative-ai-V5ZM5MCL.js} +1 -1
  18. package/dist/bundle/chunks/{google-vertex-LZXOLBIO.js → google-vertex-22THOFP5.js} +1 -1
  19. package/dist/bundle/chunks/{llama-cpp-classify-7IYGGPND.js → llama-cpp-classify-R7DQLTQN.js} +1 -1
  20. package/dist/bundle/chunks/{mistral-conversations-VYKPSSAM.js → mistral-conversations-WHSCJJWP.js} +1 -1
  21. package/dist/bundle/chunks/openai-chatgpt.js +1 -1
  22. package/dist/bundle/chunks/{openai-codex-responses-HZ4VUDXD.js → openai-codex-responses-N7GDPBPP.js} +1 -1
  23. package/dist/bundle/chunks/openai-codex.js +1 -1
  24. package/dist/bundle/chunks/{openai-completions-SKDGF6OE.js → openai-completions-RGGQK5UW.js} +1 -1
  25. package/dist/bundle/chunks/{openai-responses-FPML4SSG.js → openai-responses-3ZLD5JYI.js} +1 -1
  26. package/dist/bundle/chunks/{openrouter-images-5524IQHX.js → openrouter-images-YP3YVB54.js} +1 -1
  27. package/dist/bundle/chunks/openrouter.js +1 -1
  28. package/dist/bundle/chunks/radius.js +1 -1
  29. package/dist/bundle/chunks/{typesafe-system-one-Z2CDLKEY.js → typesafe-system-one-RREJAKWB.js} +1 -1
  30. package/dist/bundle/chunks/virtual-modules-4RQ2L6W4.js +2 -0
  31. package/dist/bundle/cli.js +1 -1
  32. package/dist/bundle/index.js +1 -1
  33. package/dist/bundle/rpc-entry.js +1 -1
  34. package/dist/cli/args.js +1 -1
  35. package/dist/cli/args.js.map +1 -1
  36. package/dist/config.d.ts +5 -8
  37. package/dist/config.d.ts.map +1 -1
  38. package/dist/config.js +16 -13
  39. package/dist/config.js.map +1 -1
  40. package/dist/core/agent-session.d.ts +21 -1
  41. package/dist/core/agent-session.d.ts.map +1 -1
  42. package/dist/core/agent-session.js +64 -11
  43. package/dist/core/agent-session.js.map +1 -1
  44. package/dist/core/extensions/index.d.ts +1 -1
  45. package/dist/core/extensions/index.d.ts.map +1 -1
  46. package/dist/core/extensions/index.js.map +1 -1
  47. package/dist/core/extensions/loader.d.ts.map +1 -1
  48. package/dist/core/extensions/loader.js +13 -1
  49. package/dist/core/extensions/loader.js.map +1 -1
  50. package/dist/core/extensions/types.d.ts +6 -1
  51. package/dist/core/extensions/types.d.ts.map +1 -1
  52. package/dist/core/extensions/types.js.map +1 -1
  53. package/dist/core/keybindings.d.ts +51 -11
  54. package/dist/core/keybindings.d.ts.map +1 -1
  55. package/dist/core/keybindings.js +11 -3
  56. package/dist/core/keybindings.js.map +1 -1
  57. package/dist/core/mcp-servers.d.ts +34 -7
  58. package/dist/core/mcp-servers.d.ts.map +1 -1
  59. package/dist/core/mcp-servers.js +52 -11
  60. package/dist/core/mcp-servers.js.map +1 -1
  61. package/dist/core/model-registry.d.ts +3 -1
  62. package/dist/core/model-registry.d.ts.map +1 -1
  63. package/dist/core/model-registry.js +4 -0
  64. package/dist/core/model-registry.js.map +1 -1
  65. package/dist/core/model-runtime.d.ts +6 -0
  66. package/dist/core/model-runtime.d.ts.map +1 -1
  67. package/dist/core/model-runtime.js +22 -18
  68. package/dist/core/model-runtime.js.map +1 -1
  69. package/dist/core/radius.d.ts +2 -0
  70. package/dist/core/radius.d.ts.map +1 -1
  71. package/dist/core/radius.js +2 -0
  72. package/dist/core/radius.js.map +1 -1
  73. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  74. package/dist/core/remote-catalog-provider.js +4 -9
  75. package/dist/core/remote-catalog-provider.js.map +1 -1
  76. package/dist/core/sdk.d.ts.map +1 -1
  77. package/dist/core/sdk.js +1 -0
  78. package/dist/core/sdk.js.map +1 -1
  79. package/dist/core/settings-manager.d.ts +7 -5
  80. package/dist/core/settings-manager.d.ts.map +1 -1
  81. package/dist/core/settings-manager.js +2 -1
  82. package/dist/core/settings-manager.js.map +1 -1
  83. package/dist/core/system-prompt.js +1 -1
  84. package/dist/core/system-prompt.js.map +1 -1
  85. package/dist/core/tasks/format.d.ts +7 -0
  86. package/dist/core/tasks/format.d.ts.map +1 -0
  87. package/dist/core/tasks/format.js +14 -0
  88. package/dist/core/tasks/format.js.map +1 -0
  89. package/dist/core/tasks/history.d.ts.map +1 -1
  90. package/dist/core/tasks/history.js +0 -19
  91. package/dist/core/tasks/history.js.map +1 -1
  92. package/dist/core/tasks/output.d.ts +8 -0
  93. package/dist/core/tasks/output.d.ts.map +1 -1
  94. package/dist/core/tasks/output.js +19 -0
  95. package/dist/core/tasks/output.js.map +1 -1
  96. package/dist/core/tasks/presentation.d.ts +1 -3
  97. package/dist/core/tasks/presentation.d.ts.map +1 -1
  98. package/dist/core/tasks/presentation.js +79 -166
  99. package/dist/core/tasks/presentation.js.map +1 -1
  100. package/dist/core/tasks/runtime.d.ts +16 -9
  101. package/dist/core/tasks/runtime.d.ts.map +1 -1
  102. package/dist/core/tasks/runtime.js +89 -106
  103. package/dist/core/tasks/runtime.js.map +1 -1
  104. package/dist/core/tasks/session.d.ts.map +1 -1
  105. package/dist/core/tasks/session.js +13 -4
  106. package/dist/core/tasks/session.js.map +1 -1
  107. package/dist/core/tasks/store.d.ts +20 -6
  108. package/dist/core/tasks/store.d.ts.map +1 -1
  109. package/dist/core/tasks/store.js +45 -18
  110. package/dist/core/tasks/store.js.map +1 -1
  111. package/dist/core/tasks/types.d.ts +14 -54
  112. package/dist/core/tasks/types.d.ts.map +1 -1
  113. package/dist/core/tasks/types.js +1 -5
  114. package/dist/core/tasks/types.js.map +1 -1
  115. package/dist/core/tools/renderers/bash.d.ts.map +1 -1
  116. package/dist/core/tools/renderers/bash.js +11 -34
  117. package/dist/core/tools/renderers/bash.js.map +1 -1
  118. package/dist/core/tools/shell-execution.d.ts +0 -1
  119. package/dist/core/tools/shell-execution.d.ts.map +1 -1
  120. package/dist/core/tools/shell-execution.js +3 -10
  121. package/dist/core/tools/shell-execution.js.map +1 -1
  122. package/dist/core/tools/shell-tool.d.ts.map +1 -1
  123. package/dist/core/tools/shell-tool.js +2 -4
  124. package/dist/core/tools/shell-tool.js.map +1 -1
  125. package/dist/core/tools/tasks/actions.d.ts +1 -1
  126. package/dist/core/tools/tasks/actions.d.ts.map +1 -1
  127. package/dist/core/tools/tasks/actions.js +26 -12
  128. package/dist/core/tools/tasks/actions.js.map +1 -1
  129. package/dist/core/tools/tasks/constants.d.ts +2 -6
  130. package/dist/core/tools/tasks/constants.d.ts.map +1 -1
  131. package/dist/core/tools/tasks/constants.js +2 -6
  132. package/dist/core/tools/tasks/constants.js.map +1 -1
  133. package/dist/core/tools/tasks/schema.d.ts +1 -1
  134. package/dist/core/tools/tasks/schema.d.ts.map +1 -1
  135. package/dist/core/tools/tasks/schema.js +8 -7
  136. package/dist/core/tools/tasks/schema.js.map +1 -1
  137. package/dist/core/tools/tasks/types.d.ts +8 -38
  138. package/dist/core/tools/tasks/types.d.ts.map +1 -1
  139. package/dist/core/tools/tasks/types.js +6 -11
  140. package/dist/core/tools/tasks/types.js.map +1 -1
  141. package/dist/core/virtual-models.d.ts +2 -0
  142. package/dist/core/virtual-models.d.ts.map +1 -1
  143. package/dist/core/virtual-models.js +19 -12
  144. package/dist/core/virtual-models.js.map +1 -1
  145. package/dist/extensions/btw/agent.d.ts +17 -8
  146. package/dist/extensions/btw/agent.d.ts.map +1 -1
  147. package/dist/extensions/btw/agent.js +74 -76
  148. package/dist/extensions/btw/agent.js.map +1 -1
  149. package/dist/extensions/btw/controller.d.ts +0 -1
  150. package/dist/extensions/btw/controller.d.ts.map +1 -1
  151. package/dist/extensions/btw/controller.js +26 -33
  152. package/dist/extensions/btw/controller.js.map +1 -1
  153. package/dist/extensions/btw/panel.d.ts +13 -14
  154. package/dist/extensions/btw/panel.d.ts.map +1 -1
  155. package/dist/extensions/btw/panel.js +38 -29
  156. package/dist/extensions/btw/panel.js.map +1 -1
  157. package/dist/extensions/codemode/execute.d.ts.map +1 -1
  158. package/dist/extensions/codemode/execute.js +197 -51
  159. package/dist/extensions/codemode/execute.js.map +1 -1
  160. package/dist/extensions/codemode/renderer.d.ts.map +1 -1
  161. package/dist/extensions/codemode/renderer.js +43 -25
  162. package/dist/extensions/codemode/renderer.js.map +1 -1
  163. package/dist/extensions/codemode/tool.d.ts +12 -11
  164. package/dist/extensions/codemode/tool.d.ts.map +1 -1
  165. package/dist/extensions/codemode/tool.js +73 -129
  166. package/dist/extensions/codemode/tool.js.map +1 -1
  167. package/dist/extensions/codemode/worker.d.ts +1 -1
  168. package/dist/extensions/codemode/worker.js +1 -1
  169. package/dist/extensions/codemode/worker.js.map +1 -1
  170. package/dist/extensions/deepwiki/schema.d.ts +1 -1
  171. package/dist/extensions/index.d.ts.map +1 -1
  172. package/dist/extensions/index.js +0 -2
  173. package/dist/extensions/index.js.map +1 -1
  174. package/dist/extensions/mcp/cli.d.ts.map +1 -1
  175. package/dist/extensions/mcp/cli.js +20 -5
  176. package/dist/extensions/mcp/cli.js.map +1 -1
  177. package/dist/extensions/mcp/config.d.ts +4 -2
  178. package/dist/extensions/mcp/config.d.ts.map +1 -1
  179. package/dist/extensions/mcp/config.js +14 -2
  180. package/dist/extensions/mcp/config.js.map +1 -1
  181. package/dist/extensions/mcp/index.d.ts +32 -8
  182. package/dist/extensions/mcp/index.d.ts.map +1 -1
  183. package/dist/extensions/mcp/index.js +235 -61
  184. package/dist/extensions/mcp/index.js.map +1 -1
  185. package/dist/extensions/mcp/oauth.d.ts +10 -7
  186. package/dist/extensions/mcp/oauth.d.ts.map +1 -1
  187. package/dist/extensions/mcp/oauth.js +56 -31
  188. package/dist/extensions/mcp/oauth.js.map +1 -1
  189. package/dist/extensions/mcp/runtime.d.ts +2 -0
  190. package/dist/extensions/mcp/runtime.d.ts.map +1 -1
  191. package/dist/extensions/mcp/runtime.js +16 -9
  192. package/dist/extensions/mcp/runtime.js.map +1 -1
  193. package/dist/extensions/mcp/tools.d.ts +5 -4
  194. package/dist/extensions/mcp/tools.d.ts.map +1 -1
  195. package/dist/extensions/mcp/tools.js +33 -15
  196. package/dist/extensions/mcp/tools.js.map +1 -1
  197. package/dist/extensions/mcp/ui.d.ts.map +1 -1
  198. package/dist/extensions/mcp/ui.js +4 -2
  199. package/dist/extensions/mcp/ui.js.map +1 -1
  200. package/dist/extensions/provider/catalog.d.ts +8 -1
  201. package/dist/extensions/provider/catalog.d.ts.map +1 -1
  202. package/dist/extensions/provider/catalog.js +31 -0
  203. package/dist/extensions/provider/catalog.js.map +1 -1
  204. package/dist/extensions/provider/connection.d.ts +4 -1
  205. package/dist/extensions/provider/connection.d.ts.map +1 -1
  206. package/dist/extensions/provider/connection.js +1 -5
  207. package/dist/extensions/provider/connection.js.map +1 -1
  208. package/dist/extensions/provider/editing.d.ts +36 -0
  209. package/dist/extensions/provider/editing.d.ts.map +1 -0
  210. package/dist/extensions/provider/editing.js +99 -0
  211. package/dist/extensions/provider/editing.js.map +1 -0
  212. package/dist/extensions/provider/json-fields.d.ts +5 -0
  213. package/dist/extensions/provider/json-fields.d.ts.map +1 -0
  214. package/dist/extensions/provider/json-fields.js +31 -0
  215. package/dist/extensions/provider/json-fields.js.map +1 -0
  216. package/dist/extensions/provider/store.d.ts +1 -4
  217. package/dist/extensions/provider/store.d.ts.map +1 -1
  218. package/dist/extensions/provider/store.js +2 -30
  219. package/dist/extensions/provider/store.js.map +1 -1
  220. package/dist/extensions/provider/ui/builtin-data.d.ts +0 -2
  221. package/dist/extensions/provider/ui/builtin-data.d.ts.map +1 -1
  222. package/dist/extensions/provider/ui/builtin-data.js +14 -79
  223. package/dist/extensions/provider/ui/builtin-data.js.map +1 -1
  224. package/dist/extensions/provider/ui/compat.d.ts.map +1 -1
  225. package/dist/extensions/provider/ui/compat.js +6 -9
  226. package/dist/extensions/provider/ui/compat.js.map +1 -1
  227. package/dist/extensions/provider/ui/controls.d.ts +48 -0
  228. package/dist/extensions/provider/ui/controls.d.ts.map +1 -0
  229. package/dist/extensions/provider/ui/controls.js +108 -0
  230. package/dist/extensions/provider/ui/controls.js.map +1 -0
  231. package/dist/extensions/provider/ui/dictionary.d.ts.map +1 -1
  232. package/dist/extensions/provider/ui/dictionary.js +6 -9
  233. package/dist/extensions/provider/ui/dictionary.js.map +1 -1
  234. package/dist/extensions/provider/ui/editor.d.ts +3 -3
  235. package/dist/extensions/provider/ui/editor.d.ts.map +1 -1
  236. package/dist/extensions/provider/ui/editor.js +35 -140
  237. package/dist/extensions/provider/ui/editor.js.map +1 -1
  238. package/dist/extensions/provider/ui/fetch-models.d.ts +0 -3
  239. package/dist/extensions/provider/ui/fetch-models.d.ts.map +1 -1
  240. package/dist/extensions/provider/ui/fetch-models.js +49 -44
  241. package/dist/extensions/provider/ui/fetch-models.js.map +1 -1
  242. package/dist/extensions/provider/ui/model-fields.d.ts.map +1 -1
  243. package/dist/extensions/provider/ui/model-fields.js +11 -14
  244. package/dist/extensions/provider/ui/model-fields.js.map +1 -1
  245. package/dist/extensions/provider/ui/model-options.d.ts +4 -34
  246. package/dist/extensions/provider/ui/model-options.d.ts.map +1 -1
  247. package/dist/extensions/provider/ui/model-options.js +90 -271
  248. package/dist/extensions/provider/ui/model-options.js.map +1 -1
  249. package/dist/extensions/provider/ui/pane.d.ts +4 -18
  250. package/dist/extensions/provider/ui/pane.d.ts.map +1 -1
  251. package/dist/extensions/provider/ui/pane.js.map +1 -1
  252. package/dist/extensions/provider/ui/provider-fields.d.ts +2 -19
  253. package/dist/extensions/provider/ui/provider-fields.d.ts.map +1 -1
  254. package/dist/extensions/provider/ui/provider-fields.js +58 -171
  255. package/dist/extensions/provider/ui/provider-fields.js.map +1 -1
  256. package/dist/extensions/provider/ui/thinking-map.d.ts.map +1 -1
  257. package/dist/extensions/provider/ui/thinking-map.js +6 -9
  258. package/dist/extensions/provider/ui/thinking-map.js.map +1 -1
  259. package/dist/extensions/question/detail-pane.d.ts +7 -2
  260. package/dist/extensions/question/detail-pane.d.ts.map +1 -1
  261. package/dist/extensions/question/detail-pane.js +16 -5
  262. package/dist/extensions/question/detail-pane.js.map +1 -1
  263. package/dist/extensions/question/dialog-view.d.ts +41 -0
  264. package/dist/extensions/question/dialog-view.d.ts.map +1 -0
  265. package/dist/extensions/question/dialog-view.js +329 -0
  266. package/dist/extensions/question/dialog-view.js.map +1 -0
  267. package/dist/extensions/question/dialog.d.ts +3 -3
  268. package/dist/extensions/question/dialog.d.ts.map +1 -1
  269. package/dist/extensions/question/dialog.js +220 -634
  270. package/dist/extensions/question/dialog.js.map +1 -1
  271. package/dist/extensions/question/index.d.ts.map +1 -1
  272. package/dist/extensions/question/index.js +2 -3
  273. package/dist/extensions/question/index.js.map +1 -1
  274. package/dist/extensions/question/render.d.ts.map +1 -1
  275. package/dist/extensions/question/render.js +22 -32
  276. package/dist/extensions/question/render.js.map +1 -1
  277. package/dist/extensions/question/results.d.ts.map +1 -1
  278. package/dist/extensions/question/results.js +56 -12
  279. package/dist/extensions/question/results.js.map +1 -1
  280. package/dist/extensions/question/schema.d.ts +21 -6
  281. package/dist/extensions/question/schema.d.ts.map +1 -1
  282. package/dist/extensions/question/schema.js.map +1 -1
  283. package/dist/extensions/question/state.d.ts +9 -7
  284. package/dist/extensions/question/state.d.ts.map +1 -1
  285. package/dist/extensions/question/state.js +63 -54
  286. package/dist/extensions/question/state.js.map +1 -1
  287. package/dist/extensions/question/types.d.ts +41 -18
  288. package/dist/extensions/question/types.d.ts.map +1 -1
  289. package/dist/extensions/question/types.js.map +1 -1
  290. package/dist/extensions/statusline/index.d.ts +4 -0
  291. package/dist/extensions/statusline/index.d.ts.map +1 -1
  292. package/dist/extensions/statusline/index.js +18 -355
  293. package/dist/extensions/statusline/index.js.map +1 -1
  294. package/dist/extensions/statusline/render.d.ts +19 -0
  295. package/dist/extensions/statusline/render.d.ts.map +1 -0
  296. package/dist/extensions/statusline/render.js +163 -0
  297. package/dist/extensions/statusline/render.js.map +1 -0
  298. package/dist/extensions/statusline/usage.d.ts +12 -0
  299. package/dist/extensions/statusline/usage.d.ts.map +1 -0
  300. package/dist/extensions/statusline/usage.js +36 -0
  301. package/dist/extensions/statusline/usage.js.map +1 -0
  302. package/dist/extensions/tool-search/tool.d.ts +5 -4
  303. package/dist/extensions/tool-search/tool.d.ts.map +1 -1
  304. package/dist/extensions/tool-search/tool.js +7 -28
  305. package/dist/extensions/tool-search/tool.js.map +1 -1
  306. package/dist/extensions/web-search/execute.d.ts +1 -5
  307. package/dist/extensions/web-search/execute.d.ts.map +1 -1
  308. package/dist/extensions/web-search/execute.js +4 -9
  309. package/dist/extensions/web-search/execute.js.map +1 -1
  310. package/dist/extensions/web-search/format.d.ts +12 -3
  311. package/dist/extensions/web-search/format.d.ts.map +1 -1
  312. package/dist/extensions/web-search/format.js +33 -25
  313. package/dist/extensions/web-search/format.js.map +1 -1
  314. package/dist/extensions/web-search/index.d.ts.map +1 -1
  315. package/dist/extensions/web-search/index.js +6 -29
  316. package/dist/extensions/web-search/index.js.map +1 -1
  317. package/dist/extensions/web-search/providers/deepseek.d.ts.map +1 -1
  318. package/dist/extensions/web-search/providers/deepseek.js +0 -1
  319. package/dist/extensions/web-search/providers/deepseek.js.map +1 -1
  320. package/dist/extensions/web-search/providers/http.d.ts +1 -1
  321. package/dist/extensions/web-search/providers/http.d.ts.map +1 -1
  322. package/dist/extensions/web-search/providers/http.js.map +1 -1
  323. package/dist/extensions/web-search/providers/minimax.d.ts.map +1 -1
  324. package/dist/extensions/web-search/providers/minimax.js +0 -1
  325. package/dist/extensions/web-search/providers/minimax.js.map +1 -1
  326. package/dist/extensions/web-search/render.d.ts +7 -2
  327. package/dist/extensions/web-search/render.d.ts.map +1 -1
  328. package/dist/extensions/web-search/render.js +32 -4
  329. package/dist/extensions/web-search/render.js.map +1 -1
  330. package/dist/extensions/web-search/results.d.ts.map +1 -1
  331. package/dist/extensions/web-search/results.js +3 -8
  332. package/dist/extensions/web-search/results.js.map +1 -1
  333. package/dist/extensions/web-search/types.d.ts +4 -2
  334. package/dist/extensions/web-search/types.d.ts.map +1 -1
  335. package/dist/extensions/web-search/types.js.map +1 -1
  336. package/dist/index.d.ts +2 -4
  337. package/dist/index.d.ts.map +1 -1
  338. package/dist/index.js +0 -1
  339. package/dist/index.js.map +1 -1
  340. package/dist/main.d.ts.map +1 -1
  341. package/dist/main.js +6 -0
  342. package/dist/main.js.map +1 -1
  343. package/dist/modes/interactive/components/oauth-selector.d.ts +8 -2
  344. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  345. package/dist/modes/interactive/components/oauth-selector.js +24 -21
  346. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  347. package/dist/modes/interactive/components/pi-logo-animation.d.ts +68 -0
  348. package/dist/modes/interactive/components/pi-logo-animation.d.ts.map +1 -0
  349. package/dist/modes/interactive/components/pi-logo-animation.js +1076 -0
  350. package/dist/modes/interactive/components/pi-logo-animation.js.map +1 -0
  351. package/dist/modes/interactive/components/pi-logo-animation.lazy.d.ts +7 -0
  352. package/dist/modes/interactive/components/pi-logo-animation.lazy.d.ts.map +1 -0
  353. package/dist/modes/interactive/components/pi-logo-animation.lazy.js +12 -0
  354. package/dist/modes/interactive/components/pi-logo-animation.lazy.js.map +1 -0
  355. package/dist/modes/interactive/components/pi-logo.d.ts +7 -0
  356. package/dist/modes/interactive/components/pi-logo.d.ts.map +1 -1
  357. package/dist/modes/interactive/components/pi-logo.js +13 -1
  358. package/dist/modes/interactive/components/pi-logo.js.map +1 -1
  359. package/dist/modes/interactive/components/radius-login-selector.d.ts +15 -0
  360. package/dist/modes/interactive/components/radius-login-selector.d.ts.map +1 -0
  361. package/dist/modes/interactive/components/radius-login-selector.js +83 -0
  362. package/dist/modes/interactive/components/radius-login-selector.js.map +1 -0
  363. package/dist/modes/interactive/components/settings-selector.d.ts +3 -3
  364. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  365. package/dist/modes/interactive/components/settings-selector.js +5 -5
  366. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  367. package/dist/modes/interactive/components/status-marker.d.ts +0 -2
  368. package/dist/modes/interactive/components/status-marker.d.ts.map +1 -1
  369. package/dist/modes/interactive/components/status-marker.js +0 -4
  370. package/dist/modes/interactive/components/status-marker.js.map +1 -1
  371. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  372. package/dist/modes/interactive/components/user-message.js +5 -4
  373. package/dist/modes/interactive/components/user-message.js.map +1 -1
  374. package/dist/modes/interactive/components/visual-truncate.d.ts +27 -3
  375. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
  376. package/dist/modes/interactive/components/visual-truncate.js +36 -6
  377. package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
  378. package/dist/modes/interactive/interactive-mode.d.ts +10 -0
  379. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  380. package/dist/modes/interactive/interactive-mode.js +167 -40
  381. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  382. package/dist/modes/interactive/tasks/completion-render.d.ts +1 -1
  383. package/dist/modes/interactive/tasks/completion-render.d.ts.map +1 -1
  384. package/dist/modes/interactive/tasks/completion-render.js +28 -82
  385. package/dist/modes/interactive/tasks/completion-render.js.map +1 -1
  386. package/dist/modes/interactive/tasks/index.d.ts.map +1 -1
  387. package/dist/modes/interactive/tasks/index.js +18 -13
  388. package/dist/modes/interactive/tasks/index.js.map +1 -1
  389. package/dist/modes/interactive/tasks/inspector.d.ts +35 -0
  390. package/dist/modes/interactive/tasks/inspector.d.ts.map +1 -0
  391. package/dist/modes/interactive/tasks/inspector.js +93 -0
  392. package/dist/modes/interactive/tasks/inspector.js.map +1 -0
  393. package/dist/modes/interactive/tasks/layout.d.ts +40 -0
  394. package/dist/modes/interactive/tasks/layout.d.ts.map +1 -0
  395. package/dist/modes/interactive/tasks/layout.js +212 -0
  396. package/dist/modes/interactive/tasks/layout.js.map +1 -0
  397. package/dist/modes/interactive/tasks/list.d.ts +21 -0
  398. package/dist/modes/interactive/tasks/list.d.ts.map +1 -0
  399. package/dist/modes/interactive/tasks/list.js +96 -0
  400. package/dist/modes/interactive/tasks/list.js.map +1 -0
  401. package/dist/modes/interactive/tasks/manager.d.ts +29 -36
  402. package/dist/modes/interactive/tasks/manager.d.ts.map +1 -1
  403. package/dist/modes/interactive/tasks/manager.js +315 -315
  404. package/dist/modes/interactive/tasks/manager.js.map +1 -1
  405. package/dist/modes/interactive/tasks/model.d.ts +21 -0
  406. package/dist/modes/interactive/tasks/model.d.ts.map +1 -0
  407. package/dist/modes/interactive/tasks/model.js +41 -0
  408. package/dist/modes/interactive/tasks/model.js.map +1 -0
  409. package/dist/modes/interactive/tasks/render.d.ts +5 -19
  410. package/dist/modes/interactive/tasks/render.d.ts.map +1 -1
  411. package/dist/modes/interactive/tasks/render.js +18 -102
  412. package/dist/modes/interactive/tasks/render.js.map +1 -1
  413. package/dist/modes/interactive/tasks/task-view.d.ts +8 -48
  414. package/dist/modes/interactive/tasks/task-view.d.ts.map +1 -1
  415. package/dist/modes/interactive/tasks/task-view.js +11 -51
  416. package/dist/modes/interactive/tasks/task-view.js.map +1 -1
  417. package/dist/modes/interactive/tasks/text.d.ts +1 -7
  418. package/dist/modes/interactive/tasks/text.d.ts.map +1 -1
  419. package/dist/modes/interactive/tasks/text.js +6 -29
  420. package/dist/modes/interactive/tasks/text.js.map +1 -1
  421. package/dist/modes/interactive/tasks/viewport.d.ts +2 -0
  422. package/dist/modes/interactive/tasks/viewport.d.ts.map +1 -1
  423. package/dist/modes/interactive/tasks/viewport.js +17 -7
  424. package/dist/modes/interactive/tasks/viewport.js.map +1 -1
  425. package/dist/modes/interactive/tasks/views.d.ts +9 -0
  426. package/dist/modes/interactive/tasks/views.d.ts.map +1 -0
  427. package/dist/modes/interactive/tasks/views.js +42 -0
  428. package/dist/modes/interactive/tasks/views.js.map +1 -0
  429. package/dist/modes/interactive/theme/system-theme.d.ts +2 -1
  430. package/dist/modes/interactive/theme/system-theme.d.ts.map +1 -1
  431. package/dist/modes/interactive/theme/system-theme.js +16 -5
  432. package/dist/modes/interactive/theme/system-theme.js.map +1 -1
  433. package/docs/bundled/README.md +0 -1
  434. package/docs/bundled/extensions/question.md +2 -2
  435. package/docs/bundled/extensions/statusline.md +24 -15
  436. package/docs/bundled/tasks.md +34 -48
  437. package/docs/codemode.md +207 -0
  438. package/docs/docs.json +4 -4
  439. package/docs/environment-variables.md +1 -1
  440. package/docs/extensions.md +7 -9
  441. package/docs/keybindings.md +13 -6
  442. package/docs/mcp.md +142 -82
  443. package/docs/models.md +21 -0
  444. package/docs/providers.md +8 -0
  445. package/docs/sdk.md +2 -2
  446. package/docs/session-format.md +12 -22
  447. package/docs/settings.md +4 -2
  448. package/docs/tui.md +1 -1
  449. package/docs/usage.md +6 -16
  450. package/examples/README.md +1 -1
  451. package/examples/extensions/README.md +1 -2
  452. package/examples/extensions/built-in-tool-renderer.ts +16 -40
  453. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  454. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  455. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  456. package/examples/extensions/gondolin/package-lock.json +2 -2
  457. package/examples/extensions/gondolin/package.json +1 -1
  458. package/examples/extensions/minimal-mode.ts +24 -96
  459. package/examples/extensions/sandbox/package-lock.json +2 -2
  460. package/examples/extensions/sandbox/package.json +1 -1
  461. package/examples/extensions/with-deps/package-lock.json +2 -2
  462. package/examples/extensions/with-deps/package.json +1 -1
  463. package/examples/sdk/14-codemode-mcp.ts +2 -2
  464. package/npm-shrinkwrap.json +69 -58
  465. package/package.json +11 -10
  466. package/dist/bundle/chunks/anthropic-messages-KIXY7EDT.js +0 -6
  467. package/dist/bundle/chunks/chunk-CLLDCO64.js +0 -2
  468. package/dist/bundle/chunks/chunk-UUSTLCVC.js +0 -2
  469. package/dist/bundle/chunks/chunk-VWCWZD6E.js +0 -2
  470. package/dist/bundle/chunks/virtual-modules-TQRORWJQ.js +0 -2
  471. package/dist/core/tasks/view-data.d.ts +0 -8
  472. package/dist/core/tasks/view-data.d.ts.map +0 -1
  473. package/dist/core/tasks/view-data.js +0 -61
  474. package/dist/core/tasks/view-data.js.map +0 -1
  475. package/dist/core/tasks/view.d.ts +0 -30
  476. package/dist/core/tasks/view.d.ts.map +0 -1
  477. package/dist/core/tasks/view.js +0 -50
  478. package/dist/core/tasks/view.js.map +0 -1
  479. package/dist/core/tools/renderers/shell-task.d.ts +0 -4
  480. package/dist/core/tools/renderers/shell-task.d.ts.map +0 -1
  481. package/dist/core/tools/renderers/shell-task.js +0 -35
  482. package/dist/core/tools/renderers/shell-task.js.map +0 -1
  483. package/dist/extensions/todo/constants.d.ts +0 -16
  484. package/dist/extensions/todo/constants.d.ts.map +0 -1
  485. package/dist/extensions/todo/constants.js +0 -30
  486. package/dist/extensions/todo/constants.js.map +0 -1
  487. package/dist/extensions/todo/index.d.ts +0 -3
  488. package/dist/extensions/todo/index.d.ts.map +0 -1
  489. package/dist/extensions/todo/index.js +0 -98
  490. package/dist/extensions/todo/index.js.map +0 -1
  491. package/dist/extensions/todo/schema.d.ts +0 -60
  492. package/dist/extensions/todo/schema.d.ts.map +0 -1
  493. package/dist/extensions/todo/schema.js +0 -56
  494. package/dist/extensions/todo/schema.js.map +0 -1
  495. package/dist/extensions/todo/state.d.ts +0 -34
  496. package/dist/extensions/todo/state.d.ts.map +0 -1
  497. package/dist/extensions/todo/state.js +0 -425
  498. package/dist/extensions/todo/state.js.map +0 -1
  499. package/dist/extensions/todo/view.d.ts +0 -36
  500. package/dist/extensions/todo/view.d.ts.map +0 -1
  501. package/dist/extensions/todo/view.js +0 -580
  502. package/dist/extensions/todo/view.js.map +0 -1
  503. package/dist/extensions/todo/widget.d.ts +0 -15
  504. package/dist/extensions/todo/widget.d.ts.map +0 -1
  505. package/dist/extensions/todo/widget.js +0 -50
  506. package/dist/extensions/todo/widget.js.map +0 -1
  507. package/dist/modes/interactive/tasks/fallback-view.d.ts +0 -4
  508. package/dist/modes/interactive/tasks/fallback-view.d.ts.map +0 -1
  509. package/dist/modes/interactive/tasks/fallback-view.js +0 -27
  510. package/dist/modes/interactive/tasks/fallback-view.js.map +0 -1
  511. package/docs/bundled/extensions/todo.md +0 -104
  512. package/examples/extensions/todo.ts +0 -297
@@ -1,372 +1,35 @@
1
- import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
2
- import { addUsageToTotals, createUsageTotals, getAccountedUsages, getTaskUsageRecord, } from "../../core/usage-totals.js";
3
- const CONTEXT_WARNING_PERCENT = 40;
4
- const CONTEXT_ERROR_PERCENT = 80;
5
- const MIN_GAP = 1;
6
- function isTui(ctx) {
7
- return ctx.mode === "tui";
8
- }
9
- /** Shorten a path to `~` relative to the user's home directory. */
10
- function formatWorkingDirectory(cwd) {
11
- const rawHomeDirectory = process.env.USERPROFILE || process.env.HOME || "";
12
- const homeDirectory = rawHomeDirectory.replace(/[\\/]+$/, "");
13
- if (!homeDirectory)
14
- return cwd;
15
- const normalizePath = (filePath) => filePath.replace(/\\/g, "/").replace(/\/+$/, "").toLowerCase();
16
- const normalizedHomeDirectory = normalizePath(homeDirectory);
17
- const normalizedCwd = normalizePath(cwd);
18
- if (normalizedCwd === normalizedHomeDirectory)
19
- return "~";
20
- if (normalizedCwd.startsWith(`${normalizedHomeDirectory}/`)) {
21
- return `~${cwd.slice(homeDirectory.length).replace(/\\/g, "/")}`;
22
- }
23
- return cwd;
24
- }
25
- /** Collapse a display path to `~/basename` or bare basename when tight. */
26
- function pathBasename(displayPath) {
27
- const normalized = displayPath.replace(/\\/g, "/").replace(/\/+$/, "");
28
- if (!normalized || normalized === "~")
29
- return normalized || displayPath;
30
- const slash = normalized.lastIndexOf("/");
31
- if (slash < 0)
32
- return normalized;
33
- const base = normalized.slice(slash + 1);
34
- if (normalized.startsWith("~/"))
35
- return `~/${base}`;
36
- return base;
37
- }
38
- /** Format token counts like Pi's native footer: 999, 1.2k, 34k, 1.0M. */
39
- function formatTokenCount(tokenCount) {
40
- if (tokenCount < 1000)
41
- return `${tokenCount}`;
42
- if (tokenCount < 10_000)
43
- return `${(tokenCount / 1000).toFixed(1)}k`;
44
- if (tokenCount < 1_000_000)
45
- return `${Math.round(tokenCount / 1000)}k`;
46
- if (tokenCount < 10_000_000)
47
- return `${(tokenCount / 1_000_000).toFixed(1)}M`;
48
- return `${Math.round(tokenCount / 1_000_000)}M`;
49
- }
50
- /** Flatten extension status text to a single printable line. */
51
- function sanitizeStatus(text) {
52
- return text
53
- .replace(/[\r\n\t]/g, " ")
54
- .replace(/ +/g, " ")
55
- .trim();
56
- }
57
- function joinSegments(segments, separator) {
58
- return segments.filter((segment) => segment.length > 0).join(separator);
59
- }
60
- /**
61
- * Latest thinking level and parent cache hit rate, plus accounted branch usage.
62
- * Cached across footer paints while leaf identity + usage fingerprint hold.
63
- */
64
- function entryUsage(entry) {
65
- if (entry.type === "message") {
66
- if (entry.message.role === "assistant")
67
- return entry.message.usage;
68
- if (entry.message.role === "toolResult")
69
- return entry.message.usage;
70
- return undefined;
71
- }
72
- if (entry.type === "branch_summary" || entry.type === "compaction")
73
- return entry.usage;
74
- return getTaskUsageRecord(entry)?.usage;
75
- }
76
- function computeBranchStats(branchEntries) {
77
- let thinkingLevel = "off";
78
- const usageTotals = createUsageTotals();
79
- let latestCacheHitPercent;
80
- for (const usage of getAccountedUsages(branchEntries))
81
- addUsageToTotals(usageTotals, usage);
82
- for (const entry of branchEntries) {
83
- if (entry.type === "thinking_level_change") {
84
- thinkingLevel = entry.thinkingLevel;
85
- continue;
86
- }
87
- const usage = entryUsage(entry);
88
- if (!usage)
89
- continue;
90
- // Keep CH tied to the latest assistant request, matching the native
91
- // footer; tool and summary usage contributes only to cumulative totals.
92
- if (entry.type === "message" && entry.message.role === "assistant") {
93
- const latestPromptTokens = usage.input + usage.cacheRead + usage.cacheWrite;
94
- const latestRequestUsedCache = usage.cacheRead > 0 || usage.cacheWrite > 0;
95
- latestCacheHitPercent =
96
- latestRequestUsedCache && latestPromptTokens > 0 ? (usage.cacheRead / latestPromptTokens) * 100 : undefined;
97
- }
98
- }
99
- return { thinkingLevel, usage: { ...usageTotals, latestCacheHitPercent } };
100
- }
101
- /**
102
- * Fingerprint the leaf so streaming usage updates invalidate even when the
103
- * SessionEntry object identity is reused in place.
104
- */
105
- function leafUsageFingerprint(entry) {
106
- if (!entry)
107
- return "";
108
- const usage = entryUsage(entry);
109
- if (!usage)
110
- return "";
111
- return [usage.input, usage.output, usage.cacheRead, usage.cacheWrite, usage.cost.total].join(":");
112
- }
113
- function getBranchStats(branchEntries, cache) {
114
- const lastEntry = branchEntries.length > 0 ? branchEntries[branchEntries.length - 1] : undefined;
115
- const leafUsage = leafUsageFingerprint(lastEntry);
116
- const cached = cache.current;
117
- if (cached &&
118
- cached.length === branchEntries.length &&
119
- cached.lastEntry === lastEntry &&
120
- cached.leafUsage === leafUsage) {
121
- return cached.stats;
122
- }
123
- const stats = computeBranchStats(branchEntries);
124
- cache.current = { length: branchEntries.length, lastEntry, leafUsage, stats };
125
- return stats;
126
- }
127
- function getBranchEntries(getLeafId, getBranch, cache) {
128
- const leafId = getLeafId();
129
- const cached = cache.current;
130
- if (cached && cached.leafId === leafId)
131
- return cached.entries;
132
- const entries = getBranch();
133
- cache.current = { leafId, entries };
134
- return entries;
135
- }
136
- function formatContextUsage(ctx, theme) {
137
- const contextUsage = ctx.getContextUsage();
138
- const contextWindow = contextUsage?.contextWindow ?? ctx.model?.contextWindow;
139
- const contextWindowSuffix = contextWindow ? `/${formatTokenCount(contextWindow)}` : "";
140
- if (contextUsage?.percent == null) {
141
- return theme.fg("accent", `CTX ?%${contextWindowSuffix}`);
142
- }
143
- const label = `CTX ${contextUsage.percent.toFixed(1)}%${contextWindowSuffix}`;
144
- if (contextUsage.percent > CONTEXT_ERROR_PERCENT)
145
- return theme.fg("error", label);
146
- if (contextUsage.percent > CONTEXT_WARNING_PERCENT)
147
- return theme.fg("warning", label);
148
- return theme.fg("accent", label);
149
- }
150
- function formatUsageSummary(summary, usesSubscription, theme, options = { includeCacheRead: true, includeCacheWrite: true }) {
151
- const usageParts = [];
152
- if (summary.input > 0)
153
- usageParts.push(`↑${formatTokenCount(summary.input)}`);
154
- if (summary.output > 0)
155
- usageParts.push(`↓${formatTokenCount(summary.output)}`);
156
- if (options.includeCacheRead && summary.cacheRead > 0) {
157
- usageParts.push(`R${formatTokenCount(summary.cacheRead)}`);
158
- }
159
- if (options.includeCacheWrite && summary.cacheWrite > 0) {
160
- usageParts.push(`W${formatTokenCount(summary.cacheWrite)}`);
161
- }
162
- if (summary.latestCacheHitPercent !== undefined) {
163
- usageParts.push(`CH${summary.latestCacheHitPercent.toFixed(1)}%`);
164
- }
165
- if (summary.cost > 0) {
166
- usageParts.push(`$${summary.cost.toFixed(3)}${usesSubscription ? " (sub)" : ""}`);
167
- }
168
- if (usageParts.length === 0)
169
- return "";
170
- return theme.fg("dim", usageParts.join(" "));
171
- }
172
- /** True when the string already carries SGR color codes from an extension. */
173
- function hasAnsiColor(text) {
174
- return text.includes("\x1b[");
175
- }
176
- function formatExtensionStatuses(statuses, theme) {
177
- const parts = Array.from(statuses.entries())
178
- .sort(([firstKey], [secondKey]) => firstKey.localeCompare(secondKey))
179
- .map(([, text]) => sanitizeStatus(text))
180
- .filter(Boolean)
181
- // Extensions may pre-color status text. Don't re-wrap those.
182
- .map((text) => (hasAnsiColor(text) ? text : theme.fg("muted", text)));
183
- return parts.join(" ");
184
- }
185
- /** Left-align `left`, right-align `right`, filling the gap with spaces. */
186
- function layoutLeftRight(left, right, width, theme) {
187
- const ellipsis = theme.fg("dim", "...");
188
- if (width <= 0)
189
- return "";
190
- if (!right)
191
- return truncateToWidth(left, width, ellipsis);
192
- if (!left) {
193
- const rightWidth = visibleWidth(right);
194
- if (rightWidth >= width)
195
- return truncateToWidth(right, width, ellipsis);
196
- return `${" ".repeat(width - rightWidth)}${right}`;
197
- }
198
- let leftText = left;
199
- let rightText = right;
200
- let leftWidth = visibleWidth(leftText);
201
- let rightWidth = visibleWidth(rightText);
202
- if (leftWidth + rightWidth + MIN_GAP > width) {
203
- // Prefer keeping the right side readable; give it up to ~45% when both compete.
204
- const maxRightWidth = Math.min(rightWidth, Math.max(8, Math.floor(width * 0.45)));
205
- if (rightWidth > maxRightWidth) {
206
- rightText = truncateToWidth(rightText, maxRightWidth, ellipsis);
207
- rightWidth = visibleWidth(rightText);
208
- }
209
- const maxLeftWidth = width - rightWidth - MIN_GAP;
210
- if (maxLeftWidth < 1)
211
- return truncateToWidth(rightText, width, ellipsis);
212
- leftText = truncateToWidth(leftText, maxLeftWidth, ellipsis);
213
- leftWidth = visibleWidth(leftText);
214
- }
215
- const gap = Math.max(MIN_GAP, width - leftWidth - rightWidth);
216
- return `${leftText}${" ".repeat(gap)}${rightText}`;
217
- }
218
- /**
219
- * Line 2 zones: CTX left, extension status pinned to the line center, usage
220
- * right. The status anchors to the absolute center of the line so it does not
221
- * drift as the usage cluster grows; when the side zones collide with the
222
- * center anchor, the free space is balanced instead. Drops the status first
223
- * when space is tight; caller should pass progressively smaller rights.
224
- */
225
- function layoutSecondaryLine(contextText, statusText, usageText, width, theme) {
226
- const ellipsis = theme.fg("dim", "...");
227
- if (!statusText) {
228
- if (!usageText)
229
- return truncateToWidth(contextText, width, ellipsis);
230
- return layoutLeftRight(contextText, usageText, width, theme);
231
- }
232
- const contextWidth = visibleWidth(contextText);
233
- const usageWidth = visibleWidth(usageText);
234
- const statusWidth = visibleWidth(statusText);
235
- const needed = contextWidth + usageWidth + statusWidth + MIN_GAP * 2;
236
- if (needed <= width) {
237
- const centerStart = Math.floor((width - statusWidth) / 2);
238
- const centeredLeftPad = centerStart - contextWidth;
239
- const centeredRightPad = width - centerStart - statusWidth - usageWidth;
240
- if (centeredLeftPad >= MIN_GAP && centeredRightPad >= MIN_GAP) {
241
- return `${contextText}${" ".repeat(centeredLeftPad)}${statusText}${" ".repeat(centeredRightPad)}${usageText}`;
242
- }
243
- const free = width - contextWidth - usageWidth - statusWidth;
244
- const leftPad = Math.floor(free / 2);
245
- const rightPad = free - leftPad;
246
- return `${contextText}${" ".repeat(leftPad)}${statusText}${" ".repeat(rightPad)}${usageText}`;
247
- }
248
- // Not enough room for a full middle status — keep CTX · usage, drop status.
249
- return layoutLeftRight(contextText, usageText, width, theme);
250
- }
251
- function fitsLeftRight(left, right, width) {
252
- if (!right)
253
- return visibleWidth(left) <= width;
254
- if (!left)
255
- return visibleWidth(right) <= width;
256
- return visibleWidth(left) + visibleWidth(right) + MIN_GAP <= width;
257
- }
258
- /** Progressive drop: branch → short path → drop provider → truncate. */
259
- function fitPrimaryLine(options) {
260
- const { modelWithProvider, modelName, effortPart, cwdFull, cwdShort, branchPart, separator, width, theme } = options;
261
- const leftRich = joinSegments([modelWithProvider, effortPart], separator);
262
- const leftPlain = joinSegments([modelName, effortPart], separator);
263
- const candidates = [
264
- { left: leftRich, right: joinSegments([cwdFull, branchPart], separator) },
265
- { left: leftRich, right: cwdFull },
266
- { left: leftRich, right: joinSegments([cwdShort, branchPart], separator) },
267
- { left: leftRich, right: cwdShort },
268
- { left: leftPlain, right: joinSegments([cwdShort, branchPart], separator) },
269
- { left: leftPlain, right: cwdShort },
270
- { left: leftPlain, right: "" },
271
- ];
272
- for (const candidate of candidates) {
273
- if (fitsLeftRight(candidate.left, candidate.right, width)) {
274
- return layoutLeftRight(candidate.left, candidate.right, width, theme);
275
- }
276
- }
277
- return layoutLeftRight(leftPlain, cwdShort, width, theme);
278
- }
279
- /** Progressive drop on the usage side: full → drop W → drop R; status fills middle when space allows. */
280
- function fitSecondaryLine(options) {
281
- const { contextText, statusText, usageCandidates, width, theme } = options;
282
- if (usageCandidates.length === 0) {
283
- return layoutSecondaryLine(contextText, statusText, "", width, theme);
284
- }
285
- for (const usageText of usageCandidates) {
286
- if (fitsLeftRight(contextText, usageText, width)) {
287
- return layoutSecondaryLine(contextText, statusText, usageText, width, theme);
288
- }
289
- }
290
- const fallbackUsage = usageCandidates[0] ?? "";
291
- return layoutLeftRight(contextText, fallbackUsage, width, theme);
292
- }
1
+ import { renderStatusline } from "./render.js";
2
+ import { BranchUsage } from "./usage.js";
293
3
  export default function statusline(pi) {
294
4
  pi.on("session_start", (_event, ctx) => {
295
- if (!isTui(ctx))
5
+ if (ctx.mode !== "tui")
296
6
  return;
297
- // Per-footer instance: branch path + stats cached across paints until the
298
- // leaf moves (or streaming usage on the leaf changes).
299
- const branchPathCache = { current: null };
300
- const branchStatsCache = { current: null };
301
7
  ctx.ui.setFooter((tui, theme, footerData) => {
302
- const unsubscribeFromBranchChanges = footerData.onBranchChange(() => tui.requestRender());
8
+ const usage = new BranchUsage();
303
9
  return {
304
- dispose: unsubscribeFromBranchChanges,
10
+ dispose: footerData.onBranchChange(() => tui.requestRender()),
305
11
  invalidate() {
306
- branchPathCache.current = null;
307
- branchStatsCache.current = null;
12
+ usage.invalidate();
308
13
  },
309
14
  render(width) {
310
- const branchEntries = getBranchEntries(() => ctx.sessionManager.getLeafId(), () => ctx.sessionManager.getBranch(), branchPathCache);
311
- const { thinkingLevel, usage: usageSummary } = getBranchStats(branchEntries, branchStatsCache);
312
15
  const model = ctx.model;
313
- const modelName = theme.fg("toolTitle", theme.bold(model?.name ?? model?.id ?? "no-model"));
314
- const providerPart = model?.provider ? theme.fg("muted", `(${model.provider})`) : "";
315
- const modelWithProvider = providerPart ? `${modelName} ${providerPart}` : modelName;
316
- let effortPart = "";
317
- if (model?.reasoning && thinkingLevel !== "off") {
318
- effortPart = theme.getThinkingBorderColor(thinkingLevel)(thinkingLevel);
319
- }
320
- const separator = theme.fg("dim", " · ");
321
- const cwdDisplay = formatWorkingDirectory(ctx.cwd);
322
- const cwdFull = theme.fg("success", cwdDisplay);
323
- const cwdShort = theme.fg("success", pathBasename(cwdDisplay));
324
- const gitBranch = footerData.getGitBranch();
325
- const branchPart = gitBranch ? theme.fg("accent", gitBranch) : "";
326
- const primaryLine = fitPrimaryLine({
327
- modelWithProvider,
328
- modelName,
329
- effortPart,
330
- cwdFull,
331
- cwdShort,
332
- branchPart,
333
- separator,
334
- width,
335
- theme,
336
- });
337
- const contextText = formatContextUsage(ctx, theme);
338
- const usesSubscription = model ? ctx.modelRegistry.isUsingOAuth(model) : false;
339
- const usageCandidates = [
340
- formatUsageSummary(usageSummary, usesSubscription, theme, {
341
- includeCacheRead: true,
342
- includeCacheWrite: true,
343
- }),
344
- formatUsageSummary(usageSummary, usesSubscription, theme, {
345
- includeCacheRead: true,
346
- includeCacheWrite: false,
347
- }),
348
- formatUsageSummary(usageSummary, usesSubscription, theme, {
349
- includeCacheRead: false,
350
- includeCacheWrite: false,
351
- }),
352
- ];
353
- // Deduplicate identical progressive candidates (e.g. when W/R are zero).
354
- const uniqueUsageCandidates = [...new Set(usageCandidates.filter(Boolean))];
355
- const statusText = formatExtensionStatuses(footerData.getExtensionStatuses(), theme);
356
- const secondaryLine = fitSecondaryLine({
357
- contextText,
358
- statusText,
359
- usageCandidates: uniqueUsageCandidates,
360
- width,
361
- theme,
362
- });
363
- return [primaryLine, secondaryLine];
16
+ return renderStatusline({
17
+ model,
18
+ thinkingLevel: ctx.thinkingLevel ?? "off",
19
+ cwd: ctx.cwd,
20
+ home: process.env.USERPROFILE || process.env.HOME || "",
21
+ gitBranch: footerData.getGitBranch(),
22
+ contextUsage: ctx.getContextUsage(),
23
+ usage: usage.read(ctx.sessionManager),
24
+ usesSubscription: model ? ctx.modelRegistry.isUsingOAuth(model) : false,
25
+ statuses: footerData.getExtensionStatuses(),
26
+ }, theme, width);
364
27
  },
365
28
  };
366
29
  });
367
30
  });
368
31
  pi.on("session_shutdown", (_event, ctx) => {
369
- if (isTui(ctx))
32
+ if (ctx.mode === "tui")
370
33
  ctx.ui.setFooter(undefined);
371
34
  });
372
35
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/extensions/statusline/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * statusline — fixed two-line footer for Pi.\n *\n * Balanced left/right layout:\n * Line 1: Model (provider) · effort ~cwd · branch\n * Line 2: CTX used/window ↑in ↓out R W CH $cost\n *\n * Extension statuses are pinned to the center of line 2 when space permits.\n * Pi does not expose auto-compaction state to custom footer factories, so the\n * native `(auto)` marker cannot be reproduced without depending on private APIs.\n */\nimport type { Usage } from \"@earendil-works/pi-ai\";\nimport { truncateToWidth, visibleWidth } from \"@earendil-works/pi-tui\";\nimport type { ExtensionAPI, ExtensionContext } from \"../../core/extensions/types.ts\";\nimport type { SessionEntry } from \"../../core/session-manager.ts\";\nimport {\n\taddUsageToTotals,\n\tcreateUsageTotals,\n\tgetAccountedUsages,\n\tgetTaskUsageRecord,\n\ttype UsageTotals,\n} from \"../../core/usage-totals.ts\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\n\nconst CONTEXT_WARNING_PERCENT = 40;\nconst CONTEXT_ERROR_PERCENT = 80;\nconst MIN_GAP = 1;\n\ntype ThinkingLevel = \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n\ninterface UsageSummary extends UsageTotals {\n\tlatestCacheHitPercent?: number;\n}\n\ninterface UsageFormatOptions {\n\tincludeCacheRead: boolean;\n\tincludeCacheWrite: boolean;\n}\n\nfunction isTui(ctx: ExtensionContext): boolean {\n\treturn ctx.mode === \"tui\";\n}\n\n/** Shorten a path to `~` relative to the user's home directory. */\nfunction formatWorkingDirectory(cwd: string): string {\n\tconst rawHomeDirectory = process.env.USERPROFILE || process.env.HOME || \"\";\n\tconst homeDirectory = rawHomeDirectory.replace(/[\\\\/]+$/, \"\");\n\tif (!homeDirectory) return cwd;\n\n\tconst normalizePath = (filePath: string) => filePath.replace(/\\\\/g, \"/\").replace(/\\/+$/, \"\").toLowerCase();\n\tconst normalizedHomeDirectory = normalizePath(homeDirectory);\n\tconst normalizedCwd = normalizePath(cwd);\n\tif (normalizedCwd === normalizedHomeDirectory) return \"~\";\n\tif (normalizedCwd.startsWith(`${normalizedHomeDirectory}/`)) {\n\t\treturn `~${cwd.slice(homeDirectory.length).replace(/\\\\/g, \"/\")}`;\n\t}\n\treturn cwd;\n}\n\n/** Collapse a display path to `~/basename` or bare basename when tight. */\nfunction pathBasename(displayPath: string): string {\n\tconst normalized = displayPath.replace(/\\\\/g, \"/\").replace(/\\/+$/, \"\");\n\tif (!normalized || normalized === \"~\") return normalized || displayPath;\n\tconst slash = normalized.lastIndexOf(\"/\");\n\tif (slash < 0) return normalized;\n\tconst base = normalized.slice(slash + 1);\n\tif (normalized.startsWith(\"~/\")) return `~/${base}`;\n\treturn base;\n}\n\n/** Format token counts like Pi's native footer: 999, 1.2k, 34k, 1.0M. */\nfunction formatTokenCount(tokenCount: number): string {\n\tif (tokenCount < 1000) return `${tokenCount}`;\n\tif (tokenCount < 10_000) return `${(tokenCount / 1000).toFixed(1)}k`;\n\tif (tokenCount < 1_000_000) return `${Math.round(tokenCount / 1000)}k`;\n\tif (tokenCount < 10_000_000) return `${(tokenCount / 1_000_000).toFixed(1)}M`;\n\treturn `${Math.round(tokenCount / 1_000_000)}M`;\n}\n\n/** Flatten extension status text to a single printable line. */\nfunction sanitizeStatus(text: string): string {\n\treturn text\n\t\t.replace(/[\\r\\n\\t]/g, \" \")\n\t\t.replace(/ +/g, \" \")\n\t\t.trim();\n}\n\nfunction joinSegments(segments: string[], separator: string): string {\n\treturn segments.filter((segment) => segment.length > 0).join(separator);\n}\n\ninterface BranchStats {\n\tthinkingLevel: ThinkingLevel;\n\tusage: UsageSummary;\n}\n\n/**\n * Latest thinking level and parent cache hit rate, plus accounted branch usage.\n * Cached across footer paints while leaf identity + usage fingerprint hold.\n */\nfunction entryUsage(entry: SessionEntry): Usage | undefined {\n\tif (entry.type === \"message\") {\n\t\tif (entry.message.role === \"assistant\") return entry.message.usage;\n\t\tif (entry.message.role === \"toolResult\") return entry.message.usage;\n\t\treturn undefined;\n\t}\n\tif (entry.type === \"branch_summary\" || entry.type === \"compaction\") return entry.usage;\n\treturn getTaskUsageRecord(entry)?.usage;\n}\n\nfunction computeBranchStats(branchEntries: SessionEntry[]): BranchStats {\n\tlet thinkingLevel: ThinkingLevel = \"off\";\n\tconst usageTotals = createUsageTotals();\n\tlet latestCacheHitPercent: number | undefined;\n\n\tfor (const usage of getAccountedUsages(branchEntries)) addUsageToTotals(usageTotals, usage);\n\n\tfor (const entry of branchEntries) {\n\t\tif (entry.type === \"thinking_level_change\") {\n\t\t\tthinkingLevel = entry.thinkingLevel as ThinkingLevel;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst usage = entryUsage(entry);\n\t\tif (!usage) continue;\n\n\t\t// Keep CH tied to the latest assistant request, matching the native\n\t\t// footer; tool and summary usage contributes only to cumulative totals.\n\t\tif (entry.type === \"message\" && entry.message.role === \"assistant\") {\n\t\t\tconst latestPromptTokens = usage.input + usage.cacheRead + usage.cacheWrite;\n\t\t\tconst latestRequestUsedCache = usage.cacheRead > 0 || usage.cacheWrite > 0;\n\t\t\tlatestCacheHitPercent =\n\t\t\t\tlatestRequestUsedCache && latestPromptTokens > 0 ? (usage.cacheRead / latestPromptTokens) * 100 : undefined;\n\t\t}\n\t}\n\n\treturn { thinkingLevel, usage: { ...usageTotals, latestCacheHitPercent } };\n}\n\n/**\n * Fingerprint the leaf so streaming usage updates invalidate even when the\n * SessionEntry object identity is reused in place.\n */\nfunction leafUsageFingerprint(entry: SessionEntry | undefined): string {\n\tif (!entry) return \"\";\n\tconst usage = entryUsage(entry);\n\tif (!usage) return \"\";\n\treturn [usage.input, usage.output, usage.cacheRead, usage.cacheWrite, usage.cost.total].join(\":\");\n}\n\n/** Cache keyed by branch length + leaf identity + usage fingerprint. */\ninterface BranchStatsCache {\n\tlength: number;\n\tlastEntry: SessionEntry | undefined;\n\tleafUsage: string;\n\tstats: BranchStats;\n}\n\nfunction getBranchStats(branchEntries: SessionEntry[], cache: { current: BranchStatsCache | null }): BranchStats {\n\tconst lastEntry = branchEntries.length > 0 ? branchEntries[branchEntries.length - 1] : undefined;\n\tconst leafUsage = leafUsageFingerprint(lastEntry);\n\tconst cached = cache.current;\n\tif (\n\t\tcached &&\n\t\tcached.length === branchEntries.length &&\n\t\tcached.lastEntry === lastEntry &&\n\t\tcached.leafUsage === leafUsage\n\t) {\n\t\treturn cached.stats;\n\t}\n\n\tconst stats = computeBranchStats(branchEntries);\n\tcache.current = { length: branchEntries.length, lastEntry, leafUsage, stats };\n\treturn stats;\n}\n\n/** Avoid rebuilding the branch path (leaf→root walk) on every footer paint. */\ninterface BranchPathCache {\n\tleafId: string | null;\n\tentries: SessionEntry[];\n}\n\nfunction getBranchEntries(\n\tgetLeafId: () => string | null,\n\tgetBranch: () => SessionEntry[],\n\tcache: { current: BranchPathCache | null },\n): SessionEntry[] {\n\tconst leafId = getLeafId();\n\tconst cached = cache.current;\n\tif (cached && cached.leafId === leafId) return cached.entries;\n\tconst entries = getBranch();\n\tcache.current = { leafId, entries };\n\treturn entries;\n}\n\nfunction formatContextUsage(ctx: ExtensionContext, theme: Theme): string {\n\tconst contextUsage = ctx.getContextUsage();\n\tconst contextWindow = contextUsage?.contextWindow ?? ctx.model?.contextWindow;\n\tconst contextWindowSuffix = contextWindow ? `/${formatTokenCount(contextWindow)}` : \"\";\n\tif (contextUsage?.percent == null) {\n\t\treturn theme.fg(\"accent\", `CTX ?%${contextWindowSuffix}`);\n\t}\n\n\tconst label = `CTX ${contextUsage.percent.toFixed(1)}%${contextWindowSuffix}`;\n\tif (contextUsage.percent > CONTEXT_ERROR_PERCENT) return theme.fg(\"error\", label);\n\tif (contextUsage.percent > CONTEXT_WARNING_PERCENT) return theme.fg(\"warning\", label);\n\treturn theme.fg(\"accent\", label);\n}\n\nfunction formatUsageSummary(\n\tsummary: UsageSummary,\n\tusesSubscription: boolean,\n\ttheme: Theme,\n\toptions: UsageFormatOptions = { includeCacheRead: true, includeCacheWrite: true },\n): string {\n\tconst usageParts: string[] = [];\n\tif (summary.input > 0) usageParts.push(`↑${formatTokenCount(summary.input)}`);\n\tif (summary.output > 0) usageParts.push(`↓${formatTokenCount(summary.output)}`);\n\tif (options.includeCacheRead && summary.cacheRead > 0) {\n\t\tusageParts.push(`R${formatTokenCount(summary.cacheRead)}`);\n\t}\n\tif (options.includeCacheWrite && summary.cacheWrite > 0) {\n\t\tusageParts.push(`W${formatTokenCount(summary.cacheWrite)}`);\n\t}\n\tif (summary.latestCacheHitPercent !== undefined) {\n\t\tusageParts.push(`CH${summary.latestCacheHitPercent.toFixed(1)}%`);\n\t}\n\tif (summary.cost > 0) {\n\t\tusageParts.push(`$${summary.cost.toFixed(3)}${usesSubscription ? \" (sub)\" : \"\"}`);\n\t}\n\tif (usageParts.length === 0) return \"\";\n\treturn theme.fg(\"dim\", usageParts.join(\" \"));\n}\n\n/** True when the string already carries SGR color codes from an extension. */\nfunction hasAnsiColor(text: string): boolean {\n\treturn text.includes(\"\\x1b[\");\n}\n\nfunction formatExtensionStatuses(statuses: ReadonlyMap<string, string>, theme: Theme): string {\n\tconst parts = Array.from(statuses.entries())\n\t\t.sort(([firstKey], [secondKey]) => firstKey.localeCompare(secondKey))\n\t\t.map(([, text]) => sanitizeStatus(text))\n\t\t.filter(Boolean)\n\t\t// Extensions may pre-color status text. Don't re-wrap those.\n\t\t.map((text) => (hasAnsiColor(text) ? text : theme.fg(\"muted\", text)));\n\treturn parts.join(\" \");\n}\n\n/** Left-align `left`, right-align `right`, filling the gap with spaces. */\nfunction layoutLeftRight(left: string, right: string, width: number, theme: Theme): string {\n\tconst ellipsis = theme.fg(\"dim\", \"...\");\n\tif (width <= 0) return \"\";\n\tif (!right) return truncateToWidth(left, width, ellipsis);\n\tif (!left) {\n\t\tconst rightWidth = visibleWidth(right);\n\t\tif (rightWidth >= width) return truncateToWidth(right, width, ellipsis);\n\t\treturn `${\" \".repeat(width - rightWidth)}${right}`;\n\t}\n\n\tlet leftText = left;\n\tlet rightText = right;\n\tlet leftWidth = visibleWidth(leftText);\n\tlet rightWidth = visibleWidth(rightText);\n\n\tif (leftWidth + rightWidth + MIN_GAP > width) {\n\t\t// Prefer keeping the right side readable; give it up to ~45% when both compete.\n\t\tconst maxRightWidth = Math.min(rightWidth, Math.max(8, Math.floor(width * 0.45)));\n\t\tif (rightWidth > maxRightWidth) {\n\t\t\trightText = truncateToWidth(rightText, maxRightWidth, ellipsis);\n\t\t\trightWidth = visibleWidth(rightText);\n\t\t}\n\t\tconst maxLeftWidth = width - rightWidth - MIN_GAP;\n\t\tif (maxLeftWidth < 1) return truncateToWidth(rightText, width, ellipsis);\n\t\tleftText = truncateToWidth(leftText, maxLeftWidth, ellipsis);\n\t\tleftWidth = visibleWidth(leftText);\n\t}\n\n\tconst gap = Math.max(MIN_GAP, width - leftWidth - rightWidth);\n\treturn `${leftText}${\" \".repeat(gap)}${rightText}`;\n}\n\n/**\n * Line 2 zones: CTX left, extension status pinned to the line center, usage\n * right. The status anchors to the absolute center of the line so it does not\n * drift as the usage cluster grows; when the side zones collide with the\n * center anchor, the free space is balanced instead. Drops the status first\n * when space is tight; caller should pass progressively smaller rights.\n */\nfunction layoutSecondaryLine(\n\tcontextText: string,\n\tstatusText: string,\n\tusageText: string,\n\twidth: number,\n\ttheme: Theme,\n): string {\n\tconst ellipsis = theme.fg(\"dim\", \"...\");\n\tif (!statusText) {\n\t\tif (!usageText) return truncateToWidth(contextText, width, ellipsis);\n\t\treturn layoutLeftRight(contextText, usageText, width, theme);\n\t}\n\n\tconst contextWidth = visibleWidth(contextText);\n\tconst usageWidth = visibleWidth(usageText);\n\tconst statusWidth = visibleWidth(statusText);\n\tconst needed = contextWidth + usageWidth + statusWidth + MIN_GAP * 2;\n\n\tif (needed <= width) {\n\t\tconst centerStart = Math.floor((width - statusWidth) / 2);\n\t\tconst centeredLeftPad = centerStart - contextWidth;\n\t\tconst centeredRightPad = width - centerStart - statusWidth - usageWidth;\n\t\tif (centeredLeftPad >= MIN_GAP && centeredRightPad >= MIN_GAP) {\n\t\t\treturn `${contextText}${\" \".repeat(centeredLeftPad)}${statusText}${\" \".repeat(centeredRightPad)}${usageText}`;\n\t\t}\n\t\tconst free = width - contextWidth - usageWidth - statusWidth;\n\t\tconst leftPad = Math.floor(free / 2);\n\t\tconst rightPad = free - leftPad;\n\t\treturn `${contextText}${\" \".repeat(leftPad)}${statusText}${\" \".repeat(rightPad)}${usageText}`;\n\t}\n\n\t// Not enough room for a full middle status — keep CTX · usage, drop status.\n\treturn layoutLeftRight(contextText, usageText, width, theme);\n}\n\nfunction fitsLeftRight(left: string, right: string, width: number): boolean {\n\tif (!right) return visibleWidth(left) <= width;\n\tif (!left) return visibleWidth(right) <= width;\n\treturn visibleWidth(left) + visibleWidth(right) + MIN_GAP <= width;\n}\n\n/** Progressive drop: branch → short path → drop provider → truncate. */\nfunction fitPrimaryLine(options: {\n\tmodelWithProvider: string;\n\tmodelName: string;\n\teffortPart: string;\n\tcwdFull: string;\n\tcwdShort: string;\n\tbranchPart: string;\n\tseparator: string;\n\twidth: number;\n\ttheme: Theme;\n}): string {\n\tconst { modelWithProvider, modelName, effortPart, cwdFull, cwdShort, branchPart, separator, width, theme } = options;\n\n\tconst leftRich = joinSegments([modelWithProvider, effortPart], separator);\n\tconst leftPlain = joinSegments([modelName, effortPart], separator);\n\n\tconst candidates: Array<{ left: string; right: string }> = [\n\t\t{ left: leftRich, right: joinSegments([cwdFull, branchPart], separator) },\n\t\t{ left: leftRich, right: cwdFull },\n\t\t{ left: leftRich, right: joinSegments([cwdShort, branchPart], separator) },\n\t\t{ left: leftRich, right: cwdShort },\n\t\t{ left: leftPlain, right: joinSegments([cwdShort, branchPart], separator) },\n\t\t{ left: leftPlain, right: cwdShort },\n\t\t{ left: leftPlain, right: \"\" },\n\t];\n\n\tfor (const candidate of candidates) {\n\t\tif (fitsLeftRight(candidate.left, candidate.right, width)) {\n\t\t\treturn layoutLeftRight(candidate.left, candidate.right, width, theme);\n\t\t}\n\t}\n\n\treturn layoutLeftRight(leftPlain, cwdShort, width, theme);\n}\n\n/** Progressive drop on the usage side: full → drop W → drop R; status fills middle when space allows. */\nfunction fitSecondaryLine(options: {\n\tcontextText: string;\n\tstatusText: string;\n\tusageCandidates: string[];\n\twidth: number;\n\ttheme: Theme;\n}): string {\n\tconst { contextText, statusText, usageCandidates, width, theme } = options;\n\n\tif (usageCandidates.length === 0) {\n\t\treturn layoutSecondaryLine(contextText, statusText, \"\", width, theme);\n\t}\n\n\tfor (const usageText of usageCandidates) {\n\t\tif (fitsLeftRight(contextText, usageText, width)) {\n\t\t\treturn layoutSecondaryLine(contextText, statusText, usageText, width, theme);\n\t\t}\n\t}\n\n\tconst fallbackUsage = usageCandidates[0] ?? \"\";\n\treturn layoutLeftRight(contextText, fallbackUsage, width, theme);\n}\n\nexport default function statusline(pi: ExtensionAPI): void {\n\tpi.on(\"session_start\", (_event, ctx) => {\n\t\tif (!isTui(ctx)) return;\n\n\t\t// Per-footer instance: branch path + stats cached across paints until the\n\t\t// leaf moves (or streaming usage on the leaf changes).\n\t\tconst branchPathCache: { current: BranchPathCache | null } = { current: null };\n\t\tconst branchStatsCache: { current: BranchStatsCache | null } = { current: null };\n\n\t\tctx.ui.setFooter((tui, theme, footerData) => {\n\t\t\tconst unsubscribeFromBranchChanges = footerData.onBranchChange(() => tui.requestRender());\n\t\t\treturn {\n\t\t\t\tdispose: unsubscribeFromBranchChanges,\n\t\t\t\tinvalidate() {\n\t\t\t\t\tbranchPathCache.current = null;\n\t\t\t\t\tbranchStatsCache.current = null;\n\t\t\t\t},\n\t\t\t\trender(width: number): string[] {\n\t\t\t\t\tconst branchEntries = getBranchEntries(\n\t\t\t\t\t\t() => ctx.sessionManager.getLeafId(),\n\t\t\t\t\t\t() => ctx.sessionManager.getBranch(),\n\t\t\t\t\t\tbranchPathCache,\n\t\t\t\t\t);\n\t\t\t\t\tconst { thinkingLevel, usage: usageSummary } = getBranchStats(branchEntries, branchStatsCache);\n\t\t\t\t\tconst model = ctx.model;\n\t\t\t\t\tconst modelName = theme.fg(\"toolTitle\", theme.bold(model?.name ?? model?.id ?? \"no-model\"));\n\t\t\t\t\tconst providerPart = model?.provider ? theme.fg(\"muted\", `(${model.provider})`) : \"\";\n\t\t\t\t\tconst modelWithProvider = providerPart ? `${modelName} ${providerPart}` : modelName;\n\n\t\t\t\t\tlet effortPart = \"\";\n\t\t\t\t\tif (model?.reasoning && thinkingLevel !== \"off\") {\n\t\t\t\t\t\teffortPart = theme.getThinkingBorderColor(thinkingLevel)(thinkingLevel);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst separator = theme.fg(\"dim\", \" · \");\n\t\t\t\t\tconst cwdDisplay = formatWorkingDirectory(ctx.cwd);\n\t\t\t\t\tconst cwdFull = theme.fg(\"success\", cwdDisplay);\n\t\t\t\t\tconst cwdShort = theme.fg(\"success\", pathBasename(cwdDisplay));\n\t\t\t\t\tconst gitBranch = footerData.getGitBranch();\n\t\t\t\t\tconst branchPart = gitBranch ? theme.fg(\"accent\", gitBranch) : \"\";\n\n\t\t\t\t\tconst primaryLine = fitPrimaryLine({\n\t\t\t\t\t\tmodelWithProvider,\n\t\t\t\t\t\tmodelName,\n\t\t\t\t\t\teffortPart,\n\t\t\t\t\t\tcwdFull,\n\t\t\t\t\t\tcwdShort,\n\t\t\t\t\t\tbranchPart,\n\t\t\t\t\t\tseparator,\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\ttheme,\n\t\t\t\t\t});\n\n\t\t\t\t\tconst contextText = formatContextUsage(ctx, theme);\n\t\t\t\t\tconst usesSubscription = model ? ctx.modelRegistry.isUsingOAuth(model) : false;\n\t\t\t\t\tconst usageCandidates = [\n\t\t\t\t\t\tformatUsageSummary(usageSummary, usesSubscription, theme, {\n\t\t\t\t\t\t\tincludeCacheRead: true,\n\t\t\t\t\t\t\tincludeCacheWrite: true,\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tformatUsageSummary(usageSummary, usesSubscription, theme, {\n\t\t\t\t\t\t\tincludeCacheRead: true,\n\t\t\t\t\t\t\tincludeCacheWrite: false,\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tformatUsageSummary(usageSummary, usesSubscription, theme, {\n\t\t\t\t\t\t\tincludeCacheRead: false,\n\t\t\t\t\t\t\tincludeCacheWrite: false,\n\t\t\t\t\t\t}),\n\t\t\t\t\t];\n\t\t\t\t\t// Deduplicate identical progressive candidates (e.g. when W/R are zero).\n\t\t\t\t\tconst uniqueUsageCandidates = [...new Set(usageCandidates.filter(Boolean))];\n\t\t\t\t\tconst statusText = formatExtensionStatuses(footerData.getExtensionStatuses(), theme);\n\n\t\t\t\t\tconst secondaryLine = fitSecondaryLine({\n\t\t\t\t\t\tcontextText,\n\t\t\t\t\t\tstatusText,\n\t\t\t\t\t\tusageCandidates: uniqueUsageCandidates,\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\ttheme,\n\t\t\t\t\t});\n\n\t\t\t\t\treturn [primaryLine, secondaryLine];\n\t\t\t\t},\n\t\t\t};\n\t\t});\n\t});\n\n\tpi.on(\"session_shutdown\", (_event, ctx) => {\n\t\tif (isTui(ctx)) ctx.ui.setFooter(undefined);\n\t});\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/extensions/statusline/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EAAgB;IAClD,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;QACtC,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK;YAAE,OAAO;QAC/B,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;YAC3C,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC;YAChC,OAAO;gBACN,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;gBAC7D,UAAU;oBACT,KAAK,CAAC,UAAU,EAAE,CAAC;gBACpB,CAAC;gBACD,MAAM,CAAC,KAAa;oBACnB,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;oBACxB,OAAO,gBAAgB,CACtB;wBACC,KAAK;wBACL,aAAa,EAAE,GAAG,CAAC,aAAa,IAAI,KAAK;wBACzC,GAAG,EAAE,GAAG,CAAC,GAAG;wBACZ,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE;wBACvD,SAAS,EAAE,UAAU,CAAC,YAAY,EAAE;wBACpC,YAAY,EAAE,GAAG,CAAC,eAAe,EAAE;wBACnC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC;wBACrC,gBAAgB,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK;wBACvE,QAAQ,EAAE,UAAU,CAAC,oBAAoB,EAAE;qBAC3C,EACD,KAAK,EACL,KAAK,CACL,CAAC;gBACH,CAAC;aACD,CAAC;QACH,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,kBAAkB,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;QACzC,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK;YAAE,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Fixed two-line footer, installed only in the interactive TUI.\n * Rendering and active-branch accounting are owned by this extension.\n */\nimport type { ExtensionAPI } from \"../../core/extensions/types.ts\";\nimport { renderStatusline } from \"./render.ts\";\nimport { BranchUsage } from \"./usage.ts\";\n\nexport default function statusline(pi: ExtensionAPI): void {\n\tpi.on(\"session_start\", (_event, ctx) => {\n\t\tif (ctx.mode !== \"tui\") return;\n\t\tctx.ui.setFooter((tui, theme, footerData) => {\n\t\t\tconst usage = new BranchUsage();\n\t\t\treturn {\n\t\t\t\tdispose: footerData.onBranchChange(() => tui.requestRender()),\n\t\t\t\tinvalidate() {\n\t\t\t\t\tusage.invalidate();\n\t\t\t\t},\n\t\t\t\trender(width: number): string[] {\n\t\t\t\t\tconst model = ctx.model;\n\t\t\t\t\treturn renderStatusline(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\tthinkingLevel: ctx.thinkingLevel ?? \"off\",\n\t\t\t\t\t\t\tcwd: ctx.cwd,\n\t\t\t\t\t\t\thome: process.env.USERPROFILE || process.env.HOME || \"\",\n\t\t\t\t\t\t\tgitBranch: footerData.getGitBranch(),\n\t\t\t\t\t\t\tcontextUsage: ctx.getContextUsage(),\n\t\t\t\t\t\t\tusage: usage.read(ctx.sessionManager),\n\t\t\t\t\t\t\tusesSubscription: model ? ctx.modelRegistry.isUsingOAuth(model) : false,\n\t\t\t\t\t\t\tstatuses: footerData.getExtensionStatuses(),\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttheme,\n\t\t\t\t\t\twidth,\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t};\n\t\t});\n\t});\n\n\tpi.on(\"session_shutdown\", (_event, ctx) => {\n\t\tif (ctx.mode === \"tui\") ctx.ui.setFooter(undefined);\n\t});\n}\n"]}
@@ -0,0 +1,19 @@
1
+ import type { ThinkingLevel } from "@earendil-works/pi-agent-core";
2
+ import type { Model } from "@earendil-works/pi-ai";
3
+ import type { ContextUsage } from "../../core/extensions/types.ts";
4
+ import type { Theme } from "../../modes/interactive/theme/theme.ts";
5
+ import type { UsageSummary } from "./usage.ts";
6
+ export interface StatuslineData {
7
+ model: Pick<Model<string>, "id" | "name" | "provider" | "reasoning" | "contextWindow"> | undefined;
8
+ thinkingLevel: ThinkingLevel;
9
+ cwd: string;
10
+ home: string;
11
+ gitBranch: string | null;
12
+ contextUsage: ContextUsage | undefined;
13
+ usage: UsageSummary;
14
+ usesSubscription: boolean;
15
+ statuses: ReadonlyMap<string, string>;
16
+ }
17
+ /** Fixed two-line presentation, independent of session access and footer lifecycle. */
18
+ export declare function renderStatusline(data: StatuslineData, theme: Theme, width: number): string[];
19
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/extensions/statusline/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wCAAwC,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,eAAe,CAAC,GAAG,SAAS,CAAC;IACnG,aAAa,EAAE,aAAa,CAAC;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,YAAY,GAAG,SAAS,CAAC;IACvC,KAAK,EAAE,YAAY,CAAC;IACpB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAsJD,uFAAuF;AACvF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAa5F"}