@astralyn/pi 0.85.1 → 0.85.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 (316) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/dist/bundle/chunks/anthropic-messages-IHRRITCV.js +6 -0
  3. package/dist/bundle/chunks/anthropic.js +75 -0
  4. package/dist/bundle/chunks/azure-openai-responses-QXBIDYXO.js +2 -0
  5. package/dist/bundle/chunks/bedrock-converse-stream.js +78 -0
  6. package/dist/bundle/chunks/chunk-37ATLPRE.js +2 -0
  7. package/dist/bundle/chunks/chunk-4L3WN2XY.js +2 -0
  8. package/dist/bundle/chunks/chunk-5B3S5DVL.js +4 -0
  9. package/dist/bundle/chunks/chunk-5FDOJRDS.js +2 -0
  10. package/dist/bundle/chunks/chunk-6CYCI3EJ.js +12 -0
  11. package/dist/bundle/chunks/chunk-7LO5Z4WE.js +2 -0
  12. package/dist/bundle/chunks/chunk-APKJ4JGA.js +2 -0
  13. package/dist/bundle/chunks/chunk-EDBLK2JQ.js +2 -0
  14. package/dist/bundle/chunks/chunk-FEZ5RM2B.js +2 -0
  15. package/dist/bundle/chunks/chunk-JEIV47WR.js +2 -0
  16. package/dist/bundle/chunks/chunk-JSJPY26N.js +2 -0
  17. package/dist/bundle/chunks/chunk-KI6LC764.js +42 -0
  18. package/dist/bundle/chunks/chunk-LB4P77SH.js +1688 -0
  19. package/dist/bundle/chunks/chunk-NUHFSC37.js +25 -0
  20. package/dist/bundle/chunks/chunk-O36ZMA3U.js +2 -0
  21. package/dist/bundle/chunks/chunk-OWESLY5T.js +11 -0
  22. package/dist/bundle/chunks/chunk-RRBI7OUG.js +50 -0
  23. package/dist/bundle/chunks/chunk-S2DJQQI2.js +2 -0
  24. package/dist/bundle/chunks/chunk-UP6RLTHQ.js +2 -0
  25. package/dist/bundle/chunks/chunk-UUSTLCVC.js +2 -0
  26. package/dist/bundle/chunks/chunk-WWBSZG5V.js +2 -0
  27. package/dist/bundle/chunks/chunk-YZJWMPUI.js +2 -0
  28. package/dist/bundle/chunks/github-copilot.js +2 -0
  29. package/dist/bundle/chunks/google-generative-ai-NBOR3IQR.js +2 -0
  30. package/dist/bundle/chunks/google-vertex-VTHX3SUB.js +2 -0
  31. package/dist/bundle/chunks/https-proxy-agent-2VXB7436.js +13 -0
  32. package/dist/bundle/chunks/image-resize-worker.js +2 -0
  33. package/dist/bundle/chunks/kimi-coding.js +2 -0
  34. package/dist/bundle/chunks/mistral-conversations-NO4ANAA5.js +5 -0
  35. package/dist/bundle/chunks/multipart-parser-SQ6GDJL7.js +3 -0
  36. package/dist/bundle/chunks/node-7L5OTM6S.js +2 -0
  37. package/dist/bundle/chunks/node-G4XOIDPH.js +16 -0
  38. package/dist/bundle/chunks/openai-codex-responses-5S3T3HMA.js +10 -0
  39. package/dist/bundle/chunks/openai-codex.js +75 -0
  40. package/dist/bundle/chunks/openai-completions-CXRRTRWE.js +7 -0
  41. package/dist/bundle/chunks/openai-responses-CV3MH6VP.js +2 -0
  42. package/dist/bundle/chunks/openrouter-images-6XDE2CEW.js +2 -0
  43. package/dist/bundle/chunks/openrouter.js +75 -0
  44. package/dist/bundle/chunks/pi-messages-PE6B42TG.js +8 -0
  45. package/dist/bundle/chunks/radius.js +75 -0
  46. package/dist/bundle/chunks/src-UK77SYZE.js +4 -0
  47. package/dist/bundle/chunks/xai.js +2 -0
  48. package/dist/bundle/cli.js +3 -0
  49. package/dist/bundle/index.js +2 -0
  50. package/dist/bundle/rpc-entry.js +3 -0
  51. package/dist/cli.js +5 -2469
  52. package/dist/core/agent-session.d.ts.map +1 -1
  53. package/dist/core/agent-session.js +2 -6
  54. package/dist/core/agent-session.js.map +1 -1
  55. package/dist/core/background/history.d.ts.map +1 -1
  56. package/dist/core/background/history.js +6 -0
  57. package/dist/core/background/history.js.map +1 -1
  58. package/dist/core/background/presentation.d.ts.map +1 -1
  59. package/dist/core/background/presentation.js +41 -4
  60. package/dist/core/background/presentation.js.map +1 -1
  61. package/dist/core/background/service.d.ts +2 -2
  62. package/dist/core/background/service.d.ts.map +1 -1
  63. package/dist/core/background/service.js +38 -15
  64. package/dist/core/background/service.js.map +1 -1
  65. package/dist/core/background/types.d.ts +9 -0
  66. package/dist/core/background/types.d.ts.map +1 -1
  67. package/dist/core/background/types.js +4 -0
  68. package/dist/core/background/types.js.map +1 -1
  69. package/dist/core/compaction/compaction.d.ts +5 -12
  70. package/dist/core/compaction/compaction.d.ts.map +1 -1
  71. package/dist/core/compaction/compaction.js +11 -19
  72. package/dist/core/compaction/compaction.js.map +1 -1
  73. package/dist/core/compaction/settings.d.ts +27 -0
  74. package/dist/core/compaction/settings.d.ts.map +1 -0
  75. package/dist/core/compaction/settings.js +40 -0
  76. package/dist/core/compaction/settings.js.map +1 -0
  77. package/dist/core/extensions/index.d.ts +1 -1
  78. package/dist/core/extensions/index.d.ts.map +1 -1
  79. package/dist/core/extensions/index.js.map +1 -1
  80. package/dist/core/extensions/runner.d.ts +0 -1
  81. package/dist/core/extensions/runner.d.ts.map +1 -1
  82. package/dist/core/extensions/runner.js +0 -6
  83. package/dist/core/extensions/runner.js.map +1 -1
  84. package/dist/core/extensions/types.d.ts +0 -11
  85. package/dist/core/extensions/types.d.ts.map +1 -1
  86. package/dist/core/extensions/types.js.map +1 -1
  87. package/dist/core/keybindings.d.ts +15 -0
  88. package/dist/core/keybindings.d.ts.map +1 -1
  89. package/dist/core/keybindings.js +12 -0
  90. package/dist/core/keybindings.js.map +1 -1
  91. package/dist/core/model-config.d.ts +32 -10
  92. package/dist/core/model-config.d.ts.map +1 -1
  93. package/dist/core/model-config.js +38 -1
  94. package/dist/core/model-config.js.map +1 -1
  95. package/dist/core/model-runtime.d.ts +2 -0
  96. package/dist/core/model-runtime.d.ts.map +1 -1
  97. package/dist/core/model-runtime.js +4 -0
  98. package/dist/core/model-runtime.js.map +1 -1
  99. package/dist/core/settings-manager.d.ts +4 -7
  100. package/dist/core/settings-manager.d.ts.map +1 -1
  101. package/dist/core/settings-manager.js +7 -6
  102. package/dist/core/settings-manager.js.map +1 -1
  103. package/dist/core/tools/bash.d.ts +3 -9
  104. package/dist/core/tools/bash.d.ts.map +1 -1
  105. package/dist/core/tools/bash.js +3 -8
  106. package/dist/core/tools/bash.js.map +1 -1
  107. package/dist/core/tools/shell-execution.d.ts.map +1 -1
  108. package/dist/core/tools/shell-execution.js +3 -1
  109. package/dist/core/tools/shell-execution.js.map +1 -1
  110. package/dist/extensions/background/manager.d.ts +8 -5
  111. package/dist/extensions/background/manager.d.ts.map +1 -1
  112. package/dist/extensions/background/manager.js +115 -39
  113. package/dist/extensions/background/manager.js.map +1 -1
  114. package/dist/extensions/background/task-view.d.ts +5 -0
  115. package/dist/extensions/background/task-view.d.ts.map +1 -1
  116. package/dist/extensions/background/task-view.js +4 -0
  117. package/dist/extensions/background/task-view.js.map +1 -1
  118. package/dist/extensions/btw/controller.d.ts +1 -1
  119. package/dist/extensions/btw/controller.d.ts.map +1 -1
  120. package/dist/extensions/btw/controller.js +4 -4
  121. package/dist/extensions/btw/controller.js.map +1 -1
  122. package/dist/extensions/btw/index.js +3 -3
  123. package/dist/extensions/btw/index.js.map +1 -1
  124. package/dist/extensions/index.js +2 -2
  125. package/dist/extensions/index.js.map +1 -1
  126. package/dist/extensions/provider/catalog.d.ts +57 -0
  127. package/dist/extensions/provider/catalog.d.ts.map +1 -0
  128. package/dist/extensions/provider/catalog.js +181 -0
  129. package/dist/extensions/provider/catalog.js.map +1 -0
  130. package/dist/extensions/provider/compat-fields.d.ts +25 -0
  131. package/dist/extensions/provider/compat-fields.d.ts.map +1 -0
  132. package/dist/extensions/provider/compat-fields.js +148 -0
  133. package/dist/extensions/provider/compat-fields.js.map +1 -0
  134. package/dist/extensions/provider/configuration.d.ts +8 -0
  135. package/dist/extensions/provider/configuration.d.ts.map +1 -0
  136. package/dist/extensions/provider/configuration.js +21 -0
  137. package/dist/extensions/provider/configuration.js.map +1 -0
  138. package/dist/extensions/provider/connection.d.ts +14 -0
  139. package/dist/extensions/provider/connection.d.ts.map +1 -0
  140. package/dist/extensions/provider/connection.js +86 -0
  141. package/dist/extensions/provider/connection.js.map +1 -0
  142. package/dist/extensions/provider/constants.d.ts +38 -0
  143. package/dist/extensions/provider/constants.d.ts.map +1 -0
  144. package/dist/extensions/provider/constants.js +75 -0
  145. package/dist/extensions/provider/constants.js.map +1 -0
  146. package/dist/extensions/provider/index.d.ts +4 -0
  147. package/dist/extensions/provider/index.d.ts.map +1 -0
  148. package/dist/extensions/provider/index.js +65 -0
  149. package/dist/extensions/provider/index.js.map +1 -0
  150. package/dist/extensions/provider/probe.d.ts +34 -0
  151. package/dist/extensions/provider/probe.d.ts.map +1 -0
  152. package/dist/extensions/provider/probe.js +178 -0
  153. package/dist/extensions/provider/probe.js.map +1 -0
  154. package/dist/extensions/provider/refresh.d.ts +30 -0
  155. package/dist/extensions/provider/refresh.d.ts.map +1 -0
  156. package/dist/extensions/provider/refresh.js +66 -0
  157. package/dist/extensions/provider/refresh.js.map +1 -0
  158. package/dist/extensions/provider/store.d.ts +131 -0
  159. package/dist/extensions/provider/store.d.ts.map +1 -0
  160. package/dist/extensions/provider/store.js +503 -0
  161. package/dist/extensions/provider/store.js.map +1 -0
  162. package/dist/extensions/provider/ui/app.d.ts +25 -0
  163. package/dist/extensions/provider/ui/app.d.ts.map +1 -0
  164. package/dist/extensions/provider/ui/app.js +153 -0
  165. package/dist/extensions/provider/ui/app.js.map +1 -0
  166. package/dist/extensions/provider/ui/builtin-data.d.ts +53 -0
  167. package/dist/extensions/provider/ui/builtin-data.d.ts.map +1 -0
  168. package/dist/extensions/provider/ui/builtin-data.js +315 -0
  169. package/dist/extensions/provider/ui/builtin-data.js.map +1 -0
  170. package/dist/extensions/provider/ui/compat.d.ts +57 -0
  171. package/dist/extensions/provider/ui/compat.d.ts.map +1 -0
  172. package/dist/extensions/provider/ui/compat.js +427 -0
  173. package/dist/extensions/provider/ui/compat.js.map +1 -0
  174. package/dist/extensions/provider/ui/dialogs.d.ts +30 -0
  175. package/dist/extensions/provider/ui/dialogs.d.ts.map +1 -0
  176. package/dist/extensions/provider/ui/dialogs.js +89 -0
  177. package/dist/extensions/provider/ui/dialogs.js.map +1 -0
  178. package/dist/extensions/provider/ui/dictionary.d.ts +29 -0
  179. package/dist/extensions/provider/ui/dictionary.d.ts.map +1 -0
  180. package/dist/extensions/provider/ui/dictionary.js +385 -0
  181. package/dist/extensions/provider/ui/dictionary.js.map +1 -0
  182. package/dist/extensions/provider/ui/editor.d.ts +91 -0
  183. package/dist/extensions/provider/ui/editor.d.ts.map +1 -0
  184. package/dist/extensions/provider/ui/editor.js +667 -0
  185. package/dist/extensions/provider/ui/editor.js.map +1 -0
  186. package/dist/extensions/provider/ui/fetch-models.d.ts +39 -0
  187. package/dist/extensions/provider/ui/fetch-models.d.ts.map +1 -0
  188. package/dist/extensions/provider/ui/fetch-models.js +320 -0
  189. package/dist/extensions/provider/ui/fetch-models.js.map +1 -0
  190. package/dist/extensions/provider/ui/model-fields.d.ts +43 -0
  191. package/dist/extensions/provider/ui/model-fields.d.ts.map +1 -0
  192. package/dist/extensions/provider/ui/model-fields.js +441 -0
  193. package/dist/extensions/provider/ui/model-fields.js.map +1 -0
  194. package/dist/extensions/provider/ui/model-options.d.ts +93 -0
  195. package/dist/extensions/provider/ui/model-options.d.ts.map +1 -0
  196. package/dist/extensions/provider/ui/model-options.js +529 -0
  197. package/dist/extensions/provider/ui/model-options.js.map +1 -0
  198. package/dist/extensions/provider/ui/pane.d.ts +81 -0
  199. package/dist/extensions/provider/ui/pane.d.ts.map +1 -0
  200. package/dist/extensions/provider/ui/pane.js +3 -0
  201. package/dist/extensions/provider/ui/pane.js.map +1 -0
  202. package/dist/extensions/provider/ui/provider-fields.d.ts +60 -0
  203. package/dist/extensions/provider/ui/provider-fields.d.ts.map +1 -0
  204. package/dist/extensions/provider/ui/provider-fields.js +326 -0
  205. package/dist/extensions/provider/ui/provider-fields.js.map +1 -0
  206. package/dist/extensions/provider/ui/provider-list.d.ts +34 -0
  207. package/dist/extensions/provider/ui/provider-list.d.ts.map +1 -0
  208. package/dist/extensions/provider/ui/provider-list.js +162 -0
  209. package/dist/extensions/provider/ui/provider-list.js.map +1 -0
  210. package/dist/extensions/provider/ui/session.d.ts +20 -0
  211. package/dist/extensions/provider/ui/session.d.ts.map +1 -0
  212. package/dist/extensions/provider/ui/session.js +52 -0
  213. package/dist/extensions/provider/ui/session.js.map +1 -0
  214. package/dist/extensions/provider/ui/thinking-map.d.ts +20 -0
  215. package/dist/extensions/provider/ui/thinking-map.d.ts.map +1 -0
  216. package/dist/extensions/provider/ui/thinking-map.js +166 -0
  217. package/dist/extensions/provider/ui/thinking-map.js.map +1 -0
  218. package/dist/extensions/provider/ui/value-row.d.ts +88 -0
  219. package/dist/extensions/provider/ui/value-row.d.ts.map +1 -0
  220. package/dist/extensions/provider/ui/value-row.js +158 -0
  221. package/dist/extensions/provider/ui/value-row.js.map +1 -0
  222. package/dist/extensions/statusline/index.js +2 -2
  223. package/dist/extensions/statusline/index.js.map +1 -1
  224. package/dist/extensions/subagent/index.d.ts.map +1 -1
  225. package/dist/extensions/subagent/index.js +4 -2
  226. package/dist/extensions/subagent/index.js.map +1 -1
  227. package/dist/extensions/subagent/resolve.d.ts +5 -0
  228. package/dist/extensions/subagent/resolve.d.ts.map +1 -1
  229. package/dist/extensions/subagent/resolve.js +15 -7
  230. package/dist/extensions/subagent/resolve.js.map +1 -1
  231. package/dist/extensions/subagent/schema.d.ts +2 -0
  232. package/dist/extensions/subagent/schema.d.ts.map +1 -1
  233. package/dist/extensions/subagent/schema.js +1 -0
  234. package/dist/extensions/subagent/schema.js.map +1 -1
  235. package/dist/index.d.ts +1 -1
  236. package/dist/index.d.ts.map +1 -1
  237. package/dist/index.js.map +1 -1
  238. package/dist/modes/interactive/components/tool-execution.d.ts +10 -0
  239. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  240. package/dist/modes/interactive/components/tool-execution.js +20 -2
  241. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  242. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  243. package/dist/modes/interactive/interactive-mode.js +6 -1
  244. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  245. package/dist/rpc-entry.js +10 -2469
  246. package/docs/bundled/README.md +1 -1
  247. package/docs/bundled/extensions/background.md +5 -5
  248. package/docs/bundled/extensions/provider.md +117 -0
  249. package/docs/bundled/extensions/statusline.md +1 -1
  250. package/docs/bundled/extensions/subagent.md +7 -3
  251. package/docs/compaction.md +16 -6
  252. package/docs/development.md +1 -1
  253. package/docs/docs.json +2 -2
  254. package/docs/extensions.md +0 -13
  255. package/docs/keybindings.md +3 -0
  256. package/docs/settings.md +11 -7
  257. package/npm-shrinkwrap.json +4 -4
  258. package/package.json +6 -5
  259. package/dist/extensions/router/constants.d.ts +0 -23
  260. package/dist/extensions/router/constants.d.ts.map +0 -1
  261. package/dist/extensions/router/constants.js +0 -30
  262. package/dist/extensions/router/constants.js.map +0 -1
  263. package/dist/extensions/router/dialog-host.d.ts +0 -60
  264. package/dist/extensions/router/dialog-host.d.ts.map +0 -1
  265. package/dist/extensions/router/dialog-host.js +0 -196
  266. package/dist/extensions/router/dialog-host.js.map +0 -1
  267. package/dist/extensions/router/dialog.d.ts +0 -45
  268. package/dist/extensions/router/dialog.d.ts.map +0 -1
  269. package/dist/extensions/router/dialog.js +0 -378
  270. package/dist/extensions/router/dialog.js.map +0 -1
  271. package/dist/extensions/router/identity.d.ts +0 -15
  272. package/dist/extensions/router/identity.d.ts.map +0 -1
  273. package/dist/extensions/router/identity.js +0 -173
  274. package/dist/extensions/router/identity.js.map +0 -1
  275. package/dist/extensions/router/index.d.ts +0 -15
  276. package/dist/extensions/router/index.d.ts.map +0 -1
  277. package/dist/extensions/router/index.js +0 -70
  278. package/dist/extensions/router/index.js.map +0 -1
  279. package/dist/extensions/router/presets.d.ts +0 -51
  280. package/dist/extensions/router/presets.d.ts.map +0 -1
  281. package/dist/extensions/router/presets.js +0 -108
  282. package/dist/extensions/router/presets.js.map +0 -1
  283. package/dist/extensions/router/probe.d.ts +0 -26
  284. package/dist/extensions/router/probe.d.ts.map +0 -1
  285. package/dist/extensions/router/probe.js +0 -216
  286. package/dist/extensions/router/probe.js.map +0 -1
  287. package/dist/extensions/router/register.d.ts +0 -12
  288. package/dist/extensions/router/register.d.ts.map +0 -1
  289. package/dist/extensions/router/register.js +0 -90
  290. package/dist/extensions/router/register.js.map +0 -1
  291. package/dist/extensions/router/state.d.ts +0 -20
  292. package/dist/extensions/router/state.d.ts.map +0 -1
  293. package/dist/extensions/router/state.js +0 -169
  294. package/dist/extensions/router/state.js.map +0 -1
  295. package/dist/extensions/router/store.d.ts +0 -12
  296. package/dist/extensions/router/store.d.ts.map +0 -1
  297. package/dist/extensions/router/store.js +0 -266
  298. package/dist/extensions/router/store.js.map +0 -1
  299. package/dist/extensions/router/stream.d.ts +0 -12
  300. package/dist/extensions/router/stream.d.ts.map +0 -1
  301. package/dist/extensions/router/stream.js +0 -233
  302. package/dist/extensions/router/stream.js.map +0 -1
  303. package/dist/extensions/router/transport.d.ts +0 -9
  304. package/dist/extensions/router/transport.d.ts.map +0 -1
  305. package/dist/extensions/router/transport.js +0 -81
  306. package/dist/extensions/router/transport.js.map +0 -1
  307. package/dist/extensions/router/types.d.ts +0 -39
  308. package/dist/extensions/router/types.d.ts.map +0 -1
  309. package/dist/extensions/router/types.js +0 -2
  310. package/dist/extensions/router/types.js.map +0 -1
  311. package/dist/extensions/router/ui.d.ts +0 -26
  312. package/dist/extensions/router/ui.d.ts.map +0 -1
  313. package/dist/extensions/router/ui.js +0 -897
  314. package/dist/extensions/router/ui.js.map +0 -1
  315. package/dist/image-resize-worker.js +0 -2
  316. package/docs/bundled/extensions/router.md +0 -197
@@ -0,0 +1,162 @@
1
+ /** Searchable provider list and new-provider id entry. */
2
+ import { fuzzyFilter, truncateToWidth } from "@earendil-works/pi-tui";
3
+ import { DynamicBorder } from "../../../modes/interactive/components/dynamic-border.js";
4
+ import { keyHint, rawKeyHint } from "../../../modes/interactive/components/keybinding-hints.js";
5
+ import { plural } from "../constants.js";
6
+ import { renderInfoLine, renderKeyValueLine, renderPlainLine, ValueEditor, windowLines } from "./value-row.js";
7
+ /** Fixed list-area height: the screen frame matches the provider editor's. */
8
+ const LIST_ROWS = 12;
9
+ export class ProviderListScreen {
10
+ constructor(tui, theme, keybindings, done, store) {
11
+ this.mode = "list";
12
+ this.query = "";
13
+ this.index = 0;
14
+ this.active = false;
15
+ this.tui = tui;
16
+ this.theme = theme;
17
+ this.keybindings = keybindings;
18
+ this.done = done;
19
+ this.store = store;
20
+ this.input = new ValueEditor({ onCommit: () => this.confirm(), onCancel: () => this.cancel() });
21
+ }
22
+ get focused() {
23
+ return this.active;
24
+ }
25
+ set focused(value) {
26
+ this.active = value;
27
+ this.input.focused = value;
28
+ }
29
+ invalidate() { }
30
+ filtered() {
31
+ const ids = this.store.getProviderIds();
32
+ return this.query.trim() ? fuzzyFilter(ids, this.query, (id) => id) : ids;
33
+ }
34
+ render(width) {
35
+ const theme = this.theme;
36
+ const border = new DynamicBorder((text) => theme.fg("border", text)).render(width)[0] ?? "";
37
+ const lines = [
38
+ border,
39
+ truncateToWidth(theme.fg("accent", theme.bold(" /provider — models.json providers")), width),
40
+ border,
41
+ renderKeyValueLine(theme, {
42
+ keyLabel: this.mode === "list" ? "Search" : "Provider id",
43
+ active: false,
44
+ paneFocused: this.active,
45
+ editing: this.input,
46
+ width,
47
+ }),
48
+ "",
49
+ ];
50
+ // The list area is a fixed window: overlong lists scroll with a (n/N)
51
+ // indicator (the /model selector convention) instead of resizing.
52
+ const area = [];
53
+ if (this.mode === "list") {
54
+ const entries = this.filtered();
55
+ const total = entries.length + 1;
56
+ this.index = Math.min(this.index, total - 1);
57
+ const rows = [];
58
+ for (let row = 0; row < total; row++) {
59
+ const id = entries[row - 1];
60
+ const provider = id === undefined ? undefined : this.store.getProvider(id);
61
+ const note = id === undefined
62
+ ? undefined
63
+ : provider
64
+ ? [
65
+ `${String(provider.models?.length ?? 0)} ${plural(provider.models?.length ?? 0, "model")}`,
66
+ provider.api,
67
+ ]
68
+ .filter(Boolean)
69
+ .join(" · ")
70
+ : "pending deletion";
71
+ rows.push(renderPlainLine(theme, row === 0 ? "+ Add Provider" : id, {
72
+ active: row === this.index,
73
+ paneFocused: this.active,
74
+ note,
75
+ width,
76
+ }));
77
+ }
78
+ if (entries.length === 0)
79
+ rows.push(renderInfoLine(theme, this.query ? "No matching providers." : "No providers yet.", width));
80
+ area.push(...windowLines(theme, rows, LIST_ROWS, { cursor: this.index }));
81
+ }
82
+ else if (this.error) {
83
+ area.push(truncateToWidth(theme.fg("error", this.error), width));
84
+ }
85
+ while (area.length < LIST_ROWS)
86
+ area.push("");
87
+ const hints = this.mode === "newProvider"
88
+ ? [keyHint("tui.input.submit", "create"), keyHint("tui.select.cancel", "cancel")]
89
+ : [
90
+ rawKeyHint("type", "filter"),
91
+ rawKeyHint("↑↓", "move"),
92
+ keyHint("tui.select.confirm", "open"),
93
+ keyHint("tui.select.cancel", "close"),
94
+ ];
95
+ return [...lines, ...area, border, truncateToWidth(hints.join(" "), width), border];
96
+ }
97
+ handleInput(data) {
98
+ const kb = this.keybindings;
99
+ if (kb.matches(data, "tui.select.cancel")) {
100
+ this.cancel();
101
+ return;
102
+ }
103
+ if (this.mode === "list") {
104
+ const total = this.filtered().length + 1;
105
+ if (kb.matches(data, "tui.select.up"))
106
+ this.index = (this.index + total - 1) % total;
107
+ else if (kb.matches(data, "tui.select.down"))
108
+ this.index = (this.index + 1) % total;
109
+ else if (kb.matches(data, "tui.select.confirm")) {
110
+ this.confirm();
111
+ return;
112
+ }
113
+ else {
114
+ const previous = this.query;
115
+ this.input.handleInput(data);
116
+ this.query = this.input.value;
117
+ if (this.query !== previous)
118
+ this.index = this.query && this.filtered().length > 0 ? 1 : 0;
119
+ }
120
+ }
121
+ else
122
+ this.input.handleInput(data);
123
+ this.tui.requestRender();
124
+ }
125
+ confirm() {
126
+ if (this.mode === "newProvider") {
127
+ const id = this.input.value.trim();
128
+ if (!id)
129
+ this.error = "Provider id must be non-empty.";
130
+ else if (this.store.getProviderIds().includes(id))
131
+ this.error = "This provider id already exists.";
132
+ else {
133
+ this.store.ensureProviderView(id);
134
+ this.done({ kind: "open", providerId: id });
135
+ return;
136
+ }
137
+ }
138
+ else if (this.index === 0) {
139
+ this.mode = "newProvider";
140
+ this.error = undefined;
141
+ // A fruitless search becomes the new id — type once, create once.
142
+ this.input.reset(this.query);
143
+ }
144
+ else {
145
+ const id = this.filtered()[this.index - 1];
146
+ if (id)
147
+ this.done({ kind: "open", providerId: id });
148
+ }
149
+ this.tui.requestRender();
150
+ }
151
+ cancel() {
152
+ if (this.mode === "list") {
153
+ this.done({ kind: "close" });
154
+ return;
155
+ }
156
+ this.mode = "list";
157
+ this.error = undefined;
158
+ this.input.reset(this.query);
159
+ this.tui.requestRender();
160
+ }
161
+ }
162
+ //# sourceMappingURL=provider-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-list.js","sourceRoot":"","sources":["../../../../src/extensions/provider/ui/provider-list.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAE1D,OAAO,EAAkC,WAAW,EAAY,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEhH,OAAO,EAAE,aAAa,EAAE,MAAM,yDAAyD,CAAC;AACxF,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,2DAA2D,CAAC;AAEhG,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE/G,8EAA8E;AAC9E,MAAM,SAAS,GAAG,EAAE,CAAC;AAGrB,MAAM,OAAO,kBAAkB;IAa9B,YACC,GAAQ,EACR,KAAY,EACZ,WAA+B,EAC/B,IAA0C,EAC1C,KAAsB;QAXf,SAAI,GAA2B,MAAM,CAAC;QACtC,UAAK,GAAG,EAAE,CAAC;QACX,UAAK,GAAG,CAAC,CAAC;QAEV,WAAM,GAAG,KAAK,CAAC;QAStB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,KAAK,GAAG,IAAI,WAAW,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACjG,CAAC;IAED,IAAI,OAAO;QACV,OAAO,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;IACD,IAAI,OAAO,CAAC,KAAc;QACzB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC;IAC5B,CAAC;IACD,UAAU,KAAU,CAAC;IAEb,QAAQ;QACf,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAC3E,CAAC;IAED,MAAM,CAAC,KAAa;QACnB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACzB,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5F,MAAM,KAAK,GAAG;YACb,MAAM;YACN,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC,EAAE,KAAK,CAAC;YAC5F,MAAM;YACN,kBAAkB,CAAC,KAAK,EAAE;gBACzB,QAAQ,EAAE,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa;gBACzD,MAAM,EAAE,KAAK;gBACb,WAAW,EAAE,IAAI,CAAC,MAAM;gBACxB,OAAO,EAAE,IAAI,CAAC,KAAK;gBACnB,KAAK;aACL,CAAC;YACF,EAAE;SACF,CAAC;QACF,sEAAsE;QACtE,kEAAkE;QAClE,MAAM,IAAI,GAAa,EAAE,CAAC;QAC1B,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;YACjC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;YAC7C,MAAM,IAAI,GAAa,EAAE,CAAC;YAC1B,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC;gBACtC,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;gBAC5B,MAAM,QAAQ,GAAG,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;gBAC3E,MAAM,IAAI,GACT,EAAE,KAAK,SAAS;oBACf,CAAC,CAAC,SAAS;oBACX,CAAC,CAAC,QAAQ;wBACT,CAAC,CAAC;4BACA,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,EAAE,OAAO,CAAC,EAAE;4BAC1F,QAAQ,CAAC,GAAG;yBACZ;6BACC,MAAM,CAAC,OAAO,CAAC;6BACf,IAAI,CAAC,KAAK,CAAC;wBACd,CAAC,CAAC,kBAAkB,CAAC;gBACxB,IAAI,CAAC,IAAI,CACR,eAAe,CAAC,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAG,EAAE;oBAC1D,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC,KAAK;oBAC1B,WAAW,EAAE,IAAI,CAAC,MAAM;oBACxB,IAAI;oBACJ,KAAK;iBACL,CAAC,CACF,CAAC;YACH,CAAC;YACD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;gBACvB,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC,CAAC;YACtG,IAAI,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC3E,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACvB,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;QAClE,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,GAAG,SAAS;YAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC9C,MAAM,KAAK,GACV,IAAI,CAAC,IAAI,KAAK,aAAa;YAC1B,CAAC,CAAC,CAAC,OAAO,CAAC,kBAAkB,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAC;YACjF,CAAC,CAAC;gBACA,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC;gBAC5B,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC;gBACxB,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC;gBACrC,OAAO,CAAC,mBAAmB,EAAE,OAAO,CAAC;aACrC,CAAC;QACL,OAAO,CAAC,GAAG,KAAK,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;IACtF,CAAC;IAED,WAAW,CAAC,IAAY;QACvB,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC;QAC5B,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,mBAAmB,CAAC,EAAE,CAAC;YAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,OAAO;QACR,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;YACzC,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,eAAe,CAAC;gBAAE,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;iBAChF,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,iBAAiB,CAAC;gBAAE,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;iBAC/E,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,oBAAoB,CAAC,EAAE,CAAC;gBACjD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACf,OAAO;YACR,CAAC;iBAAM,CAAC;gBACP,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC;gBAC5B,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;gBAC7B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;gBAC9B,IAAI,IAAI,CAAC,KAAK,KAAK,QAAQ;oBAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5F,CAAC;QACF,CAAC;;YAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC1B,CAAC;IAEO,OAAO;QACd,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YACjC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACnC,IAAI,CAAC,EAAE;gBAAE,IAAI,CAAC,KAAK,GAAG,gCAAgC,CAAC;iBAClD,IAAI,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAAE,IAAI,CAAC,KAAK,GAAG,kCAAkC,CAAC;iBAC9F,CAAC;gBACL,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;gBAClC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC5C,OAAO;YACR,CAAC;QACF,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;YAC1B,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;YACvB,kEAAkE;YAClE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;aAAM,CAAC;YACP,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YAC3C,IAAI,EAAE;gBAAE,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;QACrD,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC1B,CAAC;IAEO,MAAM;QACb,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC1B,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YAC7B,OAAO;QACR,CAAC;QACD,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC;QACnB,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACvB,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC1B,CAAC;CACD","sourcesContent":["/** Searchable provider list and new-provider id entry. */\n\nimport { type Component, type Focusable, fuzzyFilter, type TUI, truncateToWidth } from \"@earendil-works/pi-tui\";\nimport type { KeybindingsManager } from \"../../../core/keybindings.ts\";\nimport { DynamicBorder } from \"../../../modes/interactive/components/dynamic-border.ts\";\nimport { keyHint, rawKeyHint } from \"../../../modes/interactive/components/keybinding-hints.ts\";\nimport type { Theme } from \"../../../modes/interactive/theme/theme.ts\";\nimport { plural } from \"../constants.ts\";\nimport type { ModelsJsonStore } from \"../store.ts\";\nimport { renderInfoLine, renderKeyValueLine, renderPlainLine, ValueEditor, windowLines } from \"./value-row.ts\";\n\n/** Fixed list-area height: the screen frame matches the provider editor's. */\nconst LIST_ROWS = 12;\nexport type ProviderListResult = { kind: \"open\"; providerId: string } | { kind: \"close\" };\n\nexport class ProviderListScreen implements Component, Focusable {\n\tprivate readonly input: ValueEditor;\n\tprivate readonly store: ModelsJsonStore;\n\tprivate readonly tui: TUI;\n\tprivate readonly theme: Theme;\n\tprivate readonly keybindings: KeybindingsManager;\n\tprivate readonly done: (result: ProviderListResult) => void;\n\tprivate mode: \"list\" | \"newProvider\" = \"list\";\n\tprivate query = \"\";\n\tprivate index = 0;\n\tprivate error: string | undefined;\n\tprivate active = false;\n\n\tconstructor(\n\t\ttui: TUI,\n\t\ttheme: Theme,\n\t\tkeybindings: KeybindingsManager,\n\t\tdone: (result: ProviderListResult) => void,\n\t\tstore: ModelsJsonStore,\n\t) {\n\t\tthis.tui = tui;\n\t\tthis.theme = theme;\n\t\tthis.keybindings = keybindings;\n\t\tthis.done = done;\n\t\tthis.store = store;\n\t\tthis.input = new ValueEditor({ onCommit: () => this.confirm(), onCancel: () => this.cancel() });\n\t}\n\n\tget focused(): boolean {\n\t\treturn this.active;\n\t}\n\tset focused(value: boolean) {\n\t\tthis.active = value;\n\t\tthis.input.focused = value;\n\t}\n\tinvalidate(): void {}\n\n\tprivate filtered(): string[] {\n\t\tconst ids = this.store.getProviderIds();\n\t\treturn this.query.trim() ? fuzzyFilter(ids, this.query, (id) => id) : ids;\n\t}\n\n\trender(width: number): string[] {\n\t\tconst theme = this.theme;\n\t\tconst border = new DynamicBorder((text) => theme.fg(\"border\", text)).render(width)[0] ?? \"\";\n\t\tconst lines = [\n\t\t\tborder,\n\t\t\ttruncateToWidth(theme.fg(\"accent\", theme.bold(\" /provider — models.json providers\")), width),\n\t\t\tborder,\n\t\t\trenderKeyValueLine(theme, {\n\t\t\t\tkeyLabel: this.mode === \"list\" ? \"Search\" : \"Provider id\",\n\t\t\t\tactive: false,\n\t\t\t\tpaneFocused: this.active,\n\t\t\t\tediting: this.input,\n\t\t\t\twidth,\n\t\t\t}),\n\t\t\t\"\",\n\t\t];\n\t\t// The list area is a fixed window: overlong lists scroll with a (n/N)\n\t\t// indicator (the /model selector convention) instead of resizing.\n\t\tconst area: string[] = [];\n\t\tif (this.mode === \"list\") {\n\t\t\tconst entries = this.filtered();\n\t\t\tconst total = entries.length + 1;\n\t\t\tthis.index = Math.min(this.index, total - 1);\n\t\t\tconst rows: string[] = [];\n\t\t\tfor (let row = 0; row < total; row++) {\n\t\t\t\tconst id = entries[row - 1];\n\t\t\t\tconst provider = id === undefined ? undefined : this.store.getProvider(id);\n\t\t\t\tconst note =\n\t\t\t\t\tid === undefined\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: provider\n\t\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\t\t`${String(provider.models?.length ?? 0)} ${plural(provider.models?.length ?? 0, \"model\")}`,\n\t\t\t\t\t\t\t\t\tprovider.api,\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t.filter(Boolean)\n\t\t\t\t\t\t\t\t\t.join(\" · \")\n\t\t\t\t\t\t\t: \"pending deletion\";\n\t\t\t\trows.push(\n\t\t\t\t\trenderPlainLine(theme, row === 0 ? \"+ Add Provider\" : id!, {\n\t\t\t\t\t\tactive: row === this.index,\n\t\t\t\t\t\tpaneFocused: this.active,\n\t\t\t\t\t\tnote,\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\tif (entries.length === 0)\n\t\t\t\trows.push(renderInfoLine(theme, this.query ? \"No matching providers.\" : \"No providers yet.\", width));\n\t\t\tarea.push(...windowLines(theme, rows, LIST_ROWS, { cursor: this.index }));\n\t\t} else if (this.error) {\n\t\t\tarea.push(truncateToWidth(theme.fg(\"error\", this.error), width));\n\t\t}\n\t\twhile (area.length < LIST_ROWS) area.push(\"\");\n\t\tconst hints =\n\t\t\tthis.mode === \"newProvider\"\n\t\t\t\t? [keyHint(\"tui.input.submit\", \"create\"), keyHint(\"tui.select.cancel\", \"cancel\")]\n\t\t\t\t: [\n\t\t\t\t\t\trawKeyHint(\"type\", \"filter\"),\n\t\t\t\t\t\trawKeyHint(\"↑↓\", \"move\"),\n\t\t\t\t\t\tkeyHint(\"tui.select.confirm\", \"open\"),\n\t\t\t\t\t\tkeyHint(\"tui.select.cancel\", \"close\"),\n\t\t\t\t\t];\n\t\treturn [...lines, ...area, border, truncateToWidth(hints.join(\" \"), width), border];\n\t}\n\n\thandleInput(data: string): void {\n\t\tconst kb = this.keybindings;\n\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis.cancel();\n\t\t\treturn;\n\t\t}\n\t\tif (this.mode === \"list\") {\n\t\t\tconst total = this.filtered().length + 1;\n\t\t\tif (kb.matches(data, \"tui.select.up\")) this.index = (this.index + total - 1) % total;\n\t\t\telse if (kb.matches(data, \"tui.select.down\")) this.index = (this.index + 1) % total;\n\t\t\telse if (kb.matches(data, \"tui.select.confirm\")) {\n\t\t\t\tthis.confirm();\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\tconst previous = this.query;\n\t\t\t\tthis.input.handleInput(data);\n\t\t\t\tthis.query = this.input.value;\n\t\t\t\tif (this.query !== previous) this.index = this.query && this.filtered().length > 0 ? 1 : 0;\n\t\t\t}\n\t\t} else this.input.handleInput(data);\n\t\tthis.tui.requestRender();\n\t}\n\n\tprivate confirm(): void {\n\t\tif (this.mode === \"newProvider\") {\n\t\t\tconst id = this.input.value.trim();\n\t\t\tif (!id) this.error = \"Provider id must be non-empty.\";\n\t\t\telse if (this.store.getProviderIds().includes(id)) this.error = \"This provider id already exists.\";\n\t\t\telse {\n\t\t\t\tthis.store.ensureProviderView(id);\n\t\t\t\tthis.done({ kind: \"open\", providerId: id });\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else if (this.index === 0) {\n\t\t\tthis.mode = \"newProvider\";\n\t\t\tthis.error = undefined;\n\t\t\t// A fruitless search becomes the new id — type once, create once.\n\t\t\tthis.input.reset(this.query);\n\t\t} else {\n\t\t\tconst id = this.filtered()[this.index - 1];\n\t\t\tif (id) this.done({ kind: \"open\", providerId: id });\n\t\t}\n\t\tthis.tui.requestRender();\n\t}\n\n\tprivate cancel(): void {\n\t\tif (this.mode === \"list\") {\n\t\t\tthis.done({ kind: \"close\" });\n\t\t\treturn;\n\t\t}\n\t\tthis.mode = \"list\";\n\t\tthis.error = undefined;\n\t\tthis.input.reset(this.query);\n\t\tthis.tui.requestRender();\n\t}\n}\n"]}
@@ -0,0 +1,20 @@
1
+ /** Persistent TUI root with synchronous page changes and one owned lifetime. */
2
+ import { type Component, Container, type Focusable, type TUI } from "@earendil-works/pi-tui";
3
+ export type ProviderComponent = Component & {
4
+ dispose?(): void;
5
+ };
6
+ export declare class ProviderTuiSession extends Container implements Focusable {
7
+ private readonly tui;
8
+ private readonly controller;
9
+ private screen;
10
+ private active;
11
+ constructor(tui: TUI);
12
+ get signal(): AbortSignal;
13
+ get focused(): boolean;
14
+ set focused(value: boolean);
15
+ setScreen(screen: ProviderComponent): void;
16
+ handleInput(data: string): void;
17
+ dispose(): void;
18
+ private disposeScreen;
19
+ }
20
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../../src/extensions/provider/ui/session.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAEhF,OAAO,EAAE,KAAK,SAAS,EAAE,SAAS,EAAE,KAAK,SAAS,EAAe,KAAK,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAE1G,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG;IAAE,OAAO,CAAC,IAAI,IAAI,CAAA;CAAE,CAAC;AAEjE,qBAAa,kBAAmB,SAAQ,SAAU,YAAW,SAAS;IACrE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;IAC1B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyB;IACpD,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,MAAM,CAAS;gBAEX,GAAG,EAAE,GAAG;IAKpB,IAAI,MAAM,IAAI,WAAW,CAExB;IACD,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAGzB;IAED,SAAS,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAa1C,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI/B,OAAO,IAAI,IAAI;IAOf,OAAO,CAAC,aAAa;CAMrB"}
@@ -0,0 +1,52 @@
1
+ /** Persistent TUI root with synchronous page changes and one owned lifetime. */
2
+ import { Container, isFocusable } from "@earendil-works/pi-tui";
3
+ export class ProviderTuiSession extends Container {
4
+ constructor(tui) {
5
+ super();
6
+ this.controller = new AbortController();
7
+ this.active = false;
8
+ this.tui = tui;
9
+ }
10
+ get signal() {
11
+ return this.controller.signal;
12
+ }
13
+ get focused() {
14
+ return this.active;
15
+ }
16
+ set focused(value) {
17
+ this.active = value;
18
+ if (this.screen && isFocusable(this.screen))
19
+ this.screen.focused = value;
20
+ }
21
+ setScreen(screen) {
22
+ if (this.signal.aborted) {
23
+ screen.dispose?.();
24
+ return;
25
+ }
26
+ this.disposeScreen();
27
+ this.screen = screen;
28
+ this.clear();
29
+ this.addChild(screen);
30
+ this.tui.setFocus(this);
31
+ this.tui.requestRender();
32
+ }
33
+ handleInput(data) {
34
+ if (!this.signal.aborted)
35
+ this.screen?.handleInput?.(data);
36
+ }
37
+ dispose() {
38
+ if (this.signal.aborted)
39
+ return;
40
+ this.controller.abort();
41
+ this.disposeScreen();
42
+ this.clear();
43
+ }
44
+ disposeScreen() {
45
+ const previous = this.screen;
46
+ this.screen = undefined;
47
+ if (previous && isFocusable(previous))
48
+ previous.focused = false;
49
+ previous?.dispose?.();
50
+ }
51
+ }
52
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../../src/extensions/provider/ui/session.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAEhF,OAAO,EAAkB,SAAS,EAAkB,WAAW,EAAY,MAAM,wBAAwB,CAAC;AAI1G,MAAM,OAAO,kBAAmB,SAAQ,SAAS;IAMhD,YAAY,GAAQ;QACnB,KAAK,EAAE,CAAC;QALQ,eAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QAE5C,WAAM,GAAG,KAAK,CAAC;QAItB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IAChB,CAAC;IAED,IAAI,MAAM;QACT,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;IAC/B,CAAC;IACD,IAAI,OAAO;QACV,OAAO,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;IACD,IAAI,OAAO,CAAC,KAAc;QACzB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,IAAI,CAAC,MAAM,IAAI,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC;YAAE,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;IAC1E,CAAC;IAED,SAAS,CAAC,MAAyB;QAClC,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACzB,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;YACnB,OAAO;QACR,CAAC;QACD,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACtB,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACxB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC1B,CAAC;IAED,WAAW,CAAC,IAAY;QACvB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO;QACN,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO;QAChC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACxB,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,KAAK,EAAE,CAAC;IACd,CAAC;IAEO,aAAa;QACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;QACxB,IAAI,QAAQ,IAAI,WAAW,CAAC,QAAQ,CAAC;YAAE,QAAQ,CAAC,OAAO,GAAG,KAAK,CAAC;QAChE,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC;IACvB,CAAC;CACD","sourcesContent":["/** Persistent TUI root with synchronous page changes and one owned lifetime. */\n\nimport { type Component, Container, type Focusable, isFocusable, type TUI } from \"@earendil-works/pi-tui\";\n\nexport type ProviderComponent = Component & { dispose?(): void };\n\nexport class ProviderTuiSession extends Container implements Focusable {\n\tprivate readonly tui: TUI;\n\tprivate readonly controller = new AbortController();\n\tprivate screen: ProviderComponent | undefined;\n\tprivate active = false;\n\n\tconstructor(tui: TUI) {\n\t\tsuper();\n\t\tthis.tui = tui;\n\t}\n\n\tget signal(): AbortSignal {\n\t\treturn this.controller.signal;\n\t}\n\tget focused(): boolean {\n\t\treturn this.active;\n\t}\n\tset focused(value: boolean) {\n\t\tthis.active = value;\n\t\tif (this.screen && isFocusable(this.screen)) this.screen.focused = value;\n\t}\n\n\tsetScreen(screen: ProviderComponent): void {\n\t\tif (this.signal.aborted) {\n\t\t\tscreen.dispose?.();\n\t\t\treturn;\n\t\t}\n\t\tthis.disposeScreen();\n\t\tthis.screen = screen;\n\t\tthis.clear();\n\t\tthis.addChild(screen);\n\t\tthis.tui.setFocus(this);\n\t\tthis.tui.requestRender();\n\t}\n\n\thandleInput(data: string): void {\n\t\tif (!this.signal.aborted) this.screen?.handleInput?.(data);\n\t}\n\n\tdispose(): void {\n\t\tif (this.signal.aborted) return;\n\t\tthis.controller.abort();\n\t\tthis.disposeScreen();\n\t\tthis.clear();\n\t}\n\n\tprivate disposeScreen(): void {\n\t\tconst previous = this.screen;\n\t\tthis.screen = undefined;\n\t\tif (previous && isFocusable(previous)) previous.focused = false;\n\t\tprevious?.dispose?.();\n\t}\n}\n"]}
@@ -0,0 +1,20 @@
1
+ /** The seven thinking levels and their inherited, hidden, or string mappings. */
2
+ import type { EditorHost, EditorPane, ModelHandle } from "./pane.ts";
3
+ export declare class ThinkingMapPane implements EditorPane {
4
+ readonly crumb = "thinkingLevelMap";
5
+ private mode;
6
+ private index;
7
+ private editor;
8
+ private error;
9
+ private focused;
10
+ private readonly host;
11
+ private readonly model;
12
+ constructor(host: EditorHost, model: ModelHandle);
13
+ private map;
14
+ render(width: number): string[];
15
+ handleInput(data: string): void;
16
+ setFocused(focused: boolean): void;
17
+ isEditing(): boolean;
18
+ hints(): string;
19
+ }
20
+ //# sourceMappingURL=thinking-map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thinking-map.d.ts","sourceRoot":"","sources":["../../../../src/extensions/provider/ui/thinking-map.ts"],"names":[],"mappings":"AAAA,iFAAiF;AAMjF,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAYrE,qBAAa,eAAgB,YAAW,UAAU;IACjD,QAAQ,CAAC,KAAK,sBAAsB;IACpC,OAAO,CAAC,IAAI,CAAuC;IACnD,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,OAAO,CAAS;IAExB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;gBACxB,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW;IAKhD,OAAO,CAAC,GAAG;IAIX,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAsD/B,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAiF/B,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAKlC,SAAS,IAAI,OAAO;IAIpB,KAAK,IAAI,MAAM;CASf"}
@@ -0,0 +1,166 @@
1
+ /** The seven thinking levels and their inherited, hidden, or string mappings. */
2
+ import { keyHint, rawKeyHint } from "../../../modes/interactive/components/keybinding-hints.js";
3
+ import { THINKING_LEVELS, truncate } from "../constants.js";
4
+ import { DELETE } from "../store.js";
5
+ import { renderInfoLine, renderKeyValueLine, renderPlainLine, ValueEditor } from "./value-row.js";
6
+ export class ThinkingMapPane {
7
+ constructor(host, model) {
8
+ this.crumb = "thinkingLevelMap";
9
+ this.mode = { type: "levels" };
10
+ this.index = 0;
11
+ this.focused = false;
12
+ this.host = host;
13
+ this.model = model;
14
+ }
15
+ map() {
16
+ return this.model.read().thinkingLevelMap ?? {};
17
+ }
18
+ render(width) {
19
+ const theme = this.host.theme;
20
+ const lines = [];
21
+ if (this.model.read().reasoning !== true) {
22
+ lines.push(renderInfoLine(theme, "reasoning is not true — the map is stored but currently has no effect.", width));
23
+ }
24
+ if (this.mode.type === "levels") {
25
+ for (const [rowIndex, level] of THINKING_LEVELS.entries()) {
26
+ const value = this.map()[level];
27
+ const status = value === undefined ? "default" : value === null ? "null (hidden)" : value;
28
+ lines.push(renderKeyValueLine(theme, {
29
+ keyLabel: level,
30
+ valueText: status,
31
+ unset: value === undefined,
32
+ active: rowIndex === this.index,
33
+ paneFocused: this.focused,
34
+ width,
35
+ }));
36
+ }
37
+ }
38
+ else if (this.mode.type === "choice") {
39
+ lines.push(renderInfoLine(theme, `${this.mode.level} · mapping`, width));
40
+ for (const [choiceIndex, label] of [
41
+ "String target (provider effort)",
42
+ "Hidden (null)",
43
+ "Default (remove key)",
44
+ ].entries()) {
45
+ lines.push(renderPlainLine(theme, label, {
46
+ active: choiceIndex === this.mode.index,
47
+ paneFocused: this.focused,
48
+ width,
49
+ }));
50
+ }
51
+ }
52
+ else {
53
+ lines.push(renderInfoLine(theme, `${this.mode.level} · non-empty provider effort`, width));
54
+ lines.push(renderKeyValueLine(theme, {
55
+ keyLabel: this.mode.level,
56
+ active: true,
57
+ paneFocused: this.focused,
58
+ editing: this.editor,
59
+ width,
60
+ }));
61
+ }
62
+ if (this.error)
63
+ lines.push(theme.fg("error", truncate(this.error, Math.max(10, width - 2))));
64
+ return lines;
65
+ }
66
+ handleInput(data) {
67
+ const kb = this.host.keybindings;
68
+ if (this.mode.type === "target") {
69
+ if (kb.matches(data, "tui.select.up") || kb.matches(data, "tui.select.down"))
70
+ return;
71
+ this.editor?.handleInput(data);
72
+ this.host.refresh();
73
+ return;
74
+ }
75
+ if (this.mode.type === "choice") {
76
+ if (kb.matches(data, "tui.select.up")) {
77
+ this.mode = { ...this.mode, index: this.mode.index === 0 ? 2 : this.mode.index - 1 };
78
+ this.host.refresh();
79
+ return;
80
+ }
81
+ if (kb.matches(data, "tui.select.down")) {
82
+ this.mode = { ...this.mode, index: (this.mode.index + 1) % 3 };
83
+ this.host.refresh();
84
+ return;
85
+ }
86
+ if (kb.matches(data, "tui.select.cancel")) {
87
+ this.mode = { type: "levels" };
88
+ this.host.refresh();
89
+ return;
90
+ }
91
+ if (kb.matches(data, "tui.select.confirm")) {
92
+ const { level, index } = this.mode;
93
+ if (index === 0) {
94
+ const editor = new ValueEditor({
95
+ onCommit: (value) => {
96
+ const target = value.trim();
97
+ if (!target) {
98
+ this.error = "A string target must be non-empty; use Hidden for null.";
99
+ return this.host.refresh();
100
+ }
101
+ this.error = undefined;
102
+ this.mode = { type: "levels" };
103
+ this.editor = undefined;
104
+ this.host.mutate(() => this.model.setField(["thinkingLevelMap", level], target));
105
+ },
106
+ onCancel: () => {
107
+ this.editor = undefined;
108
+ this.mode = { type: "levels" };
109
+ this.host.refresh();
110
+ },
111
+ });
112
+ this.editor = editor;
113
+ editor.focused = this.focused;
114
+ const existing = this.map()[level];
115
+ if (typeof existing === "string")
116
+ editor.beginTweak(existing);
117
+ this.mode = { type: "target", level };
118
+ this.host.refresh();
119
+ return;
120
+ }
121
+ this.mode = { type: "levels" };
122
+ this.host.mutate(() => this.model.setField(["thinkingLevelMap", level], index === 1 ? null : DELETE));
123
+ return;
124
+ }
125
+ return;
126
+ }
127
+ // levels
128
+ if (kb.matches(data, "tui.select.up")) {
129
+ this.index = this.index === 0 ? THINKING_LEVELS.length - 1 : this.index - 1;
130
+ this.host.refresh();
131
+ return;
132
+ }
133
+ if (kb.matches(data, "tui.select.down")) {
134
+ this.index = (this.index + 1) % THINKING_LEVELS.length;
135
+ this.host.refresh();
136
+ return;
137
+ }
138
+ if (kb.matches(data, "tui.select.confirm")) {
139
+ this.mode = { type: "choice", level: THINKING_LEVELS[this.index], index: 0 };
140
+ this.host.refresh();
141
+ return;
142
+ }
143
+ if (kb.matches(data, "tui.select.cancel")) {
144
+ this.host.popPane();
145
+ return;
146
+ }
147
+ }
148
+ setFocused(focused) {
149
+ this.focused = focused;
150
+ if (this.editor)
151
+ this.editor.focused = focused && this.mode.type === "target";
152
+ }
153
+ isEditing() {
154
+ return this.mode.type === "target";
155
+ }
156
+ hints() {
157
+ if (this.mode.type === "target")
158
+ return [keyHint("tui.input.submit", "save"), keyHint("tui.select.cancel", "back")].join(" ");
159
+ return [
160
+ rawKeyHint("↑↓", "move"),
161
+ keyHint("tui.select.confirm", this.mode.type === "choice" ? "set" : "edit"),
162
+ keyHint("tui.select.cancel", "back"),
163
+ ].join(" ");
164
+ }
165
+ }
166
+ //# sourceMappingURL=thinking-map.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thinking-map.js","sourceRoot":"","sources":["../../../../src/extensions/provider/ui/thinking-map.ts"],"names":[],"mappings":"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","sourcesContent":["/** The seven thinking levels and their inherited, hidden, or string mappings. */\n\nimport type { ModelThinkingLevel } from \"@earendil-works/pi-ai\";\nimport { keyHint, rawKeyHint } from \"../../../modes/interactive/components/keybinding-hints.ts\";\nimport { THINKING_LEVELS, truncate } from \"../constants.ts\";\nimport { DELETE } from \"../store.ts\";\nimport type { EditorHost, EditorPane, ModelHandle } from \"./pane.ts\";\nimport { renderInfoLine, renderKeyValueLine, renderPlainLine, ValueEditor } from \"./value-row.ts\";\n\n// -------------------------------------------------------------------------\n// thinkingLevelMap\n// -------------------------------------------------------------------------\n\ntype ThinkingMapMode =\n\t| { type: \"levels\" }\n\t| { type: \"choice\"; level: ModelThinkingLevel; index: number }\n\t| { type: \"target\"; level: ModelThinkingLevel };\n\nexport class ThinkingMapPane implements EditorPane {\n\treadonly crumb = \"thinkingLevelMap\";\n\tprivate mode: ThinkingMapMode = { type: \"levels\" };\n\tprivate index = 0;\n\tprivate editor: ValueEditor | undefined;\n\tprivate error: string | undefined;\n\tprivate focused = false;\n\n\tprivate readonly host: EditorHost;\n\tprivate readonly model: ModelHandle;\n\tconstructor(host: EditorHost, model: ModelHandle) {\n\t\tthis.host = host;\n\t\tthis.model = model;\n\t}\n\n\tprivate map(): Partial<Record<ModelThinkingLevel, string | null>> {\n\t\treturn this.model.read().thinkingLevelMap ?? {};\n\t}\n\n\trender(width: number): string[] {\n\t\tconst theme = this.host.theme;\n\t\tconst lines: string[] = [];\n\t\tif (this.model.read().reasoning !== true) {\n\t\t\tlines.push(\n\t\t\t\trenderInfoLine(theme, \"reasoning is not true — the map is stored but currently has no effect.\", width),\n\t\t\t);\n\t\t}\n\t\tif (this.mode.type === \"levels\") {\n\t\t\tfor (const [rowIndex, level] of THINKING_LEVELS.entries()) {\n\t\t\t\tconst value = this.map()[level];\n\t\t\t\tconst status = value === undefined ? \"default\" : value === null ? \"null (hidden)\" : value;\n\t\t\t\tlines.push(\n\t\t\t\t\trenderKeyValueLine(theme, {\n\t\t\t\t\t\tkeyLabel: level,\n\t\t\t\t\t\tvalueText: status,\n\t\t\t\t\t\tunset: value === undefined,\n\t\t\t\t\t\tactive: rowIndex === this.index,\n\t\t\t\t\t\tpaneFocused: this.focused,\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} else if (this.mode.type === \"choice\") {\n\t\t\tlines.push(renderInfoLine(theme, `${this.mode.level} · mapping`, width));\n\t\t\tfor (const [choiceIndex, label] of [\n\t\t\t\t\"String target (provider effort)\",\n\t\t\t\t\"Hidden (null)\",\n\t\t\t\t\"Default (remove key)\",\n\t\t\t].entries()) {\n\t\t\t\tlines.push(\n\t\t\t\t\trenderPlainLine(theme, label, {\n\t\t\t\t\t\tactive: choiceIndex === this.mode.index,\n\t\t\t\t\t\tpaneFocused: this.focused,\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} else {\n\t\t\tlines.push(renderInfoLine(theme, `${this.mode.level} · non-empty provider effort`, width));\n\t\t\tlines.push(\n\t\t\t\trenderKeyValueLine(theme, {\n\t\t\t\t\tkeyLabel: this.mode.level,\n\t\t\t\t\tactive: true,\n\t\t\t\t\tpaneFocused: this.focused,\n\t\t\t\t\tediting: this.editor,\n\t\t\t\t\twidth,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\tif (this.error) lines.push(theme.fg(\"error\", truncate(this.error, Math.max(10, width - 2))));\n\t\treturn lines;\n\t}\n\n\thandleInput(data: string): void {\n\t\tconst kb = this.host.keybindings;\n\t\tif (this.mode.type === \"target\") {\n\t\t\tif (kb.matches(data, \"tui.select.up\") || kb.matches(data, \"tui.select.down\")) return;\n\t\t\tthis.editor?.handleInput(data);\n\t\t\tthis.host.refresh();\n\t\t\treturn;\n\t\t}\n\t\tif (this.mode.type === \"choice\") {\n\t\t\tif (kb.matches(data, \"tui.select.up\")) {\n\t\t\t\tthis.mode = { ...this.mode, index: this.mode.index === 0 ? 2 : this.mode.index - 1 };\n\t\t\t\tthis.host.refresh();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (kb.matches(data, \"tui.select.down\")) {\n\t\t\t\tthis.mode = { ...this.mode, index: (this.mode.index + 1) % 3 };\n\t\t\t\tthis.host.refresh();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\t\tthis.mode = { type: \"levels\" };\n\t\t\t\tthis.host.refresh();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (kb.matches(data, \"tui.select.confirm\")) {\n\t\t\t\tconst { level, index } = this.mode;\n\t\t\t\tif (index === 0) {\n\t\t\t\t\tconst editor = new ValueEditor({\n\t\t\t\t\t\tonCommit: (value) => {\n\t\t\t\t\t\t\tconst target = value.trim();\n\t\t\t\t\t\t\tif (!target) {\n\t\t\t\t\t\t\t\tthis.error = \"A string target must be non-empty; use Hidden for null.\";\n\t\t\t\t\t\t\t\treturn this.host.refresh();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis.error = undefined;\n\t\t\t\t\t\t\tthis.mode = { type: \"levels\" };\n\t\t\t\t\t\t\tthis.editor = undefined;\n\t\t\t\t\t\t\tthis.host.mutate(() => this.model.setField([\"thinkingLevelMap\", level], target));\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonCancel: () => {\n\t\t\t\t\t\t\tthis.editor = undefined;\n\t\t\t\t\t\t\tthis.mode = { type: \"levels\" };\n\t\t\t\t\t\t\tthis.host.refresh();\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t\tthis.editor = editor;\n\t\t\t\t\teditor.focused = this.focused;\n\t\t\t\t\tconst existing = this.map()[level];\n\t\t\t\t\tif (typeof existing === \"string\") editor.beginTweak(existing);\n\t\t\t\t\tthis.mode = { type: \"target\", level };\n\t\t\t\t\tthis.host.refresh();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.mode = { type: \"levels\" };\n\t\t\t\tthis.host.mutate(() => this.model.setField([\"thinkingLevelMap\", level], index === 1 ? null : DELETE));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\t// levels\n\t\tif (kb.matches(data, \"tui.select.up\")) {\n\t\t\tthis.index = this.index === 0 ? THINKING_LEVELS.length - 1 : this.index - 1;\n\t\t\tthis.host.refresh();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.down\")) {\n\t\t\tthis.index = (this.index + 1) % THINKING_LEVELS.length;\n\t\t\tthis.host.refresh();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.confirm\")) {\n\t\t\tthis.mode = { type: \"choice\", level: THINKING_LEVELS[this.index]!, index: 0 };\n\t\t\tthis.host.refresh();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis.host.popPane();\n\t\t\treturn;\n\t\t}\n\t}\n\n\tsetFocused(focused: boolean): void {\n\t\tthis.focused = focused;\n\t\tif (this.editor) this.editor.focused = focused && this.mode.type === \"target\";\n\t}\n\n\tisEditing(): boolean {\n\t\treturn this.mode.type === \"target\";\n\t}\n\n\thints(): string {\n\t\tif (this.mode.type === \"target\")\n\t\t\treturn [keyHint(\"tui.input.submit\", \"save\"), keyHint(\"tui.select.cancel\", \"back\")].join(\" \");\n\t\treturn [\n\t\t\trawKeyHint(\"↑↓\", \"move\"),\n\t\t\tkeyHint(\"tui.select.confirm\", this.mode.type === \"choice\" ? \"set\" : \"edit\"),\n\t\t\tkeyHint(\"tui.select.cancel\", \"back\"),\n\t\t].join(\" \");\n\t}\n}\n"]}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Shared row machinery for /provider right-column panes.
3
+ *
4
+ * Fixed-key rows always render `Key: Value`; the key and colon are never
5
+ * editable, but the whole row highlights when selected. Value editing uses
6
+ * pi-tui's Input: typing starts an overwrite, Enter starts a tweak with the
7
+ * old value, Esc restores.
8
+ */
9
+ import type { Theme } from "../../../modes/interactive/theme/theme.ts";
10
+ export declare const CURSOR = "\u203A";
11
+ /** Wraps pi-tui Input with the two /provider entry modes. */
12
+ export declare class ValueEditor {
13
+ private readonly input;
14
+ constructor(callbacks: {
15
+ /** Enter pressed; the pane validates and either closes the editor or keeps it open with an error. */
16
+ onCommit: (value: string) => void;
17
+ /** Esc pressed; the pane discards the in-progress value. */
18
+ onCancel: () => void;
19
+ });
20
+ /** Start with an empty value; optional first input (the character/paste that opened the editor). */
21
+ beginOverwrite(firstData?: string): void;
22
+ /** Reset the text without any editing semantics (search boxes, repurposed inputs). */
23
+ reset(value: string): void;
24
+ /** Start with the current value and the cursor at the end. */
25
+ beginTweak(current: string): void;
26
+ get value(): string;
27
+ handleInput(data: string): void;
28
+ renderLine(width: number): string;
29
+ get focused(): boolean;
30
+ set focused(value: boolean);
31
+ }
32
+ export interface KeyValueLineOptions {
33
+ /** Fixed key label, rendered as `key: `; omitted for free-form lines. */
34
+ keyLabel?: string;
35
+ /** Current value display (already masked/truncated by the caller as needed). */
36
+ valueText?: string;
37
+ /** Value is unset and the text shows a default/inherited fallback. */
38
+ unset?: boolean;
39
+ /** Row is the pane's cursor row. */
40
+ active: boolean;
41
+ /** The pane holding this row currently has keyboard focus. */
42
+ paneFocused: boolean;
43
+ /** When set, the row renders the editor in place of the value. */
44
+ editing?: ValueEditor;
45
+ /** Extra dim note after the value, e.g. `· draft`. */
46
+ note?: string;
47
+ width: number;
48
+ }
49
+ /**
50
+ * Render one `key: value` row. The selection marker and accent appear only
51
+ * when the row is active AND its pane holds focus — the screen shows exactly
52
+ * one accent `›`, and that is where the keyboard goes. Unfocused panes keep
53
+ * their content in text color; unset fallback values stay dim even when lit.
54
+ */
55
+ export declare function renderKeyValueLine(theme: Theme, opts: KeyValueLineOptions): string;
56
+ export interface PlainLineOptions {
57
+ active?: boolean;
58
+ paneFocused?: boolean;
59
+ dim?: boolean;
60
+ /** Checkbox mark; renders `[x] ` / `[ ] ` before the text. */
61
+ checked?: boolean;
62
+ note?: string;
63
+ width: number;
64
+ }
65
+ /** Render a non-key row: action rows, checkboxes, radio options, hints. Same single-accent focus rule as renderKeyValueLine. */
66
+ export declare function renderPlainLine(theme: Theme, text: string, opts: PlainLineOptions): string;
67
+ /** Dim informational line without a cursor slot. */
68
+ export declare function renderInfoLine(theme: Theme, text: string, width: number): string;
69
+ export interface ScrollWindowInfo {
70
+ /** Leading render() lines that never scroll (filter inputs, headers). */
71
+ top?: number;
72
+ /** Trailing render() lines that never scroll (status and error lines). */
73
+ bottom?: number;
74
+ /** render() line index the window keeps visible. */
75
+ cursor?: number;
76
+ }
77
+ /**
78
+ * Clip lines to a fixed height, keeping the cursor row centered and the
79
+ * pinned top/bottom lines on screen. Always returns exactly `height` lines;
80
+ * when the scrollable middle overflows, one row becomes a dim `(n/N)`
81
+ * position indicator (the /model selector convention).
82
+ */
83
+ export declare function windowLines(theme: Theme, lines: string[], height: number, scroll?: ScrollWindowInfo, indicator?: (position: number, total: number) => string): string[];
84
+ /** True for printable text input (single chars or pasted text), false for key events and control sequences. */
85
+ export declare function isPrintableInput(data: string): boolean;
86
+ /** Width-aware middle ellipsis for long identifiers: keeps the head and the tail. */
87
+ export declare function truncateMiddle(text: string, maxWidth: number): string;
88
+ //# sourceMappingURL=value-row.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"value-row.d.ts","sourceRoot":"","sources":["../../../../src/extensions/provider/ui/value-row.ts"],"names":[],"mappings":"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"}