@astralyn/pi 0.85.1 → 0.85.2

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 (248) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/cli.js +94 -91
  3. package/dist/core/agent-session.js +2 -2
  4. package/dist/core/agent-session.js.map +1 -1
  5. package/dist/core/background/history.d.ts.map +1 -1
  6. package/dist/core/background/history.js +6 -0
  7. package/dist/core/background/history.js.map +1 -1
  8. package/dist/core/background/presentation.d.ts.map +1 -1
  9. package/dist/core/background/presentation.js +41 -4
  10. package/dist/core/background/presentation.js.map +1 -1
  11. package/dist/core/background/service.d.ts +2 -2
  12. package/dist/core/background/service.d.ts.map +1 -1
  13. package/dist/core/background/service.js +38 -15
  14. package/dist/core/background/service.js.map +1 -1
  15. package/dist/core/background/types.d.ts +9 -0
  16. package/dist/core/background/types.d.ts.map +1 -1
  17. package/dist/core/background/types.js +4 -0
  18. package/dist/core/background/types.js.map +1 -1
  19. package/dist/core/compaction/compaction.d.ts +5 -12
  20. package/dist/core/compaction/compaction.d.ts.map +1 -1
  21. package/dist/core/compaction/compaction.js +11 -19
  22. package/dist/core/compaction/compaction.js.map +1 -1
  23. package/dist/core/compaction/settings.d.ts +27 -0
  24. package/dist/core/compaction/settings.d.ts.map +1 -0
  25. package/dist/core/compaction/settings.js +40 -0
  26. package/dist/core/compaction/settings.js.map +1 -0
  27. package/dist/core/keybindings.d.ts +15 -0
  28. package/dist/core/keybindings.d.ts.map +1 -1
  29. package/dist/core/keybindings.js +12 -0
  30. package/dist/core/keybindings.js.map +1 -1
  31. package/dist/core/model-config.d.ts +32 -10
  32. package/dist/core/model-config.d.ts.map +1 -1
  33. package/dist/core/model-config.js +38 -1
  34. package/dist/core/model-config.js.map +1 -1
  35. package/dist/core/model-runtime.d.ts +2 -0
  36. package/dist/core/model-runtime.d.ts.map +1 -1
  37. package/dist/core/model-runtime.js +4 -0
  38. package/dist/core/model-runtime.js.map +1 -1
  39. package/dist/core/settings-manager.d.ts +4 -7
  40. package/dist/core/settings-manager.d.ts.map +1 -1
  41. package/dist/core/settings-manager.js +7 -6
  42. package/dist/core/settings-manager.js.map +1 -1
  43. package/dist/core/tools/bash.js +1 -1
  44. package/dist/core/tools/bash.js.map +1 -1
  45. package/dist/core/tools/shell-execution.d.ts.map +1 -1
  46. package/dist/core/tools/shell-execution.js +3 -1
  47. package/dist/core/tools/shell-execution.js.map +1 -1
  48. package/dist/extensions/background/manager.d.ts +8 -5
  49. package/dist/extensions/background/manager.d.ts.map +1 -1
  50. package/dist/extensions/background/manager.js +115 -39
  51. package/dist/extensions/background/manager.js.map +1 -1
  52. package/dist/extensions/background/task-view.d.ts +5 -0
  53. package/dist/extensions/background/task-view.d.ts.map +1 -1
  54. package/dist/extensions/background/task-view.js +4 -0
  55. package/dist/extensions/background/task-view.js.map +1 -1
  56. package/dist/extensions/btw/controller.d.ts +1 -1
  57. package/dist/extensions/btw/controller.d.ts.map +1 -1
  58. package/dist/extensions/btw/controller.js +4 -4
  59. package/dist/extensions/btw/controller.js.map +1 -1
  60. package/dist/extensions/btw/index.js +3 -3
  61. package/dist/extensions/btw/index.js.map +1 -1
  62. package/dist/extensions/index.js +2 -2
  63. package/dist/extensions/index.js.map +1 -1
  64. package/dist/extensions/provider/catalog.d.ts +57 -0
  65. package/dist/extensions/provider/catalog.d.ts.map +1 -0
  66. package/dist/extensions/provider/catalog.js +181 -0
  67. package/dist/extensions/provider/catalog.js.map +1 -0
  68. package/dist/extensions/provider/compat-fields.d.ts +25 -0
  69. package/dist/extensions/provider/compat-fields.d.ts.map +1 -0
  70. package/dist/extensions/provider/compat-fields.js +148 -0
  71. package/dist/extensions/provider/compat-fields.js.map +1 -0
  72. package/dist/extensions/provider/configuration.d.ts +8 -0
  73. package/dist/extensions/provider/configuration.d.ts.map +1 -0
  74. package/dist/extensions/provider/configuration.js +21 -0
  75. package/dist/extensions/provider/configuration.js.map +1 -0
  76. package/dist/extensions/provider/connection.d.ts +14 -0
  77. package/dist/extensions/provider/connection.d.ts.map +1 -0
  78. package/dist/extensions/provider/connection.js +86 -0
  79. package/dist/extensions/provider/connection.js.map +1 -0
  80. package/dist/extensions/provider/constants.d.ts +38 -0
  81. package/dist/extensions/provider/constants.d.ts.map +1 -0
  82. package/dist/extensions/provider/constants.js +75 -0
  83. package/dist/extensions/provider/constants.js.map +1 -0
  84. package/dist/extensions/provider/index.d.ts +4 -0
  85. package/dist/extensions/provider/index.d.ts.map +1 -0
  86. package/dist/extensions/provider/index.js +65 -0
  87. package/dist/extensions/provider/index.js.map +1 -0
  88. package/dist/extensions/provider/probe.d.ts +34 -0
  89. package/dist/extensions/provider/probe.d.ts.map +1 -0
  90. package/dist/extensions/provider/probe.js +178 -0
  91. package/dist/extensions/provider/probe.js.map +1 -0
  92. package/dist/extensions/provider/refresh.d.ts +30 -0
  93. package/dist/extensions/provider/refresh.d.ts.map +1 -0
  94. package/dist/extensions/provider/refresh.js +66 -0
  95. package/dist/extensions/provider/refresh.js.map +1 -0
  96. package/dist/extensions/provider/store.d.ts +131 -0
  97. package/dist/extensions/provider/store.d.ts.map +1 -0
  98. package/dist/extensions/provider/store.js +503 -0
  99. package/dist/extensions/provider/store.js.map +1 -0
  100. package/dist/extensions/provider/ui/app.d.ts +25 -0
  101. package/dist/extensions/provider/ui/app.d.ts.map +1 -0
  102. package/dist/extensions/provider/ui/app.js +153 -0
  103. package/dist/extensions/provider/ui/app.js.map +1 -0
  104. package/dist/extensions/provider/ui/builtin-data.d.ts +53 -0
  105. package/dist/extensions/provider/ui/builtin-data.d.ts.map +1 -0
  106. package/dist/extensions/provider/ui/builtin-data.js +315 -0
  107. package/dist/extensions/provider/ui/builtin-data.js.map +1 -0
  108. package/dist/extensions/provider/ui/compat.d.ts +57 -0
  109. package/dist/extensions/provider/ui/compat.d.ts.map +1 -0
  110. package/dist/extensions/provider/ui/compat.js +427 -0
  111. package/dist/extensions/provider/ui/compat.js.map +1 -0
  112. package/dist/extensions/provider/ui/dialogs.d.ts +30 -0
  113. package/dist/extensions/provider/ui/dialogs.d.ts.map +1 -0
  114. package/dist/extensions/provider/ui/dialogs.js +89 -0
  115. package/dist/extensions/provider/ui/dialogs.js.map +1 -0
  116. package/dist/extensions/provider/ui/dictionary.d.ts +29 -0
  117. package/dist/extensions/provider/ui/dictionary.d.ts.map +1 -0
  118. package/dist/extensions/provider/ui/dictionary.js +385 -0
  119. package/dist/extensions/provider/ui/dictionary.js.map +1 -0
  120. package/dist/extensions/provider/ui/editor.d.ts +91 -0
  121. package/dist/extensions/provider/ui/editor.d.ts.map +1 -0
  122. package/dist/extensions/provider/ui/editor.js +667 -0
  123. package/dist/extensions/provider/ui/editor.js.map +1 -0
  124. package/dist/extensions/provider/ui/fetch-models.d.ts +39 -0
  125. package/dist/extensions/provider/ui/fetch-models.d.ts.map +1 -0
  126. package/dist/extensions/provider/ui/fetch-models.js +320 -0
  127. package/dist/extensions/provider/ui/fetch-models.js.map +1 -0
  128. package/dist/extensions/provider/ui/model-fields.d.ts +43 -0
  129. package/dist/extensions/provider/ui/model-fields.d.ts.map +1 -0
  130. package/dist/extensions/provider/ui/model-fields.js +441 -0
  131. package/dist/extensions/provider/ui/model-fields.js.map +1 -0
  132. package/dist/extensions/provider/ui/model-options.d.ts +93 -0
  133. package/dist/extensions/provider/ui/model-options.d.ts.map +1 -0
  134. package/dist/extensions/provider/ui/model-options.js +529 -0
  135. package/dist/extensions/provider/ui/model-options.js.map +1 -0
  136. package/dist/extensions/provider/ui/pane.d.ts +81 -0
  137. package/dist/extensions/provider/ui/pane.d.ts.map +1 -0
  138. package/dist/extensions/provider/ui/pane.js +3 -0
  139. package/dist/extensions/provider/ui/pane.js.map +1 -0
  140. package/dist/extensions/provider/ui/provider-fields.d.ts +60 -0
  141. package/dist/extensions/provider/ui/provider-fields.d.ts.map +1 -0
  142. package/dist/extensions/provider/ui/provider-fields.js +326 -0
  143. package/dist/extensions/provider/ui/provider-fields.js.map +1 -0
  144. package/dist/extensions/provider/ui/provider-list.d.ts +34 -0
  145. package/dist/extensions/provider/ui/provider-list.d.ts.map +1 -0
  146. package/dist/extensions/provider/ui/provider-list.js +162 -0
  147. package/dist/extensions/provider/ui/provider-list.js.map +1 -0
  148. package/dist/extensions/provider/ui/session.d.ts +20 -0
  149. package/dist/extensions/provider/ui/session.d.ts.map +1 -0
  150. package/dist/extensions/provider/ui/session.js +52 -0
  151. package/dist/extensions/provider/ui/session.js.map +1 -0
  152. package/dist/extensions/provider/ui/thinking-map.d.ts +20 -0
  153. package/dist/extensions/provider/ui/thinking-map.d.ts.map +1 -0
  154. package/dist/extensions/provider/ui/thinking-map.js +166 -0
  155. package/dist/extensions/provider/ui/thinking-map.js.map +1 -0
  156. package/dist/extensions/provider/ui/value-row.d.ts +88 -0
  157. package/dist/extensions/provider/ui/value-row.d.ts.map +1 -0
  158. package/dist/extensions/provider/ui/value-row.js +158 -0
  159. package/dist/extensions/provider/ui/value-row.js.map +1 -0
  160. package/dist/extensions/statusline/index.js +2 -2
  161. package/dist/extensions/statusline/index.js.map +1 -1
  162. package/dist/extensions/subagent/index.d.ts.map +1 -1
  163. package/dist/extensions/subagent/index.js +4 -2
  164. package/dist/extensions/subagent/index.js.map +1 -1
  165. package/dist/extensions/subagent/resolve.d.ts +5 -0
  166. package/dist/extensions/subagent/resolve.d.ts.map +1 -1
  167. package/dist/extensions/subagent/resolve.js +15 -7
  168. package/dist/extensions/subagent/resolve.js.map +1 -1
  169. package/dist/extensions/subagent/schema.d.ts +2 -0
  170. package/dist/extensions/subagent/schema.d.ts.map +1 -1
  171. package/dist/extensions/subagent/schema.js +1 -0
  172. package/dist/extensions/subagent/schema.js.map +1 -1
  173. package/dist/modes/interactive/components/tool-execution.d.ts +10 -0
  174. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  175. package/dist/modes/interactive/components/tool-execution.js +20 -2
  176. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  177. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  178. package/dist/modes/interactive/interactive-mode.js +6 -1
  179. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  180. package/dist/rpc-entry.js +94 -91
  181. package/docs/bundled/README.md +1 -1
  182. package/docs/bundled/extensions/background.md +5 -5
  183. package/docs/bundled/extensions/provider.md +117 -0
  184. package/docs/bundled/extensions/statusline.md +1 -1
  185. package/docs/bundled/extensions/subagent.md +7 -3
  186. package/docs/compaction.md +16 -6
  187. package/docs/docs.json +2 -2
  188. package/docs/keybindings.md +3 -0
  189. package/docs/settings.md +11 -7
  190. package/npm-shrinkwrap.json +2 -2
  191. package/package.json +1 -1
  192. package/dist/extensions/router/constants.d.ts +0 -23
  193. package/dist/extensions/router/constants.d.ts.map +0 -1
  194. package/dist/extensions/router/constants.js +0 -30
  195. package/dist/extensions/router/constants.js.map +0 -1
  196. package/dist/extensions/router/dialog-host.d.ts +0 -60
  197. package/dist/extensions/router/dialog-host.d.ts.map +0 -1
  198. package/dist/extensions/router/dialog-host.js +0 -196
  199. package/dist/extensions/router/dialog-host.js.map +0 -1
  200. package/dist/extensions/router/dialog.d.ts +0 -45
  201. package/dist/extensions/router/dialog.d.ts.map +0 -1
  202. package/dist/extensions/router/dialog.js +0 -378
  203. package/dist/extensions/router/dialog.js.map +0 -1
  204. package/dist/extensions/router/identity.d.ts +0 -15
  205. package/dist/extensions/router/identity.d.ts.map +0 -1
  206. package/dist/extensions/router/identity.js +0 -173
  207. package/dist/extensions/router/identity.js.map +0 -1
  208. package/dist/extensions/router/index.d.ts +0 -15
  209. package/dist/extensions/router/index.d.ts.map +0 -1
  210. package/dist/extensions/router/index.js +0 -70
  211. package/dist/extensions/router/index.js.map +0 -1
  212. package/dist/extensions/router/presets.d.ts +0 -51
  213. package/dist/extensions/router/presets.d.ts.map +0 -1
  214. package/dist/extensions/router/presets.js +0 -108
  215. package/dist/extensions/router/presets.js.map +0 -1
  216. package/dist/extensions/router/probe.d.ts +0 -26
  217. package/dist/extensions/router/probe.d.ts.map +0 -1
  218. package/dist/extensions/router/probe.js +0 -216
  219. package/dist/extensions/router/probe.js.map +0 -1
  220. package/dist/extensions/router/register.d.ts +0 -12
  221. package/dist/extensions/router/register.d.ts.map +0 -1
  222. package/dist/extensions/router/register.js +0 -90
  223. package/dist/extensions/router/register.js.map +0 -1
  224. package/dist/extensions/router/state.d.ts +0 -20
  225. package/dist/extensions/router/state.d.ts.map +0 -1
  226. package/dist/extensions/router/state.js +0 -169
  227. package/dist/extensions/router/state.js.map +0 -1
  228. package/dist/extensions/router/store.d.ts +0 -12
  229. package/dist/extensions/router/store.d.ts.map +0 -1
  230. package/dist/extensions/router/store.js +0 -266
  231. package/dist/extensions/router/store.js.map +0 -1
  232. package/dist/extensions/router/stream.d.ts +0 -12
  233. package/dist/extensions/router/stream.d.ts.map +0 -1
  234. package/dist/extensions/router/stream.js +0 -233
  235. package/dist/extensions/router/stream.js.map +0 -1
  236. package/dist/extensions/router/transport.d.ts +0 -9
  237. package/dist/extensions/router/transport.d.ts.map +0 -1
  238. package/dist/extensions/router/transport.js +0 -81
  239. package/dist/extensions/router/transport.js.map +0 -1
  240. package/dist/extensions/router/types.d.ts +0 -39
  241. package/dist/extensions/router/types.d.ts.map +0 -1
  242. package/dist/extensions/router/types.js +0 -2
  243. package/dist/extensions/router/types.js.map +0 -1
  244. package/dist/extensions/router/ui.d.ts +0 -26
  245. package/dist/extensions/router/ui.d.ts.map +0 -1
  246. package/dist/extensions/router/ui.js +0 -897
  247. package/dist/extensions/router/ui.js.map +0 -1
  248. package/docs/bundled/extensions/router.md +0 -197
@@ -0,0 +1,81 @@
1
+ /** Pane contract for the /provider two-pane editor's right column. */
2
+ import type { TUI } from "@earendil-works/pi-tui";
3
+ import type { KeybindingsManager } from "../../../core/keybindings.ts";
4
+ import type { ModelsJsonModel } from "../../../core/model-config.ts";
5
+ import type { Theme } from "../../../modes/interactive/theme/theme.ts";
6
+ import type { ProbeModel, ProbeResult } from "../probe.ts";
7
+ import type { RefreshCoordinator } from "../refresh.ts";
8
+ import type { ModelsJsonStore } from "../store.ts";
9
+ export interface EditorPane {
10
+ /** Drill-down label shown at the top of the right column while this sub-pane is open, e.g. "cost". */
11
+ readonly crumb?: string;
12
+ /**
13
+ * Scroll position for the editor's fixed-height right column. `top` and
14
+ * `bottom` count pinned render() lines that never scroll (filter inputs,
15
+ * status/error lines); `cursor` is the render() line index the window
16
+ * keeps visible. Omitted: no scrolling, content is expected to fit.
17
+ */
18
+ scrollWindow?(): {
19
+ top?: number;
20
+ bottom?: number;
21
+ cursor?: number;
22
+ };
23
+ /** Body lines for the right column. */
24
+ render(width: number): string[];
25
+ /** Input while the right column is focused. */
26
+ handleInput(data: string): void;
27
+ /** True while a text editor inside the pane owns ←/→ (cursor movement beats pane switching). */
28
+ isEditing?(): boolean;
29
+ /** Focus propagation for embedded Input components (IME cursor placement). */
30
+ setFocused(focused: boolean): void;
31
+ /** Contextual footer hint line. */
32
+ hints(): string;
33
+ dispose?(): void;
34
+ }
35
+ /** Read/write access to the model under edit, draft or persisted. */
36
+ export interface ModelHandle {
37
+ readonly isDraft: boolean;
38
+ /** Current values; drafts carry the unsubmitted partial object. */
39
+ read(): Partial<ModelsJsonModel> & {
40
+ id?: string;
41
+ };
42
+ /** Drafts mutate memory; persisted models queue a store op and schedule a save. */
43
+ setField(path: readonly string[], value: unknown): void;
44
+ /** Renaming an identity waits for storage before the UI starts using the new id. */
45
+ rename(newId: string): Promise<string | undefined>;
46
+ }
47
+ export interface EditorHost {
48
+ readonly tui: TUI;
49
+ readonly theme: Theme;
50
+ readonly keybindings: KeybindingsManager;
51
+ readonly store: ModelsJsonStore;
52
+ readonly refresher: RefreshCoordinator;
53
+ readonly providerId: string;
54
+ pushPane(pane: EditorPane): void;
55
+ popPane(): void;
56
+ /** Queue a mutation op, mark the provider touched, and repaint. */
57
+ mutate(apply: () => void): void;
58
+ refresh(): void;
59
+ notify(message: string, type: "info" | "warning" | "error"): void;
60
+ /** Effective api/baseUrl after provider-level and builtin-overlay fallbacks. */
61
+ effectiveApi(model?: Partial<ModelsJsonModel>): string | undefined;
62
+ effectiveBaseUrl(model?: Partial<ModelsJsonModel>): string | undefined;
63
+ /** Commit the pending model draft (id validation + addModel op); returns an error or undefined. */
64
+ commitModelDraft(): string | undefined;
65
+ /** Drop the in-memory model draft; the left column returns to + Add Model. */
66
+ discardModelDraft(): void;
67
+ /** Current session model protection (§4.3): no delete/rename of the active model or its provider. */
68
+ isCurrentModel(modelId: string): boolean;
69
+ isCurrentProvider(): boolean;
70
+ /** Last Fetch Models outcome shown next to the left-column action row. */
71
+ setFetchStatus(status: string | undefined): void;
72
+ /** Refresh the provider, resolve auth canonically, and GET {baseUrl}/models. */
73
+ runFetch(signal: AbortSignal): Promise<ProbeResult>;
74
+ /** Validate + batch-add imported models, save once, refresh; returns an error or undefined. */
75
+ importModels(models: readonly ProbeModel[], signal: AbortSignal): Promise<string | undefined>;
76
+ /** Push an in-editor Yes/No confirm into the right column. */
77
+ confirm(message: string, actionLabel: string, action: () => void): void;
78
+ /** A model was just removed: rebuild the left column and reset the right stack. */
79
+ onModelRemoved(modelId: string): void;
80
+ }
81
+ //# sourceMappingURL=pane.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pane.d.ts","sourceRoot":"","sources":["../../../../src/extensions/provider/ui/pane.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** Pane contract for the /provider two-pane editor's right column. */
2
+ export {};
3
+ //# sourceMappingURL=pane.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pane.js","sourceRoot":"","sources":["../../../../src/extensions/provider/ui/pane.ts"],"names":[],"mappings":"AAAA,sEAAsE","sourcesContent":["/** Pane contract for the /provider two-pane editor's right column. */\n\nimport type { TUI } from \"@earendil-works/pi-tui\";\nimport type { KeybindingsManager } from \"../../../core/keybindings.ts\";\nimport type { ModelsJsonModel } from \"../../../core/model-config.ts\";\nimport type { Theme } from \"../../../modes/interactive/theme/theme.ts\";\nimport type { ProbeModel, ProbeResult } from \"../probe.ts\";\nimport type { RefreshCoordinator } from \"../refresh.ts\";\nimport type { ModelsJsonStore } from \"../store.ts\";\n\nexport interface EditorPane {\n\t/** Drill-down label shown at the top of the right column while this sub-pane is open, e.g. \"cost\". */\n\treadonly crumb?: string;\n\t/**\n\t * Scroll position for the editor's fixed-height right column. `top` and\n\t * `bottom` count pinned render() lines that never scroll (filter inputs,\n\t * status/error lines); `cursor` is the render() line index the window\n\t * keeps visible. Omitted: no scrolling, content is expected to fit.\n\t */\n\tscrollWindow?(): { top?: number; bottom?: number; cursor?: number };\n\t/** Body lines for the right column. */\n\trender(width: number): string[];\n\t/** Input while the right column is focused. */\n\thandleInput(data: string): void;\n\t/** True while a text editor inside the pane owns ←/→ (cursor movement beats pane switching). */\n\tisEditing?(): boolean;\n\t/** Focus propagation for embedded Input components (IME cursor placement). */\n\tsetFocused(focused: boolean): void;\n\t/** Contextual footer hint line. */\n\thints(): string;\n\tdispose?(): void;\n}\n\n/** Read/write access to the model under edit, draft or persisted. */\nexport interface ModelHandle {\n\treadonly isDraft: boolean;\n\t/** Current values; drafts carry the unsubmitted partial object. */\n\tread(): Partial<ModelsJsonModel> & { id?: string };\n\t/** Drafts mutate memory; persisted models queue a store op and schedule a save. */\n\tsetField(path: readonly string[], value: unknown): void;\n\t/** Renaming an identity waits for storage before the UI starts using the new id. */\n\trename(newId: string): Promise<string | undefined>;\n}\n\nexport interface EditorHost {\n\treadonly tui: TUI;\n\treadonly theme: Theme;\n\treadonly keybindings: KeybindingsManager;\n\treadonly store: ModelsJsonStore;\n\treadonly refresher: RefreshCoordinator;\n\treadonly providerId: string;\n\tpushPane(pane: EditorPane): void;\n\tpopPane(): void;\n\t/** Queue a mutation op, mark the provider touched, and repaint. */\n\tmutate(apply: () => void): void;\n\trefresh(): void;\n\tnotify(message: string, type: \"info\" | \"warning\" | \"error\"): void;\n\t/** Effective api/baseUrl after provider-level and builtin-overlay fallbacks. */\n\teffectiveApi(model?: Partial<ModelsJsonModel>): string | undefined;\n\teffectiveBaseUrl(model?: Partial<ModelsJsonModel>): string | undefined;\n\t/** Commit the pending model draft (id validation + addModel op); returns an error or undefined. */\n\tcommitModelDraft(): string | undefined;\n\t/** Drop the in-memory model draft; the left column returns to + Add Model. */\n\tdiscardModelDraft(): void;\n\t/** Current session model protection (§4.3): no delete/rename of the active model or its provider. */\n\tisCurrentModel(modelId: string): boolean;\n\tisCurrentProvider(): boolean;\n\t/** Last Fetch Models outcome shown next to the left-column action row. */\n\tsetFetchStatus(status: string | undefined): void;\n\t/** Refresh the provider, resolve auth canonically, and GET {baseUrl}/models. */\n\trunFetch(signal: AbortSignal): Promise<ProbeResult>;\n\t/** Validate + batch-add imported models, save once, refresh; returns an error or undefined. */\n\timportModels(models: readonly ProbeModel[], signal: AbortSignal): Promise<string | undefined>;\n\t/** Push an in-editor Yes/No confirm into the right column. */\n\tconfirm(message: string, actionLabel: string, action: () => void): void;\n\t/** A model was just removed: rebuild the left column and reset the right stack. */\n\tonModelRemoved(modelId: string): void;\n}\n"]}
@@ -0,0 +1,60 @@
1
+ /** Provider connection and API settings panes. */
2
+ import type { ModelRegistry } from "../../../core/model-registry.ts";
3
+ import type { EditorHost, EditorPane } from "./pane.ts";
4
+ import { type ScrollWindowInfo } from "./value-row.ts";
5
+ /**
6
+ * One-line guidance on the baseUrl shape an API tag expects: pi-ai delegates
7
+ * URL assembly to the vendor SDKs, so OpenAI-style tags need the version path
8
+ * in baseUrl while the Anthropic and Mistral clients append it themselves.
9
+ */
10
+ export declare function baseUrlHint(api: string | undefined): string | undefined;
11
+ /** Shared baseUrl validation for provider-level and model-level entries; returns an error or undefined. */
12
+ export declare function validateBaseUrlValue(value: string): string | undefined;
13
+ /**
14
+ * The provider's connection page: baseUrl and apiKey edit in place, while
15
+ * API Type pushes the single-select sub-page. Credential-source notes and
16
+ * the per-API baseUrl hint stay pinned below the rows.
17
+ */
18
+ export declare class ApiAuthPane implements EditorPane {
19
+ private readonly rows;
20
+ private index;
21
+ private editing;
22
+ private editingRow;
23
+ private error;
24
+ private focused;
25
+ private readonly host;
26
+ private readonly registry;
27
+ constructor(host: EditorHost, registry: Pick<ModelRegistry, "getProviderAuthStatus">);
28
+ private provider;
29
+ scrollWindow(): ScrollWindowInfo;
30
+ private bottomNoteCount;
31
+ render(width: number): string[];
32
+ handleInput(data: string): void;
33
+ private beginEdit;
34
+ private commit;
35
+ setFocused(focused: boolean): void;
36
+ isEditing(): boolean;
37
+ hints(): string;
38
+ }
39
+ /**
40
+ * Single-select provider api sub-page of API Auth; Enter applies and
41
+ * returns. Clearing is refused while any model still resolves its api from
42
+ * the provider — set a model-level API under Model-Specific API first.
43
+ */
44
+ export declare class ApiTypePane implements EditorPane {
45
+ readonly crumb = "API Type";
46
+ private index;
47
+ private focused;
48
+ private error;
49
+ private readonly host;
50
+ constructor(host: EditorHost);
51
+ /** undefined first = not set; a custom api already stored is preserved and appended. */
52
+ private options;
53
+ private unsetLabel;
54
+ render(width: number): string[];
55
+ scrollWindow(): ScrollWindowInfo;
56
+ handleInput(data: string): void;
57
+ setFocused(focused: boolean): void;
58
+ hints(): string;
59
+ }
60
+ //# sourceMappingURL=provider-fields.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-fields.d.ts","sourceRoot":"","sources":["../../../../src/extensions/provider/ui/provider-fields.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAGlD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAKrE,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAKN,KAAK,gBAAgB,EAErB,MAAM,gBAAgB,CAAC;AAExB;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAevE;AAED,2GAA2G;AAC3G,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CActE;AAED;;;;GAIG;AACH,qBAAa,WAAY,YAAW,UAAU;IAC7C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA6C;IAClE,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,UAAU,CAAmC;IACrD,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,OAAO,CAAS;IAExB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+C;gBAC5D,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,aAAa,EAAE,uBAAuB,CAAC;IAKpF,OAAO,CAAC,QAAQ;IAIhB,YAAY,IAAI,gBAAgB;IAKhC,OAAO,CAAC,eAAe;IAMvB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAqE/B,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAoC/B,OAAO,CAAC,SAAS;IAqBjB,OAAO,CAAC,MAAM;IA8Bd,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAKlC,SAAS,IAAI,OAAO;IAIpB,KAAK,IAAI,MAAM;CAUf;AAED;;;;GAIG;AACH,qBAAa,WAAY,YAAW,UAAU;IAC7C,QAAQ,CAAC,KAAK,cAAc;IAC5B,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAqB;IAElC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;gBACtB,IAAI,EAAE,UAAU;IAQ5B,wFAAwF;IACxF,OAAO,CAAC,OAAO;IAOf,OAAO,CAAC,UAAU;IAKlB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAa/B,YAAY,IAAI,gBAAgB;IAIhC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAsC/B,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIlC,KAAK,IAAI,MAAM;CAOf"}
@@ -0,0 +1,326 @@
1
+ /** Provider connection and API settings panes. */
2
+ import { keyHint, rawKeyHint } from "../../../modes/interactive/components/keybinding-hints.js";
3
+ import { builtinDefaults } from "../catalog.js";
4
+ import { API_TYPES, maskApiKey, plural, truncate } from "../constants.js";
5
+ import { DELETE } from "../store.js";
6
+ import { isPrintableInput, renderInfoLine, renderKeyValueLine, renderPlainLine, ValueEditor, } from "./value-row.js";
7
+ /**
8
+ * One-line guidance on the baseUrl shape an API tag expects: pi-ai delegates
9
+ * URL assembly to the vendor SDKs, so OpenAI-style tags need the version path
10
+ * in baseUrl while the Anthropic and Mistral clients append it themselves.
11
+ */
12
+ export function baseUrlHint(api) {
13
+ switch (api) {
14
+ case "openai-responses":
15
+ case "openai-completions":
16
+ case "openai-codex-responses":
17
+ return "baseUrl includes the version path, e.g. https://api.openai.com/v1";
18
+ case "anthropic-messages":
19
+ return "baseUrl is the bare origin — /v1/messages is added automatically";
20
+ case "mistral-conversations":
21
+ return "baseUrl is the bare origin — /v1 is added automatically";
22
+ case "google-generative-ai":
23
+ return "baseUrl includes the version path, e.g. https://generativelanguage.googleapis.com/v1beta";
24
+ default:
25
+ return undefined;
26
+ }
27
+ }
28
+ /** Shared baseUrl validation for provider-level and model-level entries; returns an error or undefined. */
29
+ export function validateBaseUrlValue(value) {
30
+ let url;
31
+ try {
32
+ url = new URL(value);
33
+ }
34
+ catch {
35
+ return "baseUrl must be a valid URL.";
36
+ }
37
+ if (url.protocol !== "http:" && url.protocol !== "https:") {
38
+ return `Unsupported protocol: ${url.protocol}`;
39
+ }
40
+ if (url.username || url.password || url.hash) {
41
+ return "baseUrl must not contain credentials or a fragment.";
42
+ }
43
+ return undefined;
44
+ }
45
+ /**
46
+ * The provider's connection page: baseUrl and apiKey edit in place, while
47
+ * API Type pushes the single-select sub-page. Credential-source notes and
48
+ * the per-API baseUrl hint stay pinned below the rows.
49
+ */
50
+ export class ApiAuthPane {
51
+ constructor(host, registry) {
52
+ this.rows = ["baseUrl", "apiKey", "apiType"];
53
+ this.index = 0;
54
+ this.focused = false;
55
+ this.host = host;
56
+ this.registry = registry;
57
+ }
58
+ provider() {
59
+ return this.host.store.getProvider(this.host.providerId);
60
+ }
61
+ scrollWindow() {
62
+ // The value rows scroll; the credential-source notes stay pinned below.
63
+ return { cursor: this.index, bottom: this.bottomNoteCount() };
64
+ }
65
+ bottomNoteCount() {
66
+ const status = this.registry.getProviderAuthStatus(this.host.providerId);
67
+ const hint = baseUrlHint(this.provider()?.api);
68
+ return (this.error ? 1 : 0) + (status.configured ? 1 : 0) + 1 + (hint ? 1 : 0);
69
+ }
70
+ render(width) {
71
+ const theme = this.host.theme;
72
+ const provider = this.provider();
73
+ const lines = [];
74
+ for (const [rowIndex, row] of this.rows.entries()) {
75
+ const active = rowIndex === this.index;
76
+ if (row === "baseUrl") {
77
+ const value = provider?.baseUrl;
78
+ lines.push(renderKeyValueLine(theme, {
79
+ keyLabel: "baseUrl",
80
+ valueText: value ?? "not set",
81
+ unset: !value,
82
+ active,
83
+ paneFocused: this.focused,
84
+ editing: this.editingRow === "baseUrl" ? this.editing : undefined,
85
+ width,
86
+ }));
87
+ }
88
+ else if (row === "apiKey") {
89
+ const value = provider?.apiKey;
90
+ lines.push(renderKeyValueLine(theme, {
91
+ keyLabel: "apiKey",
92
+ valueText: value ? maskApiKey(value) : "not set",
93
+ unset: !value,
94
+ active,
95
+ paneFocused: this.focused,
96
+ editing: this.editingRow === "apiKey" ? this.editing : undefined,
97
+ width,
98
+ }));
99
+ }
100
+ else {
101
+ const value = provider?.api;
102
+ lines.push(renderKeyValueLine(theme, {
103
+ keyLabel: "API Type",
104
+ valueText: value ?? "not set",
105
+ unset: !value,
106
+ active,
107
+ paneFocused: this.focused,
108
+ width,
109
+ }));
110
+ }
111
+ }
112
+ if (this.error)
113
+ lines.push(theme.fg("error", truncate(this.error, Math.max(10, width - 2))));
114
+ const status = this.registry.getProviderAuthStatus(this.host.providerId);
115
+ if (status.configured && status.source === "stored") {
116
+ lines.push(renderInfoLine(theme, "A stored credential (auth.json) takes precedence over the apiKey here.", width));
117
+ }
118
+ else if (status.configured && status.source === "environment") {
119
+ lines.push(renderInfoLine(theme, `An environment variable (${status.label ?? "env"}) currently provides the key.`, width));
120
+ }
121
+ lines.push(renderInfoLine(theme, "Values are stored raw; $VAR / !command references resolve at request time.", width));
122
+ const hint = baseUrlHint(provider?.api);
123
+ if (hint)
124
+ lines.push(renderInfoLine(theme, hint, width));
125
+ return lines;
126
+ }
127
+ handleInput(data) {
128
+ const kb = this.host.keybindings;
129
+ if (this.editing) {
130
+ if (kb.matches(data, "tui.select.up") || kb.matches(data, "tui.select.down"))
131
+ return; // stay while editing
132
+ this.editing.handleInput(data);
133
+ this.host.refresh();
134
+ return;
135
+ }
136
+ if (kb.matches(data, "tui.select.up")) {
137
+ this.index = this.index === 0 ? this.rows.length - 1 : this.index - 1;
138
+ this.host.refresh();
139
+ return;
140
+ }
141
+ if (kb.matches(data, "tui.select.down")) {
142
+ this.index = (this.index + 1) % this.rows.length;
143
+ this.host.refresh();
144
+ return;
145
+ }
146
+ if (kb.matches(data, "tui.select.cancel")) {
147
+ this.host.popPane();
148
+ return;
149
+ }
150
+ if (kb.matches(data, "tui.select.confirm")) {
151
+ const row = this.rows[this.index];
152
+ if (row === "apiType")
153
+ this.host.pushPane(new ApiTypePane(this.host));
154
+ else
155
+ this.beginEdit("tweak");
156
+ return;
157
+ }
158
+ if (isPrintableInput(data)) {
159
+ const row = this.rows[this.index];
160
+ if (row === "apiType")
161
+ return;
162
+ this.beginEdit("overwrite", data);
163
+ return;
164
+ }
165
+ }
166
+ beginEdit(mode, firstData) {
167
+ const row = this.rows[this.index];
168
+ if (row !== "baseUrl" && row !== "apiKey")
169
+ return;
170
+ const current = row === "baseUrl" ? (this.provider()?.baseUrl ?? "") : (this.provider()?.apiKey ?? "");
171
+ const editor = new ValueEditor({
172
+ onCommit: (value) => this.commit(row, value),
173
+ onCancel: () => {
174
+ this.editing = undefined;
175
+ this.editingRow = undefined;
176
+ this.error = undefined;
177
+ this.host.refresh();
178
+ },
179
+ });
180
+ this.editing = editor;
181
+ this.editingRow = row;
182
+ editor.focused = this.focused;
183
+ if (mode === "overwrite")
184
+ editor.beginOverwrite(firstData);
185
+ else
186
+ editor.beginTweak(current);
187
+ this.host.refresh();
188
+ }
189
+ commit(row, raw) {
190
+ const value = raw.trim();
191
+ if (row === "baseUrl" && value) {
192
+ const invalid = validateBaseUrlValue(value);
193
+ if (invalid) {
194
+ this.error = invalid;
195
+ this.host.refresh();
196
+ return;
197
+ }
198
+ }
199
+ if (row === "baseUrl" && !value) {
200
+ // Removing baseUrl is only allowed while models still resolve an address.
201
+ const builtin = builtinDefaults(this.host.providerId).baseUrl !== undefined;
202
+ const modelsCovered = this.host.store
203
+ .getModels(this.host.providerId)
204
+ .every((model) => model.baseUrl !== undefined);
205
+ if (!builtin && !modelsCovered && this.host.store.getModels(this.host.providerId).length > 0) {
206
+ this.error = "baseUrl cannot be removed while models rely on it.";
207
+ this.host.refresh();
208
+ return;
209
+ }
210
+ }
211
+ this.error = undefined;
212
+ this.editing = undefined;
213
+ this.editingRow = undefined;
214
+ this.host.mutate(() => this.host.store.setProviderField(this.host.providerId, [row], value === "" ? DELETE : value));
215
+ }
216
+ setFocused(focused) {
217
+ this.focused = focused;
218
+ if (this.editing)
219
+ this.editing.focused = focused;
220
+ }
221
+ isEditing() {
222
+ return this.editing !== undefined;
223
+ }
224
+ hints() {
225
+ if (this.editing) {
226
+ return [keyHint("tui.input.submit", "save"), keyHint("tui.select.cancel", "cancel")].join(" ");
227
+ }
228
+ return [
229
+ rawKeyHint("type", "overwrite"),
230
+ keyHint("tui.select.confirm", "edit / open"),
231
+ keyHint("tui.select.cancel", "back"),
232
+ ].join(" ");
233
+ }
234
+ }
235
+ /**
236
+ * Single-select provider api sub-page of API Auth; Enter applies and
237
+ * returns. Clearing is refused while any model still resolves its api from
238
+ * the provider — set a model-level API under Model-Specific API first.
239
+ */
240
+ export class ApiTypePane {
241
+ constructor(host) {
242
+ this.crumb = "API Type";
243
+ this.index = 0;
244
+ this.focused = false;
245
+ this.host = host;
246
+ const current = this.host.store.getProvider(this.host.providerId)?.api;
247
+ const options = this.options();
248
+ this.index = Math.max(0, options.indexOf(current));
249
+ }
250
+ /** undefined first = not set; a custom api already stored is preserved and appended. */
251
+ options() {
252
+ const current = this.host.store.getProvider(this.host.providerId)?.api;
253
+ const base = [undefined, ...API_TYPES];
254
+ if (current && !API_TYPES.includes(current))
255
+ base.push(current);
256
+ return base;
257
+ }
258
+ unsetLabel() {
259
+ const fallback = builtinDefaults(this.host.providerId).api;
260
+ return fallback ? `not set (built-in default: ${fallback})` : "not set (models define their own)";
261
+ }
262
+ render(width) {
263
+ const theme = this.host.theme;
264
+ const current = this.host.store.getProvider(this.host.providerId)?.api;
265
+ const lines = this.options().map((option, rowIndex) => {
266
+ const active = rowIndex === this.index;
267
+ const selected = option === current;
268
+ const label = `${selected ? "●" : "○"} ${option ?? this.unsetLabel()}`;
269
+ return renderPlainLine(theme, label, { active, paneFocused: this.focused, dim: option === undefined, width });
270
+ });
271
+ if (this.error)
272
+ lines.push(renderInfoLine(theme, this.error, width));
273
+ return lines;
274
+ }
275
+ scrollWindow() {
276
+ return { cursor: this.index, bottom: this.error ? 1 : 0 };
277
+ }
278
+ handleInput(data) {
279
+ const kb = this.host.keybindings;
280
+ const options = this.options();
281
+ if (kb.matches(data, "tui.select.up")) {
282
+ this.index = this.index === 0 ? options.length - 1 : this.index - 1;
283
+ this.host.refresh();
284
+ return;
285
+ }
286
+ if (kb.matches(data, "tui.select.down")) {
287
+ this.index = (this.index + 1) % options.length;
288
+ this.host.refresh();
289
+ return;
290
+ }
291
+ if (kb.matches(data, "tui.select.cancel")) {
292
+ this.host.popPane();
293
+ return;
294
+ }
295
+ if (kb.matches(data, "tui.select.confirm") || kb.matches(data, "app.list.toggle")) {
296
+ const option = options[this.index];
297
+ if (option === undefined) {
298
+ const uncovered = this.host.store
299
+ .getModels(this.host.providerId)
300
+ .filter((model) => !model.api && !builtinDefaults(this.host.providerId, model.id).api);
301
+ if (uncovered.length > 0) {
302
+ this.error =
303
+ uncovered.length === 1
304
+ ? `Model "${uncovered[0].id}" resolves its API from here — give it a model-level API first.`
305
+ : `${uncovered.length} ${plural(uncovered.length, "model")} resolve their API from here — give them model-level APIs first.`;
306
+ this.host.refresh();
307
+ return;
308
+ }
309
+ }
310
+ this.error = undefined;
311
+ this.host.mutate(() => this.host.store.setProviderField(this.host.providerId, ["api"], option ?? DELETE));
312
+ this.host.popPane();
313
+ }
314
+ }
315
+ setFocused(focused) {
316
+ this.focused = focused;
317
+ }
318
+ hints() {
319
+ return [
320
+ rawKeyHint("↑↓", "move"),
321
+ keyHint("tui.select.confirm", "select"),
322
+ keyHint("tui.select.cancel", "back"),
323
+ ].join(" ");
324
+ }
325
+ }
326
+ //# sourceMappingURL=provider-fields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-fields.js","sourceRoot":"","sources":["../../../../src/extensions/provider/ui/provider-fields.ts"],"names":[],"mappings":"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","sourcesContent":["/** Provider connection and API settings panes. */\n\nimport type { ModelsJsonProvider } from \"../../../core/model-config.ts\";\nimport type { ModelRegistry } from \"../../../core/model-registry.ts\";\nimport { keyHint, rawKeyHint } from \"../../../modes/interactive/components/keybinding-hints.ts\";\nimport { builtinDefaults } from \"../catalog.ts\";\nimport { API_TYPES, maskApiKey, plural, truncate } from \"../constants.ts\";\nimport { DELETE } from \"../store.ts\";\nimport type { EditorHost, EditorPane } from \"./pane.ts\";\nimport {\n\tisPrintableInput,\n\trenderInfoLine,\n\trenderKeyValueLine,\n\trenderPlainLine,\n\ttype ScrollWindowInfo,\n\tValueEditor,\n} from \"./value-row.ts\";\n\n/**\n * One-line guidance on the baseUrl shape an API tag expects: pi-ai delegates\n * URL assembly to the vendor SDKs, so OpenAI-style tags need the version path\n * in baseUrl while the Anthropic and Mistral clients append it themselves.\n */\nexport function baseUrlHint(api: string | undefined): string | undefined {\n\tswitch (api) {\n\t\tcase \"openai-responses\":\n\t\tcase \"openai-completions\":\n\t\tcase \"openai-codex-responses\":\n\t\t\treturn \"baseUrl includes the version path, e.g. https://api.openai.com/v1\";\n\t\tcase \"anthropic-messages\":\n\t\t\treturn \"baseUrl is the bare origin — /v1/messages is added automatically\";\n\t\tcase \"mistral-conversations\":\n\t\t\treturn \"baseUrl is the bare origin — /v1 is added automatically\";\n\t\tcase \"google-generative-ai\":\n\t\t\treturn \"baseUrl includes the version path, e.g. https://generativelanguage.googleapis.com/v1beta\";\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\n/** Shared baseUrl validation for provider-level and model-level entries; returns an error or undefined. */\nexport function validateBaseUrlValue(value: string): string | undefined {\n\tlet url: URL;\n\ttry {\n\t\turl = new URL(value);\n\t} catch {\n\t\treturn \"baseUrl must be a valid URL.\";\n\t}\n\tif (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n\t\treturn `Unsupported protocol: ${url.protocol}`;\n\t}\n\tif (url.username || url.password || url.hash) {\n\t\treturn \"baseUrl must not contain credentials or a fragment.\";\n\t}\n\treturn undefined;\n}\n\n/**\n * The provider's connection page: baseUrl and apiKey edit in place, while\n * API Type pushes the single-select sub-page. Credential-source notes and\n * the per-API baseUrl hint stay pinned below the rows.\n */\nexport class ApiAuthPane implements EditorPane {\n\tprivate readonly rows = [\"baseUrl\", \"apiKey\", \"apiType\"] as const;\n\tprivate index = 0;\n\tprivate editing: ValueEditor | undefined;\n\tprivate editingRow: \"baseUrl\" | \"apiKey\" | undefined;\n\tprivate error: string | undefined;\n\tprivate focused = false;\n\n\tprivate readonly host: EditorHost;\n\tprivate readonly registry: Pick<ModelRegistry, \"getProviderAuthStatus\">;\n\tconstructor(host: EditorHost, registry: Pick<ModelRegistry, \"getProviderAuthStatus\">) {\n\t\tthis.host = host;\n\t\tthis.registry = registry;\n\t}\n\n\tprivate provider(): ModelsJsonProvider | undefined {\n\t\treturn this.host.store.getProvider(this.host.providerId);\n\t}\n\n\tscrollWindow(): ScrollWindowInfo {\n\t\t// The value rows scroll; the credential-source notes stay pinned below.\n\t\treturn { cursor: this.index, bottom: this.bottomNoteCount() };\n\t}\n\n\tprivate bottomNoteCount(): number {\n\t\tconst status = this.registry.getProviderAuthStatus(this.host.providerId);\n\t\tconst hint = baseUrlHint(this.provider()?.api);\n\t\treturn (this.error ? 1 : 0) + (status.configured ? 1 : 0) + 1 + (hint ? 1 : 0);\n\t}\n\n\trender(width: number): string[] {\n\t\tconst theme = this.host.theme;\n\t\tconst provider = this.provider();\n\t\tconst lines: string[] = [];\n\t\tfor (const [rowIndex, row] of this.rows.entries()) {\n\t\t\tconst active = rowIndex === this.index;\n\t\t\tif (row === \"baseUrl\") {\n\t\t\t\tconst value = provider?.baseUrl;\n\t\t\t\tlines.push(\n\t\t\t\t\trenderKeyValueLine(theme, {\n\t\t\t\t\t\tkeyLabel: \"baseUrl\",\n\t\t\t\t\t\tvalueText: value ?? \"not set\",\n\t\t\t\t\t\tunset: !value,\n\t\t\t\t\t\tactive,\n\t\t\t\t\t\tpaneFocused: this.focused,\n\t\t\t\t\t\tediting: this.editingRow === \"baseUrl\" ? this.editing : undefined,\n\t\t\t\t\t\twidth,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t} else if (row === \"apiKey\") {\n\t\t\t\tconst value = provider?.apiKey;\n\t\t\t\tlines.push(\n\t\t\t\t\trenderKeyValueLine(theme, {\n\t\t\t\t\t\tkeyLabel: \"apiKey\",\n\t\t\t\t\t\tvalueText: value ? maskApiKey(value) : \"not set\",\n\t\t\t\t\t\tunset: !value,\n\t\t\t\t\t\tactive,\n\t\t\t\t\t\tpaneFocused: this.focused,\n\t\t\t\t\t\tediting: this.editingRow === \"apiKey\" ? this.editing : undefined,\n\t\t\t\t\t\twidth,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconst value = provider?.api;\n\t\t\t\tlines.push(\n\t\t\t\t\trenderKeyValueLine(theme, {\n\t\t\t\t\t\tkeyLabel: \"API Type\",\n\t\t\t\t\t\tvalueText: value ?? \"not set\",\n\t\t\t\t\t\tunset: !value,\n\t\t\t\t\t\tactive,\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}\n\t\tif (this.error) lines.push(theme.fg(\"error\", truncate(this.error, Math.max(10, width - 2))));\n\t\tconst status = this.registry.getProviderAuthStatus(this.host.providerId);\n\t\tif (status.configured && status.source === \"stored\") {\n\t\t\tlines.push(\n\t\t\t\trenderInfoLine(theme, \"A stored credential (auth.json) takes precedence over the apiKey here.\", width),\n\t\t\t);\n\t\t} else if (status.configured && status.source === \"environment\") {\n\t\t\tlines.push(\n\t\t\t\trenderInfoLine(\n\t\t\t\t\ttheme,\n\t\t\t\t\t`An environment variable (${status.label ?? \"env\"}) currently provides the key.`,\n\t\t\t\t\twidth,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tlines.push(\n\t\t\trenderInfoLine(theme, \"Values are stored raw; $VAR / !command references resolve at request time.\", width),\n\t\t);\n\t\tconst hint = baseUrlHint(provider?.api);\n\t\tif (hint) lines.push(renderInfoLine(theme, hint, width));\n\t\treturn lines;\n\t}\n\n\thandleInput(data: string): void {\n\t\tconst kb = this.host.keybindings;\n\t\tif (this.editing) {\n\t\t\tif (kb.matches(data, \"tui.select.up\") || kb.matches(data, \"tui.select.down\")) return; // stay while editing\n\t\t\tthis.editing.handleInput(data);\n\t\t\tthis.host.refresh();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.up\")) {\n\t\t\tthis.index = this.index === 0 ? this.rows.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) % this.rows.length;\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\tif (kb.matches(data, \"tui.select.confirm\")) {\n\t\t\tconst row = this.rows[this.index]!;\n\t\t\tif (row === \"apiType\") this.host.pushPane(new ApiTypePane(this.host));\n\t\t\telse this.beginEdit(\"tweak\");\n\t\t\treturn;\n\t\t}\n\t\tif (isPrintableInput(data)) {\n\t\t\tconst row = this.rows[this.index]!;\n\t\t\tif (row === \"apiType\") return;\n\t\t\tthis.beginEdit(\"overwrite\", data);\n\t\t\treturn;\n\t\t}\n\t}\n\n\tprivate beginEdit(mode: \"overwrite\" | \"tweak\", firstData?: string): void {\n\t\tconst row = this.rows[this.index]!;\n\t\tif (row !== \"baseUrl\" && row !== \"apiKey\") return;\n\t\tconst current = row === \"baseUrl\" ? (this.provider()?.baseUrl ?? \"\") : (this.provider()?.apiKey ?? \"\");\n\t\tconst editor = new ValueEditor({\n\t\t\tonCommit: (value) => this.commit(row, value),\n\t\t\tonCancel: () => {\n\t\t\t\tthis.editing = undefined;\n\t\t\t\tthis.editingRow = undefined;\n\t\t\t\tthis.error = undefined;\n\t\t\t\tthis.host.refresh();\n\t\t\t},\n\t\t});\n\t\tthis.editing = editor;\n\t\tthis.editingRow = row;\n\t\teditor.focused = this.focused;\n\t\tif (mode === \"overwrite\") editor.beginOverwrite(firstData);\n\t\telse editor.beginTweak(current);\n\t\tthis.host.refresh();\n\t}\n\n\tprivate commit(row: \"baseUrl\" | \"apiKey\", raw: string): void {\n\t\tconst value = raw.trim();\n\t\tif (row === \"baseUrl\" && value) {\n\t\t\tconst invalid = validateBaseUrlValue(value);\n\t\t\tif (invalid) {\n\t\t\t\tthis.error = invalid;\n\t\t\t\tthis.host.refresh();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tif (row === \"baseUrl\" && !value) {\n\t\t\t// Removing baseUrl is only allowed while models still resolve an address.\n\t\t\tconst builtin = builtinDefaults(this.host.providerId).baseUrl !== undefined;\n\t\t\tconst modelsCovered = this.host.store\n\t\t\t\t.getModels(this.host.providerId)\n\t\t\t\t.every((model) => model.baseUrl !== undefined);\n\t\t\tif (!builtin && !modelsCovered && this.host.store.getModels(this.host.providerId).length > 0) {\n\t\t\t\tthis.error = \"baseUrl cannot be removed while models rely on it.\";\n\t\t\t\tthis.host.refresh();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tthis.error = undefined;\n\t\tthis.editing = undefined;\n\t\tthis.editingRow = undefined;\n\t\tthis.host.mutate(() =>\n\t\t\tthis.host.store.setProviderField(this.host.providerId, [row], value === \"\" ? DELETE : value),\n\t\t);\n\t}\n\n\tsetFocused(focused: boolean): void {\n\t\tthis.focused = focused;\n\t\tif (this.editing) this.editing.focused = focused;\n\t}\n\n\tisEditing(): boolean {\n\t\treturn this.editing !== undefined;\n\t}\n\n\thints(): string {\n\t\tif (this.editing) {\n\t\t\treturn [keyHint(\"tui.input.submit\", \"save\"), keyHint(\"tui.select.cancel\", \"cancel\")].join(\" \");\n\t\t}\n\t\treturn [\n\t\t\trawKeyHint(\"type\", \"overwrite\"),\n\t\t\tkeyHint(\"tui.select.confirm\", \"edit / open\"),\n\t\t\tkeyHint(\"tui.select.cancel\", \"back\"),\n\t\t].join(\" \");\n\t}\n}\n\n/**\n * Single-select provider api sub-page of API Auth; Enter applies and\n * returns. Clearing is refused while any model still resolves its api from\n * the provider — set a model-level API under Model-Specific API first.\n */\nexport class ApiTypePane implements EditorPane {\n\treadonly crumb = \"API Type\";\n\tprivate index = 0;\n\tprivate focused = false;\n\tprivate error: string | undefined;\n\n\tprivate readonly host: EditorHost;\n\tconstructor(host: EditorHost) {\n\t\tthis.host = host;\n\n\t\tconst current = this.host.store.getProvider(this.host.providerId)?.api;\n\t\tconst options = this.options();\n\t\tthis.index = Math.max(0, options.indexOf(current));\n\t}\n\n\t/** undefined first = not set; a custom api already stored is preserved and appended. */\n\tprivate options(): (string | undefined)[] {\n\t\tconst current = this.host.store.getProvider(this.host.providerId)?.api;\n\t\tconst base: (string | undefined)[] = [undefined, ...API_TYPES];\n\t\tif (current && !(API_TYPES as readonly string[]).includes(current)) base.push(current);\n\t\treturn base;\n\t}\n\n\tprivate unsetLabel(): string {\n\t\tconst fallback = builtinDefaults(this.host.providerId).api;\n\t\treturn fallback ? `not set (built-in default: ${fallback})` : \"not set (models define their own)\";\n\t}\n\n\trender(width: number): string[] {\n\t\tconst theme = this.host.theme;\n\t\tconst current = this.host.store.getProvider(this.host.providerId)?.api;\n\t\tconst lines = this.options().map((option, rowIndex) => {\n\t\t\tconst active = rowIndex === this.index;\n\t\t\tconst selected = option === current;\n\t\t\tconst label = `${selected ? \"●\" : \"○\"} ${option ?? this.unsetLabel()}`;\n\t\t\treturn renderPlainLine(theme, label, { active, paneFocused: this.focused, dim: option === undefined, width });\n\t\t});\n\t\tif (this.error) lines.push(renderInfoLine(theme, this.error, width));\n\t\treturn lines;\n\t}\n\n\tscrollWindow(): ScrollWindowInfo {\n\t\treturn { cursor: this.index, bottom: this.error ? 1 : 0 };\n\t}\n\n\thandleInput(data: string): void {\n\t\tconst kb = this.host.keybindings;\n\t\tconst options = this.options();\n\t\tif (kb.matches(data, \"tui.select.up\")) {\n\t\t\tthis.index = this.index === 0 ? options.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) % options.length;\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\tif (kb.matches(data, \"tui.select.confirm\") || kb.matches(data, \"app.list.toggle\")) {\n\t\t\tconst option = options[this.index];\n\t\t\tif (option === undefined) {\n\t\t\t\tconst uncovered = this.host.store\n\t\t\t\t\t.getModels(this.host.providerId)\n\t\t\t\t\t.filter((model) => !model.api && !builtinDefaults(this.host.providerId, model.id).api);\n\t\t\t\tif (uncovered.length > 0) {\n\t\t\t\t\tthis.error =\n\t\t\t\t\t\tuncovered.length === 1\n\t\t\t\t\t\t\t? `Model \"${uncovered[0]!.id}\" resolves its API from here — give it a model-level API first.`\n\t\t\t\t\t\t\t: `${uncovered.length} ${plural(uncovered.length, \"model\")} resolve their API from here — give them model-level APIs first.`;\n\t\t\t\t\tthis.host.refresh();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.error = undefined;\n\t\t\tthis.host.mutate(() => this.host.store.setProviderField(this.host.providerId, [\"api\"], option ?? DELETE));\n\t\t\tthis.host.popPane();\n\t\t}\n\t}\n\n\tsetFocused(focused: boolean): void {\n\t\tthis.focused = focused;\n\t}\n\n\thints(): string {\n\t\treturn [\n\t\t\trawKeyHint(\"↑↓\", \"move\"),\n\t\t\tkeyHint(\"tui.select.confirm\", \"select\"),\n\t\t\tkeyHint(\"tui.select.cancel\", \"back\"),\n\t\t].join(\" \");\n\t}\n}\n"]}
@@ -0,0 +1,34 @@
1
+ /** Searchable provider list and new-provider id entry. */
2
+ import { type Component, type Focusable, type TUI } from "@earendil-works/pi-tui";
3
+ import type { KeybindingsManager } from "../../../core/keybindings.ts";
4
+ import type { Theme } from "../../../modes/interactive/theme/theme.ts";
5
+ import type { ModelsJsonStore } from "../store.ts";
6
+ export type ProviderListResult = {
7
+ kind: "open";
8
+ providerId: string;
9
+ } | {
10
+ kind: "close";
11
+ };
12
+ export declare class ProviderListScreen implements Component, Focusable {
13
+ private readonly input;
14
+ private readonly store;
15
+ private readonly tui;
16
+ private readonly theme;
17
+ private readonly keybindings;
18
+ private readonly done;
19
+ private mode;
20
+ private query;
21
+ private index;
22
+ private error;
23
+ private active;
24
+ constructor(tui: TUI, theme: Theme, keybindings: KeybindingsManager, done: (result: ProviderListResult) => void, store: ModelsJsonStore);
25
+ get focused(): boolean;
26
+ set focused(value: boolean);
27
+ invalidate(): void;
28
+ private filtered;
29
+ render(width: number): string[];
30
+ handleInput(data: string): void;
31
+ private confirm;
32
+ private cancel;
33
+ }
34
+ //# sourceMappingURL=provider-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-list.d.ts","sourceRoot":"","sources":["../../../../src/extensions/provider/ui/provider-list.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAE1D,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAe,KAAK,GAAG,EAAmB,MAAM,wBAAwB,CAAC;AAChH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAGvE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAC;AAEvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAKnD,MAAM,MAAM,kBAAkB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAE1F,qBAAa,kBAAmB,YAAW,SAAS,EAAE,SAAS;IAC9D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkB;IACxC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAuC;IAC5D,OAAO,CAAC,IAAI,CAAkC;IAC9C,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,MAAM,CAAS;gBAGtB,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,kBAAkB,EAC/B,IAAI,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,EAC1C,KAAK,EAAE,eAAe;IAUvB,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAGzB;IACD,UAAU,IAAI,IAAI;IAElB,OAAO,CAAC,QAAQ;IAKhB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAkE/B,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAuB/B,OAAO,CAAC,OAAO;IAsBf,OAAO,CAAC,MAAM;CAUd"}