@bastani/atomic 0.9.11-alpha.2 → 0.9.11-alpha.3

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 (435) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/builtin/cursor/package.json +2 -2
  3. package/dist/builtin/intercom/package.json +1 -1
  4. package/dist/builtin/mcp/package.json +1 -1
  5. package/dist/builtin/subagents/CHANGELOG.md +6 -0
  6. package/dist/builtin/subagents/package.json +1 -1
  7. package/dist/builtin/subagents/src/runs/background/notify.ts +3 -1
  8. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-chain.ts +5 -2
  9. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +2 -1
  10. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +5 -2
  11. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-status.ts +34 -0
  12. package/dist/builtin/web-access/package.json +1 -1
  13. package/dist/builtin/workflows/package.json +1 -1
  14. package/dist/builtin/workflows/src/extension/ui-surface.ts +4 -0
  15. package/dist/builtin/workflows/src/tui/host-input-form.ts +1 -1
  16. package/dist/cli/args.js +2 -2
  17. package/dist/cli/args.js.map +1 -1
  18. package/dist/cli/config-selector.d.ts +4 -2
  19. package/dist/cli/config-selector.d.ts.map +1 -1
  20. package/dist/cli/config-selector.js +1 -1
  21. package/dist/cli/config-selector.js.map +1 -1
  22. package/dist/cli/startup-ui.d.ts +3 -0
  23. package/dist/cli/startup-ui.d.ts.map +1 -1
  24. package/dist/cli/startup-ui.js +50 -1
  25. package/dist/cli/startup-ui.js.map +1 -1
  26. package/dist/config-command-parser.d.ts +9 -0
  27. package/dist/config-command-parser.d.ts.map +1 -0
  28. package/dist/config-command-parser.js +22 -0
  29. package/dist/config-command-parser.js.map +1 -0
  30. package/dist/config-self-update.d.ts +6 -2
  31. package/dist/config-self-update.d.ts.map +1 -1
  32. package/dist/config-self-update.js +17 -10
  33. package/dist/config-self-update.js.map +1 -1
  34. package/dist/config.d.ts +3 -3
  35. package/dist/config.d.ts.map +1 -1
  36. package/dist/config.js +4 -4
  37. package/dist/config.js.map +1 -1
  38. package/dist/core/agent-session-export.d.ts.map +1 -1
  39. package/dist/core/agent-session-export.js +32 -25
  40. package/dist/core/agent-session-export.js.map +1 -1
  41. package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
  42. package/dist/core/agent-session-extension-bindings.js +9 -3
  43. package/dist/core/agent-session-extension-bindings.js.map +1 -1
  44. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  45. package/dist/core/agent-session-prompt.js +5 -0
  46. package/dist/core/agent-session-prompt.js.map +1 -1
  47. package/dist/core/agent-session-services.d.ts +2 -0
  48. package/dist/core/agent-session-services.d.ts.map +1 -1
  49. package/dist/core/agent-session-services.js +8 -5
  50. package/dist/core/agent-session-services.js.map +1 -1
  51. package/dist/core/agent-session-tree.d.ts.map +1 -1
  52. package/dist/core/agent-session-tree.js +3 -1
  53. package/dist/core/agent-session-tree.js.map +1 -1
  54. package/dist/core/agent-session-types.d.ts +5 -0
  55. package/dist/core/agent-session-types.d.ts.map +1 -1
  56. package/dist/core/agent-session-types.js.map +1 -1
  57. package/dist/core/auth-storage.d.ts +6 -2
  58. package/dist/core/auth-storage.d.ts.map +1 -1
  59. package/dist/core/auth-storage.js +5 -1
  60. package/dist/core/auth-storage.js.map +1 -1
  61. package/dist/core/cache-stats.d.ts +25 -0
  62. package/dist/core/cache-stats.d.ts.map +1 -0
  63. package/dist/core/cache-stats.js +68 -0
  64. package/dist/core/cache-stats.js.map +1 -0
  65. package/dist/core/compaction/branch-summarization.d.ts +2 -1
  66. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  67. package/dist/core/compaction/branch-summarization.js +1 -0
  68. package/dist/core/compaction/branch-summarization.js.map +1 -1
  69. package/dist/core/extensions/agent-events.d.ts +10 -0
  70. package/dist/core/extensions/agent-events.d.ts.map +1 -1
  71. package/dist/core/extensions/agent-events.js.map +1 -1
  72. package/dist/core/extensions/api-types.d.ts +8 -2
  73. package/dist/core/extensions/api-types.d.ts.map +1 -1
  74. package/dist/core/extensions/api-types.js.map +1 -1
  75. package/dist/core/extensions/event-types.d.ts +2 -2
  76. package/dist/core/extensions/event-types.d.ts.map +1 -1
  77. package/dist/core/extensions/event-types.js.map +1 -1
  78. package/dist/core/extensions/index.d.ts +1 -1
  79. package/dist/core/extensions/index.d.ts.map +1 -1
  80. package/dist/core/extensions/index.js.map +1 -1
  81. package/dist/core/extensions/loader-api.d.ts.map +1 -1
  82. package/dist/core/extensions/loader-api.js +13 -2
  83. package/dist/core/extensions/loader-api.js.map +1 -1
  84. package/dist/core/extensions/loader-core.d.ts.map +1 -1
  85. package/dist/core/extensions/loader-core.js +1 -0
  86. package/dist/core/extensions/loader-core.js.map +1 -1
  87. package/dist/core/extensions/loader-runtime.d.ts.map +1 -1
  88. package/dist/core/extensions/loader-runtime.js +15 -7
  89. package/dist/core/extensions/loader-runtime.js.map +1 -1
  90. package/dist/core/extensions/message-types.d.ts +5 -0
  91. package/dist/core/extensions/message-types.d.ts.map +1 -1
  92. package/dist/core/extensions/message-types.js.map +1 -1
  93. package/dist/core/extensions/provider-types.d.ts +46 -0
  94. package/dist/core/extensions/provider-types.d.ts.map +1 -1
  95. package/dist/core/extensions/provider-types.js.map +1 -1
  96. package/dist/core/extensions/runner-registries.d.ts +2 -1
  97. package/dist/core/extensions/runner-registries.d.ts.map +1 -1
  98. package/dist/core/extensions/runner-registries.js +8 -0
  99. package/dist/core/extensions/runner-registries.js.map +1 -1
  100. package/dist/core/extensions/runner.d.ts +5 -2
  101. package/dist/core/extensions/runner.d.ts.map +1 -1
  102. package/dist/core/extensions/runner.js +35 -13
  103. package/dist/core/extensions/runner.js.map +1 -1
  104. package/dist/core/extensions/runtime-types.d.ts +8 -2
  105. package/dist/core/extensions/runtime-types.d.ts.map +1 -1
  106. package/dist/core/extensions/runtime-types.js.map +1 -1
  107. package/dist/core/extensions/ui-types.d.ts +4 -0
  108. package/dist/core/extensions/ui-types.d.ts.map +1 -1
  109. package/dist/core/extensions/ui-types.js.map +1 -1
  110. package/dist/core/http-dispatcher.d.ts +1 -0
  111. package/dist/core/http-dispatcher.d.ts.map +1 -1
  112. package/dist/core/http-dispatcher.js +16 -2
  113. package/dist/core/http-dispatcher.js.map +1 -1
  114. package/dist/core/keybindings.d.ts +6 -1
  115. package/dist/core/keybindings.d.ts.map +1 -1
  116. package/dist/core/keybindings.js +3 -1
  117. package/dist/core/keybindings.js.map +1 -1
  118. package/dist/core/model-registry-auth.d.ts +2 -0
  119. package/dist/core/model-registry-auth.d.ts.map +1 -1
  120. package/dist/core/model-registry-auth.js +18 -1
  121. package/dist/core/model-registry-auth.js.map +1 -1
  122. package/dist/core/model-registry-custom-loader.d.ts.map +1 -1
  123. package/dist/core/model-registry-custom-loader.js +14 -2
  124. package/dist/core/model-registry-custom-loader.js.map +1 -1
  125. package/dist/core/model-registry-dynamic.js +2 -2
  126. package/dist/core/model-registry-dynamic.js.map +1 -1
  127. package/dist/core/model-registry-loader.d.ts.map +1 -1
  128. package/dist/core/model-registry-loader.js +2 -1
  129. package/dist/core/model-registry-loader.js.map +1 -1
  130. package/dist/core/model-registry-schemas.d.ts +17 -0
  131. package/dist/core/model-registry-schemas.d.ts.map +1 -1
  132. package/dist/core/model-registry-schemas.js +2 -0
  133. package/dist/core/model-registry-schemas.js.map +1 -1
  134. package/dist/core/model-registry-types.d.ts +10 -1
  135. package/dist/core/model-registry-types.d.ts.map +1 -1
  136. package/dist/core/model-registry-types.js.map +1 -1
  137. package/dist/core/model-registry.d.ts +26 -36
  138. package/dist/core/model-registry.d.ts.map +1 -1
  139. package/dist/core/model-registry.js +72 -67
  140. package/dist/core/model-registry.js.map +1 -1
  141. package/dist/core/model-resolver-defaults.d.ts.map +1 -1
  142. package/dist/core/model-resolver-defaults.js +3 -0
  143. package/dist/core/model-resolver-defaults.js.map +1 -1
  144. package/dist/core/model-runtime.d.ts +52 -0
  145. package/dist/core/model-runtime.d.ts.map +1 -0
  146. package/dist/core/model-runtime.js +120 -0
  147. package/dist/core/model-runtime.js.map +1 -0
  148. package/dist/core/oauth-provider-bridge.d.ts +3 -1
  149. package/dist/core/oauth-provider-bridge.d.ts.map +1 -1
  150. package/dist/core/oauth-provider-bridge.js +6 -4
  151. package/dist/core/oauth-provider-bridge.js.map +1 -1
  152. package/dist/core/package-manager-resolver.js +22 -11
  153. package/dist/core/package-manager-resolver.js.map +1 -1
  154. package/dist/core/package-manager-resource-collector.d.ts.map +1 -1
  155. package/dist/core/package-manager-resource-collector.js +8 -2
  156. package/dist/core/package-manager-resource-collector.js.map +1 -1
  157. package/dist/core/package-manager-resource-patterns.d.ts +1 -0
  158. package/dist/core/package-manager-resource-patterns.d.ts.map +1 -1
  159. package/dist/core/package-manager-resource-patterns.js +15 -0
  160. package/dist/core/package-manager-resource-patterns.js.map +1 -1
  161. package/dist/core/package-manager-source.d.ts.map +1 -1
  162. package/dist/core/package-manager-source.js +15 -8
  163. package/dist/core/package-manager-source.js.map +1 -1
  164. package/dist/core/package-manager-types.d.ts +1 -0
  165. package/dist/core/package-manager-types.d.ts.map +1 -1
  166. package/dist/core/package-manager-types.js.map +1 -1
  167. package/dist/core/provider-display-names.d.ts.map +1 -1
  168. package/dist/core/provider-display-names.js +4 -0
  169. package/dist/core/provider-display-names.js.map +1 -1
  170. package/dist/core/resource-loader-core.d.ts.map +1 -1
  171. package/dist/core/resource-loader-core.js.map +1 -1
  172. package/dist/core/resource-loader-extensions.d.ts.map +1 -1
  173. package/dist/core/resource-loader-extensions.js +5 -2
  174. package/dist/core/resource-loader-extensions.js.map +1 -1
  175. package/dist/core/resource-loader-helpers.d.ts.map +1 -1
  176. package/dist/core/resource-loader-helpers.js +1 -0
  177. package/dist/core/resource-loader-helpers.js.map +1 -1
  178. package/dist/core/resource-loader-internals.d.ts +2 -2
  179. package/dist/core/resource-loader-internals.d.ts.map +1 -1
  180. package/dist/core/resource-loader-internals.js.map +1 -1
  181. package/dist/core/resource-loader-types.d.ts +3 -3
  182. package/dist/core/resource-loader-types.d.ts.map +1 -1
  183. package/dist/core/resource-loader-types.js.map +1 -1
  184. package/dist/core/sdk-exports.d.ts +1 -1
  185. package/dist/core/sdk-exports.d.ts.map +1 -1
  186. package/dist/core/sdk-exports.js.map +1 -1
  187. package/dist/core/sdk-types.d.ts +3 -0
  188. package/dist/core/sdk-types.d.ts.map +1 -1
  189. package/dist/core/sdk-types.js.map +1 -1
  190. package/dist/core/sdk.js +6 -2
  191. package/dist/core/sdk.js.map +1 -1
  192. package/dist/core/session-manager-core.d.ts +1 -1
  193. package/dist/core/session-manager-core.d.ts.map +1 -1
  194. package/dist/core/session-manager-core.js +2 -2
  195. package/dist/core/session-manager-core.js.map +1 -1
  196. package/dist/core/session-manager-entries.d.ts +2 -2
  197. package/dist/core/session-manager-entries.d.ts.map +1 -1
  198. package/dist/core/session-manager-entries.js +2 -1
  199. package/dist/core/session-manager-entries.js.map +1 -1
  200. package/dist/core/session-manager-history.d.ts +5 -0
  201. package/dist/core/session-manager-history.d.ts.map +1 -1
  202. package/dist/core/session-manager-history.js +33 -0
  203. package/dist/core/session-manager-history.js.map +1 -1
  204. package/dist/core/session-manager-types.d.ts +4 -2
  205. package/dist/core/session-manager-types.d.ts.map +1 -1
  206. package/dist/core/session-manager-types.js.map +1 -1
  207. package/dist/core/session-manager.d.ts +1 -1
  208. package/dist/core/session-manager.d.ts.map +1 -1
  209. package/dist/core/session-manager.js +1 -1
  210. package/dist/core/session-manager.js.map +1 -1
  211. package/dist/core/settings-manager-basic-accessors.d.ts +7 -0
  212. package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
  213. package/dist/core/settings-manager-basic-accessors.js +35 -0
  214. package/dist/core/settings-manager-basic-accessors.js.map +1 -1
  215. package/dist/core/settings-manager-resource-accessors.d.ts +3 -0
  216. package/dist/core/settings-manager-resource-accessors.d.ts.map +1 -1
  217. package/dist/core/settings-manager-resource-accessors.js +16 -0
  218. package/dist/core/settings-manager-resource-accessors.js.map +1 -1
  219. package/dist/core/settings-types.d.ts +8 -2
  220. package/dist/core/settings-types.d.ts.map +1 -1
  221. package/dist/core/settings-types.js.map +1 -1
  222. package/dist/core/slash-commands.d.ts +1 -0
  223. package/dist/core/slash-commands.d.ts.map +1 -1
  224. package/dist/core/slash-commands.js +1 -1
  225. package/dist/core/slash-commands.js.map +1 -1
  226. package/dist/core/usage-totals.d.ts +18 -0
  227. package/dist/core/usage-totals.d.ts.map +1 -0
  228. package/dist/core/usage-totals.js +40 -0
  229. package/dist/core/usage-totals.js.map +1 -0
  230. package/dist/extensions/index.d.ts +3 -0
  231. package/dist/extensions/index.d.ts.map +1 -0
  232. package/dist/extensions/index.js +5 -0
  233. package/dist/extensions/index.js.map +1 -0
  234. package/dist/extensions/llama/client.d.ts +61 -0
  235. package/dist/extensions/llama/client.d.ts.map +1 -0
  236. package/dist/extensions/llama/client.js +300 -0
  237. package/dist/extensions/llama/client.js.map +1 -0
  238. package/dist/extensions/llama/huggingface-ui.d.ts +33 -0
  239. package/dist/extensions/llama/huggingface-ui.d.ts.map +1 -0
  240. package/dist/extensions/llama/huggingface-ui.js +166 -0
  241. package/dist/extensions/llama/huggingface-ui.js.map +1 -0
  242. package/dist/extensions/llama/huggingface.d.ts +23 -0
  243. package/dist/extensions/llama/huggingface.d.ts.map +1 -0
  244. package/dist/extensions/llama/huggingface.js +139 -0
  245. package/dist/extensions/llama/huggingface.js.map +1 -0
  246. package/dist/extensions/llama/index.d.ts +3 -0
  247. package/dist/extensions/llama/index.d.ts.map +1 -0
  248. package/dist/extensions/llama/index.js +208 -0
  249. package/dist/extensions/llama/index.js.map +1 -0
  250. package/dist/extensions/llama/provider.d.ts +11 -0
  251. package/dist/extensions/llama/provider.d.ts.map +1 -0
  252. package/dist/extensions/llama/provider.js +93 -0
  253. package/dist/extensions/llama/provider.js.map +1 -0
  254. package/dist/extensions/llama/ui.d.ts +42 -0
  255. package/dist/extensions/llama/ui.d.ts.map +1 -0
  256. package/dist/extensions/llama/ui.js +237 -0
  257. package/dist/extensions/llama/ui.js.map +1 -0
  258. package/dist/index-extensions.d.ts +1 -1
  259. package/dist/index-extensions.d.ts.map +1 -1
  260. package/dist/index-extensions.js.map +1 -1
  261. package/dist/index.d.ts +4 -3
  262. package/dist/index.d.ts.map +1 -1
  263. package/dist/index.js +4 -3
  264. package/dist/index.js.map +1 -1
  265. package/dist/main-first-time-setup.d.ts +6 -0
  266. package/dist/main-first-time-setup.d.ts.map +1 -0
  267. package/dist/main-first-time-setup.js +10 -0
  268. package/dist/main-first-time-setup.js.map +1 -0
  269. package/dist/main-types.d.ts +2 -2
  270. package/dist/main-types.d.ts.map +1 -1
  271. package/dist/main-types.js.map +1 -1
  272. package/dist/main.d.ts.map +1 -1
  273. package/dist/main.js +17 -7
  274. package/dist/main.js.map +1 -1
  275. package/dist/modes/interactive/chat-input-actions.d.ts.map +1 -1
  276. package/dist/modes/interactive/chat-input-actions.js +14 -2
  277. package/dist/modes/interactive/chat-input-actions.js.map +1 -1
  278. package/dist/modes/interactive/components/config-selector-list.d.ts +6 -6
  279. package/dist/modes/interactive/components/config-selector-list.d.ts.map +1 -1
  280. package/dist/modes/interactive/components/config-selector-list.js +64 -125
  281. package/dist/modes/interactive/components/config-selector-list.js.map +1 -1
  282. package/dist/modes/interactive/components/config-selector-project-scope.d.ts +4 -0
  283. package/dist/modes/interactive/components/config-selector-project-scope.d.ts.map +1 -0
  284. package/dist/modes/interactive/components/config-selector-project-scope.js +61 -0
  285. package/dist/modes/interactive/components/config-selector-project-scope.js.map +1 -0
  286. package/dist/modes/interactive/components/config-selector.d.ts +8 -5
  287. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  288. package/dist/modes/interactive/components/config-selector.js +46 -22
  289. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  290. package/dist/modes/interactive/components/custom-entry.d.ts +16 -0
  291. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -0
  292. package/dist/modes/interactive/components/custom-entry.js +45 -0
  293. package/dist/modes/interactive/components/custom-entry.js.map +1 -0
  294. package/dist/modes/interactive/components/first-time-setup.d.ts +24 -0
  295. package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -0
  296. package/dist/modes/interactive/components/first-time-setup.js +69 -0
  297. package/dist/modes/interactive/components/first-time-setup.js.map +1 -0
  298. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  299. package/dist/modes/interactive/components/footer.js +46 -24
  300. package/dist/modes/interactive/components/footer.js.map +1 -1
  301. package/dist/modes/interactive/components/host-input-form.d.ts +2 -0
  302. package/dist/modes/interactive/components/host-input-form.d.ts.map +1 -1
  303. package/dist/modes/interactive/components/host-input-form.js +6 -3
  304. package/dist/modes/interactive/components/host-input-form.js.map +1 -1
  305. package/dist/modes/interactive/components/idle-status.d.ts +8 -0
  306. package/dist/modes/interactive/components/idle-status.d.ts.map +1 -0
  307. package/dist/modes/interactive/components/idle-status.js +13 -0
  308. package/dist/modes/interactive/components/idle-status.js.map +1 -0
  309. package/dist/modes/interactive/components/index.d.ts +3 -0
  310. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  311. package/dist/modes/interactive/components/index.js +3 -0
  312. package/dist/modes/interactive/components/index.js.map +1 -1
  313. package/dist/modes/interactive/components/login-dialog.d.ts +5 -5
  314. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  315. package/dist/modes/interactive/components/login-dialog.js +14 -6
  316. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  317. package/dist/modes/interactive/components/oauth-selector.d.ts +1 -1
  318. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  319. package/dist/modes/interactive/components/oauth-selector.js +10 -6
  320. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  321. package/dist/modes/interactive/components/settings-selector-handlers.d.ts.map +1 -1
  322. package/dist/modes/interactive/components/settings-selector-handlers.js +6 -0
  323. package/dist/modes/interactive/components/settings-selector-handlers.js.map +1 -1
  324. package/dist/modes/interactive/components/settings-selector-items.d.ts.map +1 -1
  325. package/dist/modes/interactive/components/settings-selector-items.js +14 -0
  326. package/dist/modes/interactive/components/settings-selector-items.js.map +1 -1
  327. package/dist/modes/interactive/components/settings-selector-types.d.ts +4 -0
  328. package/dist/modes/interactive/components/settings-selector-types.d.ts.map +1 -1
  329. package/dist/modes/interactive/components/settings-selector-types.js.map +1 -1
  330. package/dist/modes/interactive/interactive-agent-events.js +21 -0
  331. package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
  332. package/dist/modes/interactive/interactive-auth-login.js +17 -8
  333. package/dist/modes/interactive/interactive-auth-login.js.map +1 -1
  334. package/dist/modes/interactive/interactive-auth-routing.d.ts +2 -0
  335. package/dist/modes/interactive/interactive-auth-routing.d.ts.map +1 -1
  336. package/dist/modes/interactive/interactive-auth-routing.js +88 -40
  337. package/dist/modes/interactive/interactive-auth-routing.js.map +1 -1
  338. package/dist/modes/interactive/interactive-autocomplete.js +6 -0
  339. package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
  340. package/dist/modes/interactive/interactive-extension-runtime.js +4 -0
  341. package/dist/modes/interactive/interactive-extension-runtime.js.map +1 -1
  342. package/dist/modes/interactive/interactive-global-clear.d.ts +10 -2
  343. package/dist/modes/interactive/interactive-global-clear.d.ts.map +1 -1
  344. package/dist/modes/interactive/interactive-global-clear.js +3 -1
  345. package/dist/modes/interactive/interactive-global-clear.js.map +1 -1
  346. package/dist/modes/interactive/interactive-input-handling.js +6 -4
  347. package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
  348. package/dist/modes/interactive/interactive-mode-helpers.d.ts +2 -1
  349. package/dist/modes/interactive/interactive-mode-helpers.d.ts.map +1 -1
  350. package/dist/modes/interactive/interactive-mode-helpers.js +6 -10
  351. package/dist/modes/interactive/interactive-mode-helpers.js.map +1 -1
  352. package/dist/modes/interactive/interactive-mode-surface.d.ts +11 -2
  353. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  354. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  355. package/dist/modes/interactive/interactive-render-chat.js +69 -12
  356. package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
  357. package/dist/modes/interactive/interactive-resource-rendering.js +1 -1
  358. package/dist/modes/interactive/interactive-resource-rendering.js.map +1 -1
  359. package/dist/modes/interactive/interactive-selectors.js +10 -0
  360. package/dist/modes/interactive/interactive-selectors.js.map +1 -1
  361. package/dist/modes/interactive/interactive-session-routing.js +3 -0
  362. package/dist/modes/interactive/interactive-session-routing.js.map +1 -1
  363. package/dist/modes/interactive/interactive-slash-commands.js +14 -0
  364. package/dist/modes/interactive/interactive-slash-commands.js.map +1 -1
  365. package/dist/modes/interactive/login-provider-options.d.ts +21 -0
  366. package/dist/modes/interactive/login-provider-options.d.ts.map +1 -0
  367. package/dist/modes/interactive/login-provider-options.js +51 -0
  368. package/dist/modes/interactive/login-provider-options.js.map +1 -0
  369. package/dist/modes/interactive-engine/engine-input-form.d.ts +1 -1
  370. package/dist/modes/interactive-engine/engine-input-form.d.ts.map +1 -1
  371. package/dist/modes/interactive-engine/engine-input-form.js +10 -2
  372. package/dist/modes/interactive-engine/engine-input-form.js.map +1 -1
  373. package/dist/modes/interactive-engine/input-form-host.d.ts.map +1 -1
  374. package/dist/modes/interactive-engine/input-form-host.js +7 -2
  375. package/dist/modes/interactive-engine/input-form-host.js.map +1 -1
  376. package/dist/modes/interactive-engine/isolated-runtime.js +1 -1
  377. package/dist/modes/interactive-engine/isolated-runtime.js.map +1 -1
  378. package/dist/modes/interactive-engine/protocol.d.ts +5 -0
  379. package/dist/modes/interactive-engine/protocol.d.ts.map +1 -1
  380. package/dist/modes/interactive-engine/protocol.js +9 -1
  381. package/dist/modes/interactive-engine/protocol.js.map +1 -1
  382. package/dist/modes/interactive-engine/remote-model-catalog.d.ts +2 -0
  383. package/dist/modes/interactive-engine/remote-model-catalog.d.ts.map +1 -1
  384. package/dist/modes/interactive-engine/remote-model-catalog.js +33 -0
  385. package/dist/modes/interactive-engine/remote-model-catalog.js.map +1 -1
  386. package/dist/modes/rpc/rpc-client-api.d.ts +3 -1
  387. package/dist/modes/rpc/rpc-client-api.d.ts.map +1 -1
  388. package/dist/modes/rpc/rpc-client-api.js +15 -0
  389. package/dist/modes/rpc/rpc-client-api.js.map +1 -1
  390. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  391. package/dist/modes/rpc/rpc-client.js +1 -0
  392. package/dist/modes/rpc/rpc-client.js.map +1 -1
  393. package/dist/modes/rpc/rpc-command-handler.d.ts +5 -1
  394. package/dist/modes/rpc/rpc-command-handler.d.ts.map +1 -1
  395. package/dist/modes/rpc/rpc-command-handler.js +62 -2
  396. package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
  397. package/dist/modes/rpc/rpc-input-scheduler.d.ts.map +1 -1
  398. package/dist/modes/rpc/rpc-input-scheduler.js +1 -0
  399. package/dist/modes/rpc/rpc-input-scheduler.js.map +1 -1
  400. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  401. package/dist/modes/rpc/rpc-mode.js +1 -0
  402. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  403. package/dist/modes/rpc/rpc-types.d.ts +31 -0
  404. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  405. package/dist/modes/rpc/rpc-types.js.map +1 -1
  406. package/dist/package-manager-cli.d.ts +3 -3
  407. package/dist/package-manager-cli.d.ts.map +1 -1
  408. package/dist/package-manager-cli.js +55 -51
  409. package/dist/package-manager-cli.js.map +1 -1
  410. package/dist/self-update-plan.d.ts +12 -0
  411. package/dist/self-update-plan.d.ts.map +1 -0
  412. package/dist/self-update-plan.js +42 -0
  413. package/dist/self-update-plan.js.map +1 -0
  414. package/dist/utils/clipboard-native.d.ts +1 -0
  415. package/dist/utils/clipboard-native.d.ts.map +1 -1
  416. package/dist/utils/clipboard-native.js.map +1 -1
  417. package/dist/utils/clipboard.d.ts +3 -0
  418. package/dist/utils/clipboard.d.ts.map +1 -1
  419. package/dist/utils/clipboard.js +10 -0
  420. package/dist/utils/clipboard.js.map +1 -1
  421. package/dist/utils/version-check.d.ts +1 -0
  422. package/dist/utils/version-check.d.ts.map +1 -1
  423. package/dist/utils/version-check.js +3 -3
  424. package/dist/utils/version-check.js.map +1 -1
  425. package/docs/docs.json +2 -1
  426. package/docs/extensions.md +56 -4
  427. package/docs/keybindings.md +3 -0
  428. package/docs/llama-cpp.md +70 -0
  429. package/docs/models.md +8 -3
  430. package/docs/packages.md +4 -2
  431. package/docs/providers.md +37 -3
  432. package/docs/sdk.md +18 -0
  433. package/docs/settings.md +19 -3
  434. package/npm-shrinkwrap.json +23 -23
  435. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"config-selector.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/config-selector.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAU,MAAM,wBAAwB,CAAC;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAGzE,OAAO,EAAwB,YAAY,EAAe,MAAM,2BAA2B,CAAC;AAC5F,qBAAa,uBAAwB,SAAQ,SAAU,YAAW,SAAS;IAC1E,OAAO,CAAC,YAAY,CAAe;IAEnC,OAAO,CAAC,QAAQ,CAAS;IACzB,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAGzB;IAED,YACC,aAAa,EAAE,aAAa,EAC5B,eAAe,EAAE,eAAe,EAChC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,IAAI,EACnB,MAAM,EAAE,MAAM,IAAI,EAClB,aAAa,EAAE,MAAM,IAAI,EAuBzB;IAED,eAAe,IAAI,YAAY,CAE9B;CACD"}
1
+ {"version":3,"file":"config-selector.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/config-selector.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,OAAO,EAAkB,SAAS,EAAE,KAAK,SAAS,EAAyC,MAAM,wBAAwB,CAAC;AAE1H,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAIzE,OAAO,EAAE,YAAY,EAAmC,MAAM,2BAA2B,CAAC;AAE1F,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,SAAS,CAAC;AACpD,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;AAwB1E,qBAAa,uBAAwB,SAAQ,SAAU,YAAW,SAAS;IAC1E,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAC9C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4C;IACnE,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,QAAQ,CAAS;IACzB,IAAI,OAAO,IAAI,OAAO,CAA0B;IAChD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAA+D;IAEzF,YACC,aAAa,EAAE,mBAAmB,EAClC,eAAe,EAAE,eAAe,EAChC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,IAAI,EACnB,MAAM,EAAE,MAAM,IAAI,EAClB,aAAa,EAAE,MAAM,IAAI,EACzB,cAAc,CAAC,EAAE,MAAM,EACvB,UAAU,GAAE,gBAA2B,EACvC,oBAAoB,UAAO,EA6B3B;IACD,eAAe,IAAI,YAAY,CAA8B;CAC7D"}
@@ -1,39 +1,63 @@
1
- /**
2
- * TUI component for managing package resources (enable/disable)
3
- */
4
- import { Container, Spacer } from "@earendil-works/pi-tui";
1
+ /** TUI component for managing global and project package resources. */
2
+ import { Container, Spacer, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
3
+ import { CONFIG_DIR_NAME } from "../../../config.js";
4
+ import { theme } from "../theme/theme.js";
5
5
  import { DynamicBorder } from "./dynamic-border.js";
6
- import { ConfigSelectorHeader, ResourceList, buildGroups } from "./config-selector-list.js";
7
- export class ConfigSelectorComponent extends Container {
8
- get focused() {
9
- return this._focused;
6
+ import { keyHint, rawKeyHint } from "./keybinding-hints.js";
7
+ import { ResourceList, buildGroups } from "./config-selector-list.js";
8
+ class ConfigSelectorHeader {
9
+ constructor(writeScope, projectModeAvailable) {
10
+ this.writeScope = writeScope;
11
+ this.projectModeAvailable = projectModeAvailable;
10
12
  }
11
- set focused(value) {
12
- this._focused = value;
13
- this.resourceList.focused = value;
13
+ setWriteScope(scope) { this.writeScope = scope; }
14
+ invalidate() { }
15
+ render(width) {
16
+ const title = theme.bold(this.writeScope === "project" ? "Project Local Resources" : "Global Resources");
17
+ const sep = theme.fg("muted", " · ");
18
+ const switchHint = this.projectModeAvailable ? keyHint("tui.input.tab", "switch scope") + sep : "";
19
+ const hint = switchHint + rawKeyHint("space", "toggle") + sep + rawKeyHint("esc", "close");
20
+ const spacing = Math.max(1, width - visibleWidth(title) - visibleWidth(hint));
21
+ const scopeFile = this.writeScope === "project"
22
+ ? `${CONFIG_DIR_NAME}/settings.json · global resources are inherited`
23
+ : `~/${CONFIG_DIR_NAME}/agent/settings.json`;
24
+ return [truncateToWidth(`${title}${" ".repeat(spacing)}${hint}`, width, ""), theme.fg("muted", scopeFile)];
14
25
  }
15
- constructor(resolvedPaths, settingsManager, cwd, agentDir, onClose, onExit, requestRender) {
26
+ }
27
+ export class ConfigSelectorComponent extends Container {
28
+ get focused() { return this._focused; }
29
+ set focused(value) { this._focused = value; this.resourceList.focused = value; }
30
+ constructor(resolvedPaths, settingsManager, cwd, agentDir, onClose, onExit, requestRender, terminalHeight, writeScope = "global", projectModeAvailable = true) {
16
31
  super();
17
32
  this._focused = false;
18
- const groups = buildGroups(resolvedPaths, agentDir);
19
- // Add header
33
+ this.writeScope = writeScope;
34
+ this.groups = {
35
+ global: buildGroups(resolvedPaths.global, agentDir),
36
+ project: buildGroups(resolvedPaths.project, agentDir),
37
+ };
20
38
  this.addChild(new Spacer(1));
21
39
  this.addChild(new DynamicBorder());
22
40
  this.addChild(new Spacer(1));
23
- this.addChild(new ConfigSelectorHeader());
41
+ this.header = new ConfigSelectorHeader(writeScope, projectModeAvailable);
42
+ this.addChild(this.header);
24
43
  this.addChild(new Spacer(1));
25
- // Resource list
26
- this.resourceList = new ResourceList(groups, settingsManager, cwd, agentDir);
44
+ this.resourceList = new ResourceList(this.groups[writeScope], settingsManager, cwd, agentDir, terminalHeight);
45
+ this.resourceList.setWriteScope(writeScope);
27
46
  this.resourceList.onCancel = onClose;
28
47
  this.resourceList.onExit = onExit;
29
- this.resourceList.onToggle = () => requestRender();
48
+ this.resourceList.onToggle = requestRender;
49
+ if (projectModeAvailable)
50
+ this.resourceList.onSwitchMode = () => {
51
+ this.writeScope = this.writeScope === "global" ? "project" : "global";
52
+ this.header.setWriteScope(this.writeScope);
53
+ this.resourceList.setWriteScope(this.writeScope);
54
+ this.resourceList.setGroups(this.groups[this.writeScope]);
55
+ requestRender();
56
+ };
30
57
  this.addChild(this.resourceList);
31
- // Bottom border
32
58
  this.addChild(new Spacer(1));
33
59
  this.addChild(new DynamicBorder());
34
60
  }
35
- getResourceList() {
36
- return this.resourceList;
37
- }
61
+ getResourceList() { return this.resourceList; }
38
62
  }
39
63
  //# sourceMappingURL=config-selector.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config-selector.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/config-selector.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAkB,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAG3E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC5F,MAAM,OAAO,uBAAwB,SAAQ,SAAS;IAIrD,IAAI,OAAO;QACV,OAAO,IAAI,CAAC,QAAQ,CAAC;IACtB,CAAC;IACD,IAAI,OAAO,CAAC,KAAc;QACzB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC,YAAY,CAAC,OAAO,GAAG,KAAK,CAAC;IACnC,CAAC;IAED,YACC,aAA4B,EAC5B,eAAgC,EAChC,GAAW,EACX,QAAgB,EAChB,OAAmB,EACnB,MAAkB,EAClB,aAAyB;QAEzB,KAAK,EAAE,CAAC;QAlBD,aAAQ,GAAG,KAAK,CAAC;QAoBxB,MAAM,MAAM,GAAG,WAAW,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;QAEpD,aAAa;QACb,IAAI,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7B,IAAI,CAAC,QAAQ,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC;QACnC,IAAI,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7B,IAAI,CAAC,QAAQ,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAE7B,gBAAgB;QAChB,IAAI,CAAC,YAAY,GAAG,IAAI,YAAY,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC7E,IAAI,CAAC,YAAY,CAAC,QAAQ,GAAG,OAAO,CAAC;QACrC,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,MAAM,CAAC;QAClC,IAAI,CAAC,YAAY,CAAC,QAAQ,GAAG,GAAG,EAAE,CAAC,aAAa,EAAE,CAAC;QACnD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAEjC,gBAAgB;QAChB,IAAI,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7B,IAAI,CAAC,QAAQ,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,eAAe;QACd,OAAO,IAAI,CAAC,YAAY,CAAC;IAC1B,CAAC;CACD","sourcesContent":["/**\n * TUI component for managing package resources (enable/disable)\n */\n\nimport { Container, type Focusable, Spacer } from \"@earendil-works/pi-tui\";\nimport type { ResolvedPaths } from \"../../../core/package-manager.ts\";\nimport type { SettingsManager } from \"../../../core/settings-manager.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\n\nimport { ConfigSelectorHeader, ResourceList, buildGroups } from \"./config-selector-list.ts\";\nexport class ConfigSelectorComponent extends Container implements Focusable {\n\tprivate resourceList: ResourceList;\n\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.resourceList.focused = value;\n\t}\n\n\tconstructor(\n\t\tresolvedPaths: ResolvedPaths,\n\t\tsettingsManager: SettingsManager,\n\t\tcwd: string,\n\t\tagentDir: string,\n\t\tonClose: () => void,\n\t\tonExit: () => void,\n\t\trequestRender: () => void,\n\t) {\n\t\tsuper();\n\n\t\tconst groups = buildGroups(resolvedPaths, agentDir);\n\n\t\t// Add header\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new ConfigSelectorHeader());\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Resource list\n\t\tthis.resourceList = new ResourceList(groups, settingsManager, cwd, agentDir);\n\t\tthis.resourceList.onCancel = onClose;\n\t\tthis.resourceList.onExit = onExit;\n\t\tthis.resourceList.onToggle = () => requestRender();\n\t\tthis.addChild(this.resourceList);\n\n\t\t// Bottom border\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t}\n\n\tgetResourceList(): ResourceList {\n\t\treturn this.resourceList;\n\t}\n}\n"]}
1
+ {"version":3,"file":"config-selector.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/config-selector.ts"],"names":[],"mappings":"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","sourcesContent":["/** TUI component for managing global and project package resources. */\nimport { type Component, Container, type Focusable, Spacer, truncateToWidth, visibleWidth } from \"@earendil-works/pi-tui\";\nimport { CONFIG_DIR_NAME } from \"../../../config.ts\";\nimport type { ResolvedPaths } from \"../../../core/package-manager.ts\";\nimport type { SettingsManager } from \"../../../core/settings-manager.ts\";\nimport { theme } from \"../theme/theme.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\nimport { keyHint, rawKeyHint } from \"./keybinding-hints.ts\";\nimport { ResourceList, buildGroups, type ResourceGroup } from \"./config-selector-list.ts\";\n\nexport type ConfigWriteScope = \"global\" | \"project\";\nexport type ScopedResolvedPaths = Record<ConfigWriteScope, ResolvedPaths>;\n\nclass ConfigSelectorHeader implements Component {\n\tprivate writeScope: ConfigWriteScope;\n\tprivate readonly projectModeAvailable: boolean;\n\tconstructor(writeScope: ConfigWriteScope, projectModeAvailable: boolean) {\n\t\tthis.writeScope = writeScope;\n\t\tthis.projectModeAvailable = projectModeAvailable;\n\t}\n\tsetWriteScope(scope: ConfigWriteScope): void { this.writeScope = scope; }\n\tinvalidate(): void {}\n\trender(width: number): string[] {\n\t\tconst title = theme.bold(this.writeScope === \"project\" ? \"Project Local Resources\" : \"Global Resources\");\n\t\tconst sep = theme.fg(\"muted\", \" · \");\n\t\tconst switchHint = this.projectModeAvailable ? keyHint(\"tui.input.tab\", \"switch scope\") + sep : \"\";\n\t\tconst hint = switchHint + rawKeyHint(\"space\", \"toggle\") + sep + rawKeyHint(\"esc\", \"close\");\n\t\tconst spacing = Math.max(1, width - visibleWidth(title) - visibleWidth(hint));\n\t\tconst scopeFile = this.writeScope === \"project\"\n\t\t\t? `${CONFIG_DIR_NAME}/settings.json · global resources are inherited`\n\t\t\t: `~/${CONFIG_DIR_NAME}/agent/settings.json`;\n\t\treturn [truncateToWidth(`${title}${\" \".repeat(spacing)}${hint}`, width, \"\"), theme.fg(\"muted\", scopeFile)];\n\t}\n}\n\nexport class ConfigSelectorComponent extends Container implements Focusable {\n\tprivate readonly header: ConfigSelectorHeader;\n\tprivate readonly resourceList: ResourceList;\n\tprivate readonly groups: Record<ConfigWriteScope, ResourceGroup[]>;\n\tprivate writeScope: ConfigWriteScope;\n\tprivate _focused = false;\n\tget focused(): boolean { return this._focused; }\n\tset focused(value: boolean) { this._focused = value; this.resourceList.focused = value; }\n\n\tconstructor(\n\t\tresolvedPaths: ScopedResolvedPaths,\n\t\tsettingsManager: SettingsManager,\n\t\tcwd: string,\n\t\tagentDir: string,\n\t\tonClose: () => void,\n\t\tonExit: () => void,\n\t\trequestRender: () => void,\n\t\tterminalHeight?: number,\n\t\twriteScope: ConfigWriteScope = \"global\",\n\t\tprojectModeAvailable = true,\n\t) {\n\t\tsuper();\n\t\tthis.writeScope = writeScope;\n\t\tthis.groups = {\n\t\t\tglobal: buildGroups(resolvedPaths.global, agentDir),\n\t\t\tproject: buildGroups(resolvedPaths.project, agentDir),\n\t\t};\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.header = new ConfigSelectorHeader(writeScope, projectModeAvailable);\n\t\tthis.addChild(this.header);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.resourceList = new ResourceList(this.groups[writeScope], settingsManager, cwd, agentDir, terminalHeight);\n\t\tthis.resourceList.setWriteScope(writeScope);\n\t\tthis.resourceList.onCancel = onClose;\n\t\tthis.resourceList.onExit = onExit;\n\t\tthis.resourceList.onToggle = requestRender;\n\t\tif (projectModeAvailable) this.resourceList.onSwitchMode = () => {\n\t\t\tthis.writeScope = this.writeScope === \"global\" ? \"project\" : \"global\";\n\t\t\tthis.header.setWriteScope(this.writeScope);\n\t\t\tthis.resourceList.setWriteScope(this.writeScope);\n\t\t\tthis.resourceList.setGroups(this.groups[this.writeScope]);\n\t\t\trequestRender();\n\t\t};\n\t\tthis.addChild(this.resourceList);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t}\n\tgetResourceList(): ResourceList { return this.resourceList; }\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import { Container } from "@earendil-works/pi-tui";
2
+ import type { EntryRenderer } from "../../../core/extensions/types.ts";
3
+ import type { CustomEntry } from "../../../core/session-manager.ts";
4
+ /** Renders an extension-owned persistent session entry. */
5
+ export declare class CustomEntryComponent extends Container {
6
+ private customComponent?;
7
+ private expanded;
8
+ private readonly entry;
9
+ private readonly renderer;
10
+ constructor(entry: CustomEntry<unknown>, renderer: EntryRenderer);
11
+ hasContent(): boolean;
12
+ setExpanded(expanded: boolean): void;
13
+ invalidate(): void;
14
+ private rebuild;
15
+ }
16
+ //# sourceMappingURL=custom-entry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-entry.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/custom-entry.ts"],"names":[],"mappings":"AACA,OAAO,EAAO,SAAS,EAAgB,MAAM,wBAAwB,CAAC;AACtE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAGpE,2DAA2D;AAC3D,qBAAa,oBAAqB,SAAQ,SAAS;IACjD,OAAO,CAAC,eAAe,CAAC,CAAY;IACpC,OAAO,CAAC,QAAQ,CAAS;IAEzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuB;IAC7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IAEzC,YAAY,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,aAAa,EAK/D;IAED,UAAU,IAAI,OAAO,CAEpB;IAED,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAInC;IAEQ,UAAU,IAAI,IAAI,CAG1B;IAED,OAAO,CAAC,OAAO;CAiBhB"}
@@ -0,0 +1,45 @@
1
+ import { Box, Container, Spacer, Text } from "@earendil-works/pi-tui";
2
+ import { theme } from "../theme/theme.js";
3
+ /** Renders an extension-owned persistent session entry. */
4
+ export class CustomEntryComponent extends Container {
5
+ constructor(entry, renderer) {
6
+ super();
7
+ this.expanded = false;
8
+ this.entry = entry;
9
+ this.renderer = renderer;
10
+ this.rebuild();
11
+ }
12
+ hasContent() {
13
+ return this.customComponent !== undefined;
14
+ }
15
+ setExpanded(expanded) {
16
+ if (this.expanded === expanded)
17
+ return;
18
+ this.expanded = expanded;
19
+ this.rebuild();
20
+ }
21
+ invalidate() {
22
+ super.invalidate();
23
+ this.rebuild();
24
+ }
25
+ rebuild() {
26
+ this.clear();
27
+ this.customComponent = undefined;
28
+ let component;
29
+ try {
30
+ component = this.renderer(this.entry, { expanded: this.expanded }, theme);
31
+ }
32
+ catch (error) {
33
+ const message = error instanceof Error ? error.message : String(error);
34
+ const box = new Box(1, 1, (text) => theme.bg("customMessageBg", text));
35
+ box.addChild(new Text(theme.fg("error", `[${this.entry.customType}] renderer failed: ${message}`), 0, 0));
36
+ component = box;
37
+ }
38
+ if (!component)
39
+ return;
40
+ this.customComponent = component;
41
+ this.addChild(new Spacer(1));
42
+ this.addChild(component);
43
+ }
44
+ }
45
+ //# sourceMappingURL=custom-entry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-entry.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/custom-entry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAGtE,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C,2DAA2D;AAC3D,MAAM,OAAO,oBAAqB,SAAQ,SAAS;IAOjD,YAAY,KAA2B,EAAE,QAAuB;QAC9D,KAAK,EAAE,CAAC;QANF,aAAQ,GAAG,KAAK,CAAC;QAOvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,eAAe,KAAK,SAAS,CAAC;IAC5C,CAAC;IAED,WAAW,CAAC,QAAiB;QAC3B,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ;YAAE,OAAO;QACvC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAEQ,UAAU;QACjB,KAAK,CAAC,UAAU,EAAE,CAAC;QACnB,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAEO,OAAO;QACb,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC;QACjC,IAAI,SAAgC,CAAC;QACrC,IAAI,CAAC;YACH,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,KAAK,CAAC,CAAC;QAC5E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC,CAAC;YACvE,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,sBAAsB,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC1G,SAAS,GAAG,GAAG,CAAC;QAClB,CAAC;QACD,IAAI,CAAC,SAAS;YAAE,OAAO;QACvB,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC;QACjC,IAAI,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7B,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC3B,CAAC;CACF","sourcesContent":["import type { Component } from \"@earendil-works/pi-tui\";\nimport { Box, Container, Spacer, Text } from \"@earendil-works/pi-tui\";\nimport type { EntryRenderer } from \"../../../core/extensions/types.ts\";\nimport type { CustomEntry } from \"../../../core/session-manager.ts\";\nimport { theme } from \"../theme/theme.ts\";\n\n/** Renders an extension-owned persistent session entry. */\nexport class CustomEntryComponent extends Container {\n private customComponent?: Component;\n private expanded = false;\n\n private readonly entry: CustomEntry<unknown>;\n private readonly renderer: EntryRenderer;\n\n constructor(entry: CustomEntry<unknown>, renderer: EntryRenderer) {\n super();\n this.entry = entry;\n this.renderer = renderer;\n this.rebuild();\n }\n\n hasContent(): boolean {\n return this.customComponent !== undefined;\n }\n\n setExpanded(expanded: boolean): void {\n if (this.expanded === expanded) return;\n this.expanded = expanded;\n this.rebuild();\n }\n\n override invalidate(): void {\n super.invalidate();\n this.rebuild();\n }\n\n private rebuild(): void {\n this.clear();\n this.customComponent = undefined;\n let component: Component | undefined;\n try {\n component = this.renderer(this.entry, { expanded: this.expanded }, theme);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const box = new Box(1, 1, (text) => theme.bg(\"customMessageBg\", text));\n box.addChild(new Text(theme.fg(\"error\", `[${this.entry.customType}] renderer failed: ${message}`), 0, 0));\n component = box;\n }\n if (!component) return;\n this.customComponent = component;\n this.addChild(new Spacer(1));\n this.addChild(component);\n }\n}\n"]}
@@ -0,0 +1,24 @@
1
+ import { Container } from "@earendil-works/pi-tui";
2
+ import { type TerminalTheme } from "../theme/theme.ts";
3
+ export interface FirstTimeSetupResult {
4
+ theme: TerminalTheme;
5
+ shareAnalytics: boolean;
6
+ }
7
+ export interface FirstTimeSetupOptions {
8
+ detectedTheme: TerminalTheme;
9
+ onThemePreview(themeName: TerminalTheme): void;
10
+ onSubmit(result: FirstTimeSetupResult): void;
11
+ onCancel(): void;
12
+ }
13
+ export declare class FirstTimeSetupComponent extends Container {
14
+ private step;
15
+ private themeIndex;
16
+ private analyticsIndex;
17
+ private readonly options;
18
+ constructor(options: FirstTimeSetupOptions);
19
+ private update;
20
+ private addOptions;
21
+ private move;
22
+ handleInput(data: string): void;
23
+ }
24
+ //# sourceMappingURL=first-time-setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"first-time-setup.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/first-time-setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAgC,MAAM,wBAAwB,CAAC;AAEjF,OAAO,EAAE,KAAK,aAAa,EAAS,MAAM,mBAAmB,CAAC;AAI9D,MAAM,WAAW,oBAAoB;IAAG,KAAK,EAAE,aAAa,CAAC;IAAC,cAAc,EAAE,OAAO,CAAA;CAAE;AACvF,MAAM,WAAW,qBAAqB;IACrC,aAAa,EAAE,aAAa,CAAC;IAC7B,cAAc,CAAC,SAAS,EAAE,aAAa,GAAG,IAAI,CAAC;IAC/C,QAAQ,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC7C,QAAQ,IAAI,IAAI,CAAC;CACjB;AAID,qBAAa,uBAAwB,SAAQ,SAAS;IACrD,OAAO,CAAC,IAAI,CAAkC;IAC9C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,YAAY,OAAO,EAAE,qBAAqB,EAKzC;IACD,OAAO,CAAC,MAAM;IAmBd,OAAO,CAAC,UAAU;IAKlB,OAAO,CAAC,IAAI;IAOZ,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAQ9B;CACD"}
@@ -0,0 +1,69 @@
1
+ import { Container, getKeybindings, Spacer, Text } from "@earendil-works/pi-tui";
2
+ import { APP_NAME } from "../../../config.js";
3
+ import { theme } from "../theme/theme.js";
4
+ import { DynamicBorder } from "./dynamic-border.js";
5
+ import { keyHint, rawKeyHint } from "./keybinding-hints.js";
6
+ const THEMES = [{ value: "dark", label: "Dark" }, { value: "light", label: "Light" }];
7
+ const ANALYTICS = [{ value: true, label: "Share anonymous usage data" }, { value: false, label: "Don't share" }];
8
+ export class FirstTimeSetupComponent extends Container {
9
+ constructor(options) {
10
+ super();
11
+ this.step = "theme";
12
+ this.analyticsIndex = 0;
13
+ this.options = options;
14
+ this.themeIndex = Math.max(0, THEMES.findIndex((option) => option.value === options.detectedTheme));
15
+ this.update();
16
+ }
17
+ update() {
18
+ this.clear();
19
+ this.addChild(new DynamicBorder());
20
+ this.addChild(new Spacer(1));
21
+ this.addChild(new Text(theme.fg("accent", theme.bold(`Welcome to ${APP_NAME}.`)), 1, 0));
22
+ this.addChild(new Spacer(1));
23
+ if (this.step === "theme") {
24
+ this.addChild(new Text(theme.fg("text", "Pick a theme."), 1, 0));
25
+ this.addChild(new Text(theme.fg("muted", `Detected system appearance: ${this.options.detectedTheme}`), 1, 0));
26
+ this.addOptions(THEMES.map((option) => option.label), this.themeIndex);
27
+ }
28
+ else {
29
+ this.addChild(new Text(theme.fg("text", "Opt in to anonymous usage analytics?"), 1, 0));
30
+ this.addChild(new Text(theme.fg("muted", "This choice and a random tracking ID are stored locally in settings.json.\nAtomic does not transmit analytics data in this release. You can change this setting anytime."), 1, 0));
31
+ this.addOptions(ANALYTICS.map((option) => option.label), this.analyticsIndex);
32
+ }
33
+ this.addChild(new Spacer(1));
34
+ this.addChild(new Text(`${rawKeyHint("↑↓", "navigate")} ${keyHint("tui.select.confirm", this.step === "theme" ? "continue" : "finish")} ${keyHint("tui.select.cancel", "skip setup")}`, 1, 0));
35
+ this.addChild(new DynamicBorder());
36
+ }
37
+ addOptions(labels, selected) {
38
+ for (let index = 0; index < labels.length; index++) {
39
+ this.addChild(new Text(index === selected ? theme.fg("accent", `→ ${labels[index]}`) : ` ${theme.fg("text", labels[index] ?? "")}`, 1, 0));
40
+ }
41
+ }
42
+ move(delta) {
43
+ if (this.step === "theme") {
44
+ this.themeIndex = Math.max(0, Math.min(THEMES.length - 1, this.themeIndex + delta));
45
+ this.options.onThemePreview(THEMES[this.themeIndex].value);
46
+ }
47
+ else
48
+ this.analyticsIndex = Math.max(0, Math.min(ANALYTICS.length - 1, this.analyticsIndex + delta));
49
+ this.update();
50
+ }
51
+ handleInput(data) {
52
+ const keys = getKeybindings();
53
+ if (keys.matches(data, "tui.select.up") || data === "k")
54
+ this.move(-1);
55
+ else if (keys.matches(data, "tui.select.down") || data === "j")
56
+ this.move(1);
57
+ else if (keys.matches(data, "tui.select.confirm") || data === "\n") {
58
+ if (this.step === "theme") {
59
+ this.step = "analytics";
60
+ this.update();
61
+ }
62
+ else
63
+ this.options.onSubmit({ theme: THEMES[this.themeIndex].value, shareAnalytics: ANALYTICS[this.analyticsIndex].value });
64
+ }
65
+ else if (keys.matches(data, "tui.select.cancel"))
66
+ this.options.onCancel();
67
+ }
68
+ }
69
+ //# sourceMappingURL=first-time-setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"first-time-setup.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/first-time-setup.ts"],"names":[],"mappings":"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","sourcesContent":["import { Container, getKeybindings, Spacer, Text } from \"@earendil-works/pi-tui\";\nimport { APP_NAME } from \"../../../config.ts\";\nimport { type TerminalTheme, theme } from \"../theme/theme.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\nimport { keyHint, rawKeyHint } from \"./keybinding-hints.ts\";\n\nexport interface FirstTimeSetupResult { theme: TerminalTheme; shareAnalytics: boolean }\nexport interface FirstTimeSetupOptions {\n\tdetectedTheme: TerminalTheme;\n\tonThemePreview(themeName: TerminalTheme): void;\n\tonSubmit(result: FirstTimeSetupResult): void;\n\tonCancel(): void;\n}\nconst THEMES: Array<{ value: TerminalTheme; label: string }> = [{ value: \"dark\", label: \"Dark\" }, { value: \"light\", label: \"Light\" }];\nconst ANALYTICS = [{ value: true, label: \"Share anonymous usage data\" }, { value: false, label: \"Don't share\" }];\n\nexport class FirstTimeSetupComponent extends Container {\n\tprivate step: \"theme\" | \"analytics\" = \"theme\";\n\tprivate themeIndex: number;\n\tprivate analyticsIndex = 0;\n\tprivate readonly options: FirstTimeSetupOptions;\n\tconstructor(options: FirstTimeSetupOptions) {\n\t\tsuper();\n\t\tthis.options = options;\n\t\tthis.themeIndex = Math.max(0, THEMES.findIndex((option) => option.value === options.detectedTheme));\n\t\tthis.update();\n\t}\n\tprivate update(): void {\n\t\tthis.clear();\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new Text(theme.fg(\"accent\", theme.bold(`Welcome to ${APP_NAME}.`)), 1, 0));\n\t\tthis.addChild(new Spacer(1));\n\t\tif (this.step === \"theme\") {\n\t\t\tthis.addChild(new Text(theme.fg(\"text\", \"Pick a theme.\"), 1, 0));\n\t\t\tthis.addChild(new Text(theme.fg(\"muted\", `Detected system appearance: ${this.options.detectedTheme}`), 1, 0));\n\t\t\tthis.addOptions(THEMES.map((option) => option.label), this.themeIndex);\n\t\t} else {\n\t\t\tthis.addChild(new Text(theme.fg(\"text\", \"Opt in to anonymous usage analytics?\"), 1, 0));\n\t\t\tthis.addChild(new Text(theme.fg(\"muted\", \"This choice and a random tracking ID are stored locally in settings.json.\\nAtomic does not transmit analytics data in this release. You can change this setting anytime.\"), 1, 0));\n\t\t\tthis.addOptions(ANALYTICS.map((option) => option.label), this.analyticsIndex);\n\t\t}\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new Text(`${rawKeyHint(\"↑↓\", \"navigate\")} ${keyHint(\"tui.select.confirm\", this.step === \"theme\" ? \"continue\" : \"finish\")} ${keyHint(\"tui.select.cancel\", \"skip setup\")}`, 1, 0));\n\t\tthis.addChild(new DynamicBorder());\n\t}\n\tprivate addOptions(labels: string[], selected: number): void {\n\t\tfor (let index = 0; index < labels.length; index++) {\n\t\t\tthis.addChild(new Text(index === selected ? theme.fg(\"accent\", `→ ${labels[index]}`) : ` ${theme.fg(\"text\", labels[index] ?? \"\")}`, 1, 0));\n\t\t}\n\t}\n\tprivate move(delta: number): void {\n\t\tif (this.step === \"theme\") {\n\t\t\tthis.themeIndex = Math.max(0, Math.min(THEMES.length - 1, this.themeIndex + delta));\n\t\t\tthis.options.onThemePreview(THEMES[this.themeIndex]!.value);\n\t\t} else this.analyticsIndex = Math.max(0, Math.min(ANALYTICS.length - 1, this.analyticsIndex + delta));\n\t\tthis.update();\n\t}\n\thandleInput(data: string): void {\n\t\tconst keys = getKeybindings();\n\t\tif (keys.matches(data, \"tui.select.up\") || data === \"k\") this.move(-1);\n\t\telse if (keys.matches(data, \"tui.select.down\") || data === \"j\") this.move(1);\n\t\telse if (keys.matches(data, \"tui.select.confirm\") || data === \"\\n\") {\n\t\t\tif (this.step === \"theme\") { this.step = \"analytics\"; this.update(); }\n\t\t\telse this.options.onSubmit({ theme: THEMES[this.themeIndex]!.value, shareAnalytics: ANALYTICS[this.analyticsIndex]!.value });\n\t\t} else if (keys.matches(data, \"tui.select.cancel\")) this.options.onCancel();\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/footer.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,SAAS,EAGf,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAKnE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAC;AAsHxF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAYhF;AAED;;;GAGG;AACH,qBAAa,mBAAoB,YAAW,SAAS;IACnD,OAAO,CAAC,kBAAkB,CAAQ;IAElC,QAAgB,OAAO,CAAe;IAEtC,YAAY,OAAO,EAAE,YAAY,EAEjC;IAEA,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAEtC;IAED,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAE5C;IAED,UAAU,IAAI,IAAI,CAEjB;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAE9B;CACF;AAED;;;GAGG;AACH,qBAAa,eAAgB,YAAW,SAAS;IAC/C,QAAgB,OAAO,CAAe;IACtC,QAAgB,UAAU,CAA6B;IAEvD,YACE,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,0BAA0B,EAIxC;IAEA,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAEtC;IAED,qBAAqB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAE7C;IAED;;;OAGG;IACH,UAAU,IAAI,IAAI,CAEjB;IAED;;;OAGG;IACH,OAAO,IAAI,IAAI,CAEd;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CA+B9B;CACF"}
1
+ {"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/footer.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,SAAS,EAGf,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAKnE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAC;AA4HxF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAYhF;AAED;;;GAGG;AACH,qBAAa,mBAAoB,YAAW,SAAS;IACnD,OAAO,CAAC,kBAAkB,CAAQ;IAElC,QAAgB,OAAO,CAAe;IAEtC,YAAY,OAAO,EAAE,YAAY,EAEjC;IAEA,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAEtC;IAED,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAE5C;IAED,UAAU,IAAI,IAAI,CAEjB;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAE9B;CACF;AAED;;;GAGG;AACH,qBAAa,eAAgB,YAAW,SAAS;IAC/C,QAAgB,OAAO,CAAe;IACtC,QAAgB,UAAU,CAA6B;IAEvD,YACE,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,0BAA0B,EAIxC;IAEA,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAEtC;IAED,qBAAqB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAE7C;IAED;;;OAGG;IACH,UAAU,IAAI,IAAI,CAEjB;IAED;;;OAGG;IACH,OAAO,IAAI,IAAI,CAEd;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CA0C9B;CACF"}
@@ -1,7 +1,16 @@
1
1
  import { isAbsolute, relative, resolve, sep } from "node:path";
2
2
  import { truncateToWidth, visibleWidth, } from "@earendil-works/pi-tui";
3
3
  import { formatCodexFastModeModelLabel, shouldApplyCodexFastMode, } from "../../../core/codex-fast-mode.js";
4
+ import { areExperimentalFeaturesEnabled } from "../../../core/experimental.js";
5
+ import { addUsageToTotals, createUsageTotals } from "../../../core/usage-totals.js";
4
6
  import { theme } from "../theme/theme.js";
7
+ function sanitizeStatusText(text) {
8
+ // Replace newlines, tabs, carriage returns with space, then collapse
9
+ // multiple spaces (pi parity). ANSI/SGR sequences must survive intact:
10
+ // extension statuses are frequently theme-colored, and stripping only the
11
+ // ESC byte would leave the rest of the sequence as visible literal text.
12
+ return text.replace(/[\r\n\t]/g, " ").replace(/ +/g, " ").trim();
13
+ }
5
14
  /**
6
15
  * Format token counts (similar to web-ui)
7
16
  */
@@ -29,22 +38,20 @@ function rightAlign(line, width) {
29
38
  function getUsageLine(session, autoCompactEnabled, width) {
30
39
  const state = session.state;
31
40
  // Calculate cumulative usage from ALL session entries (not just post-compaction messages)
32
- let totalInput = 0;
33
- let totalOutput = 0;
34
- let totalCacheRead = 0;
35
- let totalCacheWrite = 0;
36
- let totalCost = 0;
41
+ const totals = createUsageTotals();
37
42
  let latestCacheHitRate;
38
43
  for (const entry of session.sessionManager.getEntries()) {
39
44
  if (entry.type === "message" && entry.message.role === "assistant") {
40
- totalInput += entry.message.usage.input;
41
- totalOutput += entry.message.usage.output;
42
- totalCacheRead += entry.message.usage.cacheRead;
43
- totalCacheWrite += entry.message.usage.cacheWrite;
44
- totalCost += entry.message.usage.cost.total;
45
+ addUsageToTotals(totals, entry.message.usage);
45
46
  const latestPromptTokens = entry.message.usage.input + entry.message.usage.cacheRead + entry.message.usage.cacheWrite;
46
47
  latestCacheHitRate = latestPromptTokens > 0 ? (entry.message.usage.cacheRead / latestPromptTokens) * 100 : undefined;
47
48
  }
49
+ else if (entry.type === "branch_summary" && entry.usage) {
50
+ addUsageToTotals(totals, entry.usage);
51
+ }
52
+ else if (entry.type === "message" && entry.message.role === "toolResult" && "usage" in entry.message && entry.message.usage) {
53
+ addUsageToTotals(totals, entry.message.usage);
54
+ }
48
55
  }
49
56
  // Calculate context usage from session (handles compaction correctly).
50
57
  // After compaction, tokens are unknown until the next LLM response.
@@ -53,23 +60,23 @@ function getUsageLine(session, autoCompactEnabled, width) {
53
60
  const contextPercentValue = contextUsage?.percent ?? 0;
54
61
  const contextPercent = contextUsage?.percent !== null ? contextPercentValue.toFixed(1) : "?";
55
62
  const usageParts = [];
56
- if (totalInput)
57
- usageParts.push(`${theme.fg("dim", "↑")}${theme.fg("muted", formatTokens(totalInput))}`);
58
- if (totalOutput)
59
- usageParts.push(`${theme.fg("dim", "↓")}${theme.fg("muted", formatTokens(totalOutput))}`);
60
- if (totalCacheRead)
61
- usageParts.push(`${theme.fg("dim", "R")}${theme.fg("muted", formatTokens(totalCacheRead))}`);
62
- if (totalCacheWrite)
63
- usageParts.push(`${theme.fg("dim", "W")}${theme.fg("muted", formatTokens(totalCacheWrite))}`);
64
- if ((totalCacheRead > 0 || totalCacheWrite > 0) && latestCacheHitRate !== undefined) {
63
+ if (totals.input)
64
+ usageParts.push(`${theme.fg("dim", "↑")}${theme.fg("muted", formatTokens(totals.input))}`);
65
+ if (totals.output)
66
+ usageParts.push(`${theme.fg("dim", "↓")}${theme.fg("muted", formatTokens(totals.output))}`);
67
+ if (totals.cacheRead)
68
+ usageParts.push(`${theme.fg("dim", "R")}${theme.fg("muted", formatTokens(totals.cacheRead))}`);
69
+ if (totals.cacheWrite)
70
+ usageParts.push(`${theme.fg("dim", "W")}${theme.fg("muted", formatTokens(totals.cacheWrite))}`);
71
+ if ((totals.cacheRead > 0 || totals.cacheWrite > 0) && latestCacheHitRate !== undefined) {
65
72
  usageParts.push(`${theme.fg("dim", "CH")}${theme.fg("muted", `${latestCacheHitRate.toFixed(1)}%`)}`);
66
73
  }
67
74
  // Kimi Coding is subscription-backed despite using API-key authentication.
68
75
  const usingSubscription = state.model
69
76
  ? state.model.provider === "kimi-coding" || session.modelRegistry.isUsingOAuth(state.model)
70
77
  : false;
71
- if (totalCost || usingSubscription) {
72
- usageParts.push(`${theme.fg("muted", `$${totalCost.toFixed(3)}`)}${usingSubscription ? ` ${theme.fg("dim", "(sub)")}` : ""}`);
78
+ if (totals.cost || usingSubscription) {
79
+ usageParts.push(`${theme.fg("muted", `$${totals.cost.toFixed(3)}`)}${usingSubscription ? ` ${theme.fg("dim", "(sub)")}` : ""}`);
73
80
  }
74
81
  const autoIndicator = autoCompactEnabled ? " (auto)" : "";
75
82
  const contextPercentDisplay = contextPercent === "?"
@@ -158,7 +165,15 @@ export class FooterComponent {
158
165
  }
159
166
  render(width) {
160
167
  const state = this.session.state;
161
- const pwd = replaceHome(this.session.sessionManager.getCwd());
168
+ let pwd = replaceHome(this.session.sessionManager.getCwd());
169
+ const branch = this.footerData.getGitBranch();
170
+ if (branch)
171
+ pwd += ` (${branch})`;
172
+ const sessionName = typeof this.session.sessionManager.getSessionName === "function"
173
+ ? this.session.sessionManager.getSessionName()
174
+ : undefined;
175
+ if (sessionName)
176
+ pwd += ` • ${sessionName}`;
162
177
  const modelName = state.model?.id || "no-model";
163
178
  const fastModeSettings = this.session.settingsManager.getCodexFastModeSettings();
164
179
  const fastModeEnabled = state.model
@@ -177,9 +192,16 @@ export class FooterComponent {
177
192
  const liveState = this.session.isStreaming
178
193
  ? theme.fg("muted", "esc to interrupt")
179
194
  : undefined;
180
- const statusText = liveState ??
195
+ let statusText = liveState ??
181
196
  `${theme.fg("dim", modelLabel)} ${theme.fg("dim", "•")} ${theme.fg("muted", pwd)}`;
182
- return [truncateToWidth(statusText, width, theme.fg("dim", "..."))];
197
+ if (areExperimentalFeaturesEnabled())
198
+ statusText += ` ${theme.fg("warning", "xp")}`;
199
+ const lines = [truncateToWidth(statusText, width, theme.fg("dim", "..."))];
200
+ const statuses = [...this.footerData.getExtensionStatuses()].sort(([a], [b]) => a.localeCompare(b));
201
+ if (statuses.length > 0) {
202
+ lines.push(truncateToWidth(statuses.map(([, text]) => sanitizeStatusText(text)).join(" "), width, theme.fg("dim", "...")));
203
+ }
204
+ return lines;
183
205
  }
184
206
  }
185
207
  //# sourceMappingURL=footer.js.map
@@ -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 {\n type Component,\n truncateToWidth,\n visibleWidth,\n} from \"@earendil-works/pi-tui\";\nimport type { AgentSession } from \"../../../core/agent-session.ts\";\nimport {\n formatCodexFastModeModelLabel,\n shouldApplyCodexFastMode,\n} from \"../../../core/codex-fast-mode.ts\";\nimport type { ReadonlyFooterDataProvider } from \"../../../core/footer-data-provider.ts\";\nimport { theme } from \"../theme/theme.ts\";\n\n/**\n * Format token counts (similar to web-ui)\n */\nfunction formatTokens(count: number): string {\n if (count < 1000) return count.toString();\n if (count < 10000) return `${(count / 1000).toFixed(1)}k`;\n if (count < 1000000) return `${Math.round(count / 1000)}k`;\n if (count < 10000000) return `${(count / 1000000).toFixed(1)}M`;\n return `${Math.round(count / 1000000)}M`;\n}\n\nfunction replaceHome(input: string): string {\n return formatCwdForFooter(input, process.env.HOME || process.env.USERPROFILE);\n}\n\nfunction rightAlign(line: string, width: number): string {\n const lineWidth = visibleWidth(line);\n if (lineWidth >= width) {\n return truncateToWidth(line, width, theme.fg(\"dim\", \"...\"));\n }\n return `${\" \".repeat(width - lineWidth)}${line}`;\n}\n\nfunction getUsageLine(\n session: AgentSession,\n autoCompactEnabled: boolean,\n width: number,\n): string {\n const state = session.state;\n\n // Calculate cumulative usage from ALL session entries (not just post-compaction messages)\n let totalInput = 0;\n let totalOutput = 0;\n let totalCacheRead = 0;\n let totalCacheWrite = 0;\n let totalCost = 0;\n let latestCacheHitRate: number | undefined;\n\n for (const entry of session.sessionManager.getEntries()) {\n if (entry.type === \"message\" && entry.message.role === \"assistant\") {\n totalInput += entry.message.usage.input;\n totalOutput += entry.message.usage.output;\n totalCacheRead += entry.message.usage.cacheRead;\n totalCacheWrite += entry.message.usage.cacheWrite;\n totalCost += entry.message.usage.cost.total;\n\n const latestPromptTokens =\n entry.message.usage.input + entry.message.usage.cacheRead + entry.message.usage.cacheWrite;\n latestCacheHitRate = latestPromptTokens > 0 ? (entry.message.usage.cacheRead / latestPromptTokens) * 100 : undefined;\n }\n }\n\n // Calculate context usage from session (handles compaction correctly).\n // After compaction, tokens are unknown until the next LLM response.\n const contextUsage = session.getContextUsage();\n const contextWindow =\n contextUsage?.contextWindow ?? state.model?.contextWindow ?? 0;\n const contextPercentValue = contextUsage?.percent ?? 0;\n const contextPercent =\n contextUsage?.percent !== null ? contextPercentValue.toFixed(1) : \"?\";\n\n const usageParts = [];\n if (totalInput)\n usageParts.push(\n `${theme.fg(\"dim\", \"↑\")}${theme.fg(\"muted\", formatTokens(totalInput))}`,\n );\n if (totalOutput)\n usageParts.push(\n `${theme.fg(\"dim\", \"↓\")}${theme.fg(\"muted\", formatTokens(totalOutput))}`,\n );\n if (totalCacheRead)\n usageParts.push(\n `${theme.fg(\"dim\", \"R\")}${theme.fg(\"muted\", formatTokens(totalCacheRead))}`,\n );\n if (totalCacheWrite)\n usageParts.push(\n `${theme.fg(\"dim\", \"W\")}${theme.fg(\"muted\", formatTokens(totalCacheWrite))}`,\n );\n if ((totalCacheRead > 0 || totalCacheWrite > 0) && latestCacheHitRate !== undefined) {\n usageParts.push(`${theme.fg(\"dim\", \"CH\")}${theme.fg(\"muted\", `${latestCacheHitRate.toFixed(1)}%`)}`);\n }\n\n // Kimi Coding is subscription-backed despite using API-key authentication.\n const usingSubscription = state.model\n ? state.model.provider === \"kimi-coding\" || session.modelRegistry.isUsingOAuth(state.model)\n : false;\n if (totalCost || usingSubscription) {\n usageParts.push(\n `${theme.fg(\"muted\", `$${totalCost.toFixed(3)}`)}${usingSubscription ? ` ${theme.fg(\"dim\", \"(sub)\")}` : \"\"}`,\n );\n }\n\n const autoIndicator = autoCompactEnabled ? \" (auto)\" : \"\";\n const contextPercentDisplay =\n contextPercent === \"?\"\n ? `?/${formatTokens(contextWindow)}${autoIndicator}`\n : `${contextPercent}%/${formatTokens(contextWindow)}${autoIndicator}`;\n if (autoCompactEnabled && contextPercentValue > 70) {\n usageParts.push(theme.fg(\"warning\", contextPercentDisplay));\n } else if (contextPercentValue > 90) {\n usageParts.push(theme.fg(\"error\", contextPercentDisplay));\n } else if (contextPercentValue > 70) {\n usageParts.push(theme.fg(\"warning\", contextPercentDisplay));\n } else {\n usageParts.push(theme.fg(\"muted\", contextPercentDisplay));\n }\n\n const separator = theme.fg(\"dim\", \" • \");\n const usageText =\n usageParts.length > 0\n ? usageParts.join(separator)\n : theme.fg(\"muted\", contextPercentDisplay);\n return rightAlign(usageText, width);\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 * Right-aligned usage meter that sits above the composer, matching the approved\n * prototype's separate token/cost/context ribbon.\n */\nexport class UsageMeterComponent implements Component {\n private autoCompactEnabled = true;\n\n declare private session: AgentSession;\n\n constructor(session: AgentSession) {\n this.session = session;\n\t}\n\n setSession(session: AgentSession): void {\n this.session = session;\n }\n\n setAutoCompactEnabled(enabled: boolean): void {\n this.autoCompactEnabled = enabled;\n }\n\n invalidate(): void {\n // Render pulls live session data.\n }\n\n render(width: number): string[] {\n return [getUsageLine(this.session, this.autoCompactEnabled, width)];\n }\n}\n\n/**\n * Sparse statusline below the composer. It mirrors the preview: model + cwd\n * when idle, or one semantic dot with short recovery copy while work is live.\n */\nexport class FooterComponent implements Component {\n declare private session: AgentSession;\n declare private footerData: ReadonlyFooterDataProvider;\n\n constructor(\n session: AgentSession,\n footerData: ReadonlyFooterDataProvider,\n ) {\n this.session = session;\n this.footerData = footerData;\n\t}\n\n setSession(session: AgentSession): void {\n this.session = session;\n }\n\n setAutoCompactEnabled(_enabled: boolean): void {\n // Usage state lives in UsageMeterComponent. Kept for compatibility with existing call sites.\n }\n\n /**\n * No-op: git branch caching now handled by provider.\n * Kept for compatibility with existing call sites in interactive-mode.\n */\n invalidate(): void {\n // No-op: git branch is cached/invalidated by provider\n }\n\n /**\n * Clean up resources.\n * Git watcher cleanup now handled by provider.\n */\n dispose(): void {\n // Git watcher cleanup handled by provider\n }\n\n render(width: number): string[] {\n const state = this.session.state;\n const pwd = replaceHome(this.session.sessionManager.getCwd());\n\n const modelName = state.model?.id || \"no-model\";\n const fastModeSettings = this.session.settingsManager.getCodexFastModeSettings();\n const fastModeEnabled = state.model\n ? shouldApplyCodexFastMode(\n state.model,\n fastModeSettings,\n this.session.orchestrationContext,\n )\n : false;\n let modelLabel = modelName;\n if (state.model?.reasoning) {\n const thinkingLevel = state.thinkingLevel || \"off\";\n modelLabel =\n thinkingLevel === \"off\" ? modelLabel : `${modelLabel} ${thinkingLevel}`;\n }\n modelLabel = formatCodexFastModeModelLabel(modelLabel, fastModeEnabled);\n if (this.footerData.getAvailableProviderCount() > 1 && state.model) {\n modelLabel = `(${state.model.provider}) ${modelLabel}`;\n }\n\n const liveState = this.session.isStreaming\n ? theme.fg(\"muted\", \"esc to interrupt\")\n : undefined;\n const statusText =\n liveState ??\n `${theme.fg(\"dim\", modelLabel)} ${theme.fg(\"dim\", \"•\")} ${theme.fg(\"muted\", pwd)}`;\n return [truncateToWidth(statusText, width, theme.fg(\"dim\", \"...\"))];\n }\n}\n"]}
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 {\n type Component,\n truncateToWidth,\n visibleWidth,\n} from \"@earendil-works/pi-tui\";\nimport type { AgentSession } from \"../../../core/agent-session.ts\";\nimport {\n formatCodexFastModeModelLabel,\n shouldApplyCodexFastMode,\n} from \"../../../core/codex-fast-mode.ts\";\nimport type { ReadonlyFooterDataProvider } from \"../../../core/footer-data-provider.ts\";\nimport { areExperimentalFeaturesEnabled } from \"../../../core/experimental.ts\";\nimport { addUsageToTotals, createUsageTotals } from \"../../../core/usage-totals.ts\";\nimport { theme } from \"../theme/theme.ts\";\n\nfunction sanitizeStatusText(text: string): string {\n // Replace newlines, tabs, carriage returns with space, then collapse\n // multiple spaces (pi parity). ANSI/SGR sequences must survive intact:\n // extension statuses are frequently theme-colored, and stripping only the\n // ESC byte would leave the rest of the sequence as visible literal text.\n return text.replace(/[\\r\\n\\t]/g, \" \").replace(/ +/g, \" \").trim();\n}\n\n/**\n * Format token counts (similar to web-ui)\n */\nfunction formatTokens(count: number): string {\n if (count < 1000) return count.toString();\n if (count < 10000) return `${(count / 1000).toFixed(1)}k`;\n if (count < 1000000) return `${Math.round(count / 1000)}k`;\n if (count < 10000000) return `${(count / 1000000).toFixed(1)}M`;\n return `${Math.round(count / 1000000)}M`;\n}\n\nfunction replaceHome(input: string): string {\n return formatCwdForFooter(input, process.env.HOME || process.env.USERPROFILE);\n}\n\nfunction rightAlign(line: string, width: number): string {\n const lineWidth = visibleWidth(line);\n if (lineWidth >= width) {\n return truncateToWidth(line, width, theme.fg(\"dim\", \"...\"));\n }\n return `${\" \".repeat(width - lineWidth)}${line}`;\n}\n\nfunction getUsageLine(\n session: AgentSession,\n autoCompactEnabled: boolean,\n width: number,\n): string {\n const state = session.state;\n\n // Calculate cumulative usage from ALL session entries (not just post-compaction messages)\n const totals = createUsageTotals();\n let latestCacheHitRate: number | undefined;\n\n for (const entry of session.sessionManager.getEntries()) {\n if (entry.type === \"message\" && entry.message.role === \"assistant\") {\n addUsageToTotals(totals, entry.message.usage);\n\n const latestPromptTokens =\n entry.message.usage.input + entry.message.usage.cacheRead + entry.message.usage.cacheWrite;\n latestCacheHitRate = latestPromptTokens > 0 ? (entry.message.usage.cacheRead / latestPromptTokens) * 100 : undefined;\n } else if (entry.type === \"branch_summary\" && entry.usage) {\n addUsageToTotals(totals, entry.usage);\n } else if (entry.type === \"message\" && entry.message.role === \"toolResult\" && \"usage\" in entry.message && entry.message.usage) {\n addUsageToTotals(totals, entry.message.usage);\n }\n }\n\n // Calculate context usage from session (handles compaction correctly).\n // After compaction, tokens are unknown until the next LLM response.\n const contextUsage = session.getContextUsage();\n const contextWindow =\n contextUsage?.contextWindow ?? state.model?.contextWindow ?? 0;\n const contextPercentValue = contextUsage?.percent ?? 0;\n const contextPercent =\n contextUsage?.percent !== null ? contextPercentValue.toFixed(1) : \"?\";\n\n const usageParts = [];\n if (totals.input)\n usageParts.push(\n `${theme.fg(\"dim\", \"↑\")}${theme.fg(\"muted\", formatTokens(totals.input))}`,\n );\n if (totals.output)\n usageParts.push(\n `${theme.fg(\"dim\", \"↓\")}${theme.fg(\"muted\", formatTokens(totals.output))}`,\n );\n if (totals.cacheRead)\n usageParts.push(\n `${theme.fg(\"dim\", \"R\")}${theme.fg(\"muted\", formatTokens(totals.cacheRead))}`,\n );\n if (totals.cacheWrite)\n usageParts.push(\n `${theme.fg(\"dim\", \"W\")}${theme.fg(\"muted\", formatTokens(totals.cacheWrite))}`,\n );\n if ((totals.cacheRead > 0 || totals.cacheWrite > 0) && latestCacheHitRate !== undefined) {\n usageParts.push(`${theme.fg(\"dim\", \"CH\")}${theme.fg(\"muted\", `${latestCacheHitRate.toFixed(1)}%`)}`);\n }\n\n // Kimi Coding is subscription-backed despite using API-key authentication.\n const usingSubscription = state.model\n ? state.model.provider === \"kimi-coding\" || session.modelRegistry.isUsingOAuth(state.model)\n : false;\n if (totals.cost || usingSubscription) {\n usageParts.push(\n `${theme.fg(\"muted\", `$${totals.cost.toFixed(3)}`)}${usingSubscription ? ` ${theme.fg(\"dim\", \"(sub)\")}` : \"\"}`,\n );\n }\n\n const autoIndicator = autoCompactEnabled ? \" (auto)\" : \"\";\n const contextPercentDisplay =\n contextPercent === \"?\"\n ? `?/${formatTokens(contextWindow)}${autoIndicator}`\n : `${contextPercent}%/${formatTokens(contextWindow)}${autoIndicator}`;\n if (autoCompactEnabled && contextPercentValue > 70) {\n usageParts.push(theme.fg(\"warning\", contextPercentDisplay));\n } else if (contextPercentValue > 90) {\n usageParts.push(theme.fg(\"error\", contextPercentDisplay));\n } else if (contextPercentValue > 70) {\n usageParts.push(theme.fg(\"warning\", contextPercentDisplay));\n } else {\n usageParts.push(theme.fg(\"muted\", contextPercentDisplay));\n }\n\n const separator = theme.fg(\"dim\", \" • \");\n const usageText =\n usageParts.length > 0\n ? usageParts.join(separator)\n : theme.fg(\"muted\", contextPercentDisplay);\n return rightAlign(usageText, width);\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 * Right-aligned usage meter that sits above the composer, matching the approved\n * prototype's separate token/cost/context ribbon.\n */\nexport class UsageMeterComponent implements Component {\n private autoCompactEnabled = true;\n\n declare private session: AgentSession;\n\n constructor(session: AgentSession) {\n this.session = session;\n\t}\n\n setSession(session: AgentSession): void {\n this.session = session;\n }\n\n setAutoCompactEnabled(enabled: boolean): void {\n this.autoCompactEnabled = enabled;\n }\n\n invalidate(): void {\n // Render pulls live session data.\n }\n\n render(width: number): string[] {\n return [getUsageLine(this.session, this.autoCompactEnabled, width)];\n }\n}\n\n/**\n * Sparse statusline below the composer. It mirrors the preview: model + cwd\n * when idle, or one semantic dot with short recovery copy while work is live.\n */\nexport class FooterComponent implements Component {\n declare private session: AgentSession;\n declare private footerData: ReadonlyFooterDataProvider;\n\n constructor(\n session: AgentSession,\n footerData: ReadonlyFooterDataProvider,\n ) {\n this.session = session;\n this.footerData = footerData;\n\t}\n\n setSession(session: AgentSession): void {\n this.session = session;\n }\n\n setAutoCompactEnabled(_enabled: boolean): void {\n // Usage state lives in UsageMeterComponent. Kept for compatibility with existing call sites.\n }\n\n /**\n * No-op: git branch caching now handled by provider.\n * Kept for compatibility with existing call sites in interactive-mode.\n */\n invalidate(): void {\n // No-op: git branch is cached/invalidated by provider\n }\n\n /**\n * Clean up resources.\n * Git watcher cleanup now handled by provider.\n */\n dispose(): void {\n // Git watcher cleanup handled by provider\n }\n\n render(width: number): string[] {\n const state = this.session.state;\n let pwd = replaceHome(this.session.sessionManager.getCwd());\n const branch = this.footerData.getGitBranch();\n if (branch) pwd += ` (${branch})`;\n const sessionName = typeof this.session.sessionManager.getSessionName === \"function\"\n ? this.session.sessionManager.getSessionName()\n : undefined;\n if (sessionName) pwd += ` • ${sessionName}`;\n\n const modelName = state.model?.id || \"no-model\";\n const fastModeSettings = this.session.settingsManager.getCodexFastModeSettings();\n const fastModeEnabled = state.model\n ? shouldApplyCodexFastMode(\n state.model,\n fastModeSettings,\n this.session.orchestrationContext,\n )\n : false;\n let modelLabel = modelName;\n if (state.model?.reasoning) {\n const thinkingLevel = state.thinkingLevel || \"off\";\n modelLabel =\n thinkingLevel === \"off\" ? modelLabel : `${modelLabel} ${thinkingLevel}`;\n }\n modelLabel = formatCodexFastModeModelLabel(modelLabel, fastModeEnabled);\n if (this.footerData.getAvailableProviderCount() > 1 && state.model) {\n modelLabel = `(${state.model.provider}) ${modelLabel}`;\n }\n\n const liveState = this.session.isStreaming\n ? theme.fg(\"muted\", \"esc to interrupt\")\n : undefined;\n let statusText = liveState ??\n `${theme.fg(\"dim\", modelLabel)} ${theme.fg(\"dim\", \"•\")} ${theme.fg(\"muted\", pwd)}`;\n if (areExperimentalFeaturesEnabled()) statusText += ` ${theme.fg(\"warning\", \"xp\")}`;\n const lines = [truncateToWidth(statusText, width, theme.fg(\"dim\", \"...\"))];\n const statuses = [...this.footerData.getExtensionStatuses()].sort(([a], [b]) => a.localeCompare(b));\n if (statuses.length > 0) {\n lines.push(truncateToWidth(statuses.map(([, text]) => sanitizeStatusText(text)).join(\" \"), width, theme.fg(\"dim\", \"...\")));\n }\n return lines;\n }\n}\n"]}
@@ -9,6 +9,8 @@ export interface HostInputFormDelegate {
9
9
  /** Host-owned form: all key handling and mutable editing state stay in the terminal process. */
10
10
  export declare class HostInputFormComponent implements Component, Focusable {
11
11
  private readonly title;
12
+ private readonly heading;
13
+ private readonly submitLabel;
12
14
  private readonly fields;
13
15
  private readonly values;
14
16
  private readonly editors;
@@ -1 +1 @@
1
- {"version":3,"file":"host-input-form.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/host-input-form.ts"],"names":[],"mappings":"AAAA,OAAO,EAQN,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,GAAG,EACR,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAEX,oBAAoB,EACpB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAM/C,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAC/C,QAAQ,IAAI,IAAI,CAAC;CACjB;AAQD,gGAAgG;AAChG,qBAAa,sBAAuB,YAAW,SAAS,EAAE,SAAS;IAClE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAW;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;IACtD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IACjD,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,QAAQ,CAAQ;IAExB,YACC,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,kBAAkB,EAC/B,OAAO,EAAE,oBAAoB,EAC7B,QAAQ,EAAE,qBAAqB,EA+B/B;IAED,IAAI,OAAO,IAAI,OAAO,CAA0B;IAChD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAA8C;IAExE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAkB9B;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAqC9B;IAED,UAAU,IAAI,IAAI,CAA6D;IAE/E,OAAO,CAAC,WAAW;IAenB,OAAO,CAAC,cAAc;IAmCtB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,MAAM;IAUd,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,YAAY;IACpB,4GAA4G;IAC5G,OAAO,CAAC,QAAQ;IAehB,qGAAqG;IACrG,OAAO,CAAC,SAAS;IASjB,6DAA6D;IAC7D,OAAO,CAAC,SAAS;IAOjB;;;;;OAKG;IACH,OAAO,CAAC,KAAK;CAYb"}
1
+ {"version":3,"file":"host-input-form.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/host-input-form.ts"],"names":[],"mappings":"AAAA,OAAO,EAQN,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,GAAG,EACR,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAEX,oBAAoB,EACpB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAM/C,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAC/C,QAAQ,IAAI,IAAI,CAAC;CACjB;AAQD,gGAAgG;AAChG,qBAAa,sBAAuB,YAAW,SAAS,EAAE,SAAS;IAClE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAW;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;IACtD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IACjD,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,QAAQ,CAAQ;IAExB,YACC,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,kBAAkB,EAC/B,OAAO,EAAE,oBAAoB,EAC7B,QAAQ,EAAE,qBAAqB,EAiC/B;IAED,IAAI,OAAO,IAAI,OAAO,CAA0B;IAChD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAA8C;IAExE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAkB9B;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAqC9B;IAED,UAAU,IAAI,IAAI,CAA6D;IAE/E,OAAO,CAAC,WAAW;IAenB,OAAO,CAAC,cAAc;IAmCtB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,MAAM;IAUd,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,YAAY;IACpB,4GAA4G;IAC5G,OAAO,CAAC,QAAQ;IAehB,qGAAqG;IACrG,OAAO,CAAC,SAAS;IAUjB,6DAA6D;IAC7D,OAAO,CAAC,SAAS;IAOjB;;;;;OAKG;IACH,OAAO,CAAC,KAAK;CAYb"}
@@ -11,6 +11,8 @@ export class HostInputFormComponent {
11
11
  this.invalid = new Set();
12
12
  this._focused = true;
13
13
  this.title = request.title;
14
+ this.heading = request.heading ?? "";
15
+ this.submitLabel = request.submitLabel ?? "[ Submit ]";
14
16
  this.tui = tui;
15
17
  this.theme = theme;
16
18
  this.keybindings = keybindings;
@@ -242,11 +244,12 @@ export class HostInputFormComponent {
242
244
  }
243
245
  /** Submit control rendered as a button pill; filled accent when focused, quiet outline otherwise. */
244
246
  submitRow() {
247
+ const label = this.submitLabel;
245
248
  const active = this.focusedIndex === this.fields.length;
246
249
  const marker = active ? this.theme.fg("accent", "▸") : " ";
247
250
  const pill = active
248
- ? this.theme.bg("selectedBg", this.theme.bold(this.theme.fg("accent", "[ Run workflow ]")))
249
- : this.theme.fg("dim", "[ Run workflow ]");
251
+ ? this.theme.bg("selectedBg", this.theme.bold(this.theme.fg("accent", label)))
252
+ : this.theme.fg("dim", label);
250
253
  return `${marker} ${pill}`;
251
254
  }
252
255
  /** Key-hint footer with accent key chips and muted verbs. */
@@ -264,7 +267,7 @@ export class HostInputFormComponent {
264
267
  */
265
268
  frame(body, inner, cw) {
266
269
  const border = (glyph) => this.theme.fg("border", glyph);
267
- const title = ` ${this.theme.fg("accent", this.theme.bold("WORKFLOW INPUTS"))} `;
270
+ const title = this.heading ? ` ${this.theme.fg("accent", this.theme.bold(this.heading))} ` : "";
268
271
  const top = `${border("╭")}${title}${border("─".repeat(Math.max(0, inner - visibleWidth(title))))}${border("╮")}`;
269
272
  const rows = body.map((line) => {
270
273
  const clipped = visibleWidth(line) > cw ? truncateToWidth(line, cw, "…") : line;