@astralyn/pi 1.4.2 → 1.4.4
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.
- package/CHANGELOG.md +18 -0
- package/dist/bundle/chunks/{chunk-FGPSYHTQ.js → chunk-SBVVM3NV.js} +117 -117
- package/dist/bundle/chunks/{chunk-HXKY52DF.js → chunk-VGSZTBVJ.js} +1 -1
- package/dist/bundle/chunks/{virtual-modules-5NSVVTKO.js → virtual-modules-ETYFHSUG.js} +1 -1
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/core/agent-session.d.ts +15 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +1 -8
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/distribution-api.d.ts +1 -1
- package/dist/core/extensions/distribution-api.d.ts.map +1 -1
- package/dist/core/extensions/distribution-api.js.map +1 -1
- package/dist/core/extensions/index.d.ts +2 -2
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +4 -2
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +14 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/keybinding-registry.d.ts +16 -1
- package/dist/core/keybinding-registry.d.ts.map +1 -1
- package/dist/core/keybinding-registry.js +20 -0
- package/dist/core/keybinding-registry.js.map +1 -1
- package/dist/core/keybindings-schema.d.ts.map +1 -1
- package/dist/core/keybindings-schema.js +2 -1
- package/dist/core/keybindings-schema.js.map +1 -1
- package/dist/core/keybindings.d.ts +4 -106
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +0 -13
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +0 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/tasks/format.d.ts.map +1 -1
- package/dist/core/tasks/format.js +10 -4
- package/dist/core/tasks/format.js.map +1 -1
- package/dist/core/tasks/limits.d.ts +5 -0
- package/dist/core/tasks/limits.d.ts.map +1 -0
- package/dist/core/tasks/limits.js +5 -0
- package/dist/core/tasks/limits.js.map +1 -0
- package/dist/core/tasks/runtime.d.ts +1 -0
- package/dist/core/tasks/runtime.d.ts.map +1 -1
- package/dist/core/tasks/runtime.js +7 -3
- package/dist/core/tasks/runtime.js.map +1 -1
- package/dist/core/tasks/session.d.ts +1 -1
- package/dist/core/tasks/session.d.ts.map +1 -1
- package/dist/core/tasks/session.js +10 -2
- package/dist/core/tasks/session.js.map +1 -1
- package/dist/core/tasks/types.d.ts +13 -0
- package/dist/core/tasks/types.d.ts.map +1 -1
- package/dist/core/tasks/types.js.map +1 -1
- package/dist/core/tools/bash.d.ts +98 -9
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +308 -11
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/index.d.ts +5 -4
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +3 -11
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/powershell.d.ts +2 -1
- package/dist/core/tools/powershell.d.ts.map +1 -1
- package/dist/core/tools/powershell.js +2 -1
- package/dist/core/tools/powershell.js.map +1 -1
- package/dist/core/tools/renderers/bash.d.ts +1 -1
- package/dist/core/tools/renderers/bash.d.ts.map +1 -1
- package/dist/core/tools/renderers/bash.js.map +1 -1
- package/dist/core/tools/renderers/index.d.ts.map +1 -1
- package/dist/core/tools/renderers/index.js +7 -5
- package/dist/core/tools/renderers/index.js.map +1 -1
- package/dist/core/tools/shell-execution.d.ts +2 -2
- package/dist/core/tools/shell-execution.d.ts.map +1 -1
- package/dist/core/tools/shell-execution.js +0 -21
- package/dist/core/tools/shell-execution.js.map +1 -1
- package/dist/core/tools/shell-operations.d.ts +12 -0
- package/dist/core/tools/shell-operations.d.ts.map +1 -0
- package/dist/core/tools/shell-operations.js +38 -0
- package/dist/core/tools/shell-operations.js.map +1 -0
- package/dist/core/tools/shell-tool.d.ts +8 -64
- package/dist/core/tools/shell-tool.d.ts.map +1 -1
- package/dist/core/tools/shell-tool.js +27 -125
- package/dist/core/tools/shell-tool.js.map +1 -1
- package/dist/extensions/index.d.ts +1 -0
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/extensions/index.js +5 -0
- package/dist/extensions/index.js.map +1 -1
- package/dist/extensions/keybindings.d.ts +6 -0
- package/dist/extensions/keybindings.d.ts.map +1 -0
- package/dist/extensions/keybindings.js +6 -0
- package/dist/extensions/keybindings.js.map +1 -0
- package/dist/extensions/provider/store.d.ts +2 -0
- package/dist/extensions/provider/store.d.ts.map +1 -1
- package/dist/extensions/provider/store.js +4 -0
- package/dist/extensions/provider/store.js.map +1 -1
- package/dist/extensions/provider/ui/editor.d.ts +7 -9
- package/dist/extensions/provider/ui/editor.d.ts.map +1 -1
- package/dist/extensions/provider/ui/editor.js +103 -48
- package/dist/extensions/provider/ui/editor.js.map +1 -1
- package/dist/extensions/provider/ui/provider-list.d.ts.map +1 -1
- package/dist/extensions/provider/ui/provider-list.js +13 -19
- package/dist/extensions/provider/ui/provider-list.js.map +1 -1
- package/dist/extensions/run-summary/format.d.ts +2 -0
- package/dist/extensions/run-summary/format.d.ts.map +1 -0
- package/dist/extensions/run-summary/format.js +11 -0
- package/dist/extensions/run-summary/format.js.map +1 -0
- package/dist/extensions/run-summary/index.d.ts +4 -0
- package/dist/extensions/run-summary/index.d.ts.map +1 -0
- package/dist/extensions/run-summary/index.js +48 -0
- package/dist/extensions/run-summary/index.js.map +1 -0
- package/dist/extensions/run-summary/record.d.ts +11 -0
- package/dist/extensions/run-summary/record.d.ts.map +1 -0
- package/dist/extensions/run-summary/record.js +29 -0
- package/dist/extensions/run-summary/record.js.map +1 -0
- package/dist/extensions/tasks/index.d.ts +5 -0
- package/dist/extensions/tasks/index.d.ts.map +1 -0
- package/dist/extensions/tasks/index.js +42 -0
- package/dist/extensions/tasks/index.js.map +1 -0
- package/dist/extensions/tasks/keybindings.d.ts +19 -0
- package/dist/extensions/tasks/keybindings.d.ts.map +1 -0
- package/dist/extensions/tasks/keybindings.js +30 -0
- package/dist/extensions/tasks/keybindings.js.map +1 -0
- package/dist/{core/tools/tasks → extensions/tasks/tool}/actions.d.ts +2 -2
- package/dist/extensions/tasks/tool/actions.d.ts.map +1 -0
- package/dist/{core/tools/tasks → extensions/tasks/tool}/actions.js +4 -4
- package/dist/extensions/tasks/tool/actions.js.map +1 -0
- package/dist/{core/tools/tasks → extensions/tasks/tool}/constants.d.ts +1 -3
- package/dist/extensions/tasks/tool/constants.d.ts.map +1 -0
- package/dist/{core/tools/tasks → extensions/tasks/tool}/constants.js +1 -3
- package/dist/extensions/tasks/tool/constants.js.map +1 -0
- package/dist/extensions/tasks/tool/schema.d.ts.map +1 -0
- package/dist/{core/tools/tasks → extensions/tasks/tool}/schema.js +5 -4
- package/dist/extensions/tasks/tool/schema.js.map +1 -0
- package/dist/{core/tools/tasks → extensions/tasks/tool}/types.d.ts +1 -1
- package/dist/extensions/tasks/tool/types.d.ts.map +1 -0
- package/dist/extensions/tasks/tool/types.js.map +1 -0
- package/dist/extensions/tasks/tool.d.ts +6 -0
- package/dist/extensions/tasks/tool.d.ts.map +1 -0
- package/dist/{core/tools/tasks.js → extensions/tasks/tool.js} +6 -10
- package/dist/extensions/tasks/tool.js.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/completion-render.d.ts +1 -1
- package/dist/extensions/tasks/ui/completion-render.d.ts.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/completion-render.js +2 -2
- package/dist/extensions/tasks/ui/completion-render.js.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/index.d.ts +1 -1
- package/dist/extensions/tasks/ui/index.d.ts.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/index.js +4 -4
- package/dist/extensions/tasks/ui/index.js.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/inspector.d.ts +1 -1
- package/dist/extensions/tasks/ui/inspector.d.ts.map +1 -0
- package/dist/extensions/tasks/ui/inspector.js.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/layout.d.ts +1 -1
- package/dist/extensions/tasks/ui/layout.d.ts.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/layout.js +1 -1
- package/dist/extensions/tasks/ui/layout.js.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/list.d.ts +1 -1
- package/dist/extensions/tasks/ui/list.d.ts.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/list.js +1 -1
- package/dist/extensions/tasks/ui/list.js.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/manager.d.ts +2 -1
- package/dist/extensions/tasks/ui/manager.d.ts.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/manager.js +2 -1
- package/dist/extensions/tasks/ui/manager.js.map +1 -0
- package/dist/extensions/tasks/ui/model.d.ts.map +1 -0
- package/dist/extensions/tasks/ui/model.js.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/render.d.ts +3 -3
- package/dist/extensions/tasks/ui/render.d.ts.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/render.js +2 -2
- package/dist/extensions/tasks/ui/render.js.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/task-view.d.ts +1 -1
- package/dist/extensions/tasks/ui/task-view.d.ts.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/task-view.js +1 -1
- package/dist/extensions/tasks/ui/task-view.js.map +1 -0
- package/dist/extensions/tasks/ui/text.d.ts.map +1 -0
- package/dist/extensions/tasks/ui/text.js.map +1 -0
- package/dist/extensions/tasks/ui/tree.d.ts +7 -0
- package/dist/extensions/tasks/ui/tree.d.ts.map +1 -0
- package/dist/{modes/interactive/tasks/host-hooks.js → extensions/tasks/ui/tree.js} +1 -18
- package/dist/extensions/tasks/ui/tree.js.map +1 -0
- package/dist/extensions/tasks/ui/viewport.d.ts.map +1 -0
- package/dist/extensions/tasks/ui/viewport.js.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/views.d.ts +1 -1
- package/dist/extensions/tasks/ui/views.d.ts.map +1 -0
- package/dist/{modes/interactive/tasks → extensions/tasks/ui}/views.js +1 -1
- package/dist/extensions/tasks/ui/views.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +3 -2
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +65 -18
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +1 -3
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +16 -4
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +73 -33
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +3 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/docs/bundled/README.md +2 -4
- package/docs/bundled/extensions/provider.md +9 -7
- package/docs/bundled/extensions/run-summary.md +17 -0
- package/docs/bundled/tasks.md +3 -3
- package/docs/docs.json +4 -0
- package/docs/extensions.md +10 -3
- package/docs/settings.md +1 -1
- package/docs/tui.md +13 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/schemas/keybindings.schema.json +84 -52
- package/dist/core/tools/tasks/actions.d.ts.map +0 -1
- package/dist/core/tools/tasks/actions.js.map +0 -1
- package/dist/core/tools/tasks/constants.d.ts.map +0 -1
- package/dist/core/tools/tasks/constants.js.map +0 -1
- package/dist/core/tools/tasks/schema.d.ts.map +0 -1
- package/dist/core/tools/tasks/schema.js.map +0 -1
- package/dist/core/tools/tasks/types.d.ts.map +0 -1
- package/dist/core/tools/tasks/types.js.map +0 -1
- package/dist/core/tools/tasks.d.ts +0 -14
- package/dist/core/tools/tasks.d.ts.map +0 -1
- package/dist/core/tools/tasks.js.map +0 -1
- package/dist/modes/interactive/tasks/completion-render.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/completion-render.js.map +0 -1
- package/dist/modes/interactive/tasks/host-hooks.d.ts +0 -14
- package/dist/modes/interactive/tasks/host-hooks.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/host-hooks.js.map +0 -1
- package/dist/modes/interactive/tasks/index.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/index.js.map +0 -1
- package/dist/modes/interactive/tasks/inspector.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/inspector.js.map +0 -1
- package/dist/modes/interactive/tasks/layout.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/layout.js.map +0 -1
- package/dist/modes/interactive/tasks/list.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/list.js.map +0 -1
- package/dist/modes/interactive/tasks/manager.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/manager.js.map +0 -1
- package/dist/modes/interactive/tasks/model.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/model.js.map +0 -1
- package/dist/modes/interactive/tasks/render.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/render.js.map +0 -1
- package/dist/modes/interactive/tasks/task-view.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/task-view.js.map +0 -1
- package/dist/modes/interactive/tasks/text.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/text.js.map +0 -1
- package/dist/modes/interactive/tasks/viewport.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/viewport.js.map +0 -1
- package/dist/modes/interactive/tasks/views.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/views.js.map +0 -1
- /package/dist/{core/tools/tasks → extensions/tasks/tool}/schema.d.ts +0 -0
- /package/dist/{core/tools/tasks → extensions/tasks/tool}/types.js +0 -0
- /package/dist/{modes/interactive/tasks → extensions/tasks/ui}/inspector.js +0 -0
- /package/dist/{modes/interactive/tasks → extensions/tasks/ui}/model.d.ts +0 -0
- /package/dist/{modes/interactive/tasks → extensions/tasks/ui}/model.js +0 -0
- /package/dist/{modes/interactive/tasks → extensions/tasks/ui}/text.d.ts +0 -0
- /package/dist/{modes/interactive/tasks → extensions/tasks/ui}/text.js +0 -0
- /package/dist/{modes/interactive/tasks → extensions/tasks/ui}/viewport.d.ts +0 -0
- /package/dist/{modes/interactive/tasks → extensions/tasks/ui}/viewport.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../../src/extensions/provider/ui/editor.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../../src/extensions/provider/ui/editor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Two-pane provider editor.
|
|
3
3
|
*
|
|
4
|
-
* Left column
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* fixed window with a (n/N) position indicator instead of resizing, and the
|
|
10
|
-
* selected row stays accent in both panes while the unfocused pane's other
|
|
11
|
-
* rows dim back. Typing on a value row overwrites, Enter tweaks or enters,
|
|
12
|
-
* ←/→ switch panes, Esc cancels/pops/backs out.
|
|
4
|
+
* Left column groups connection, models, and management actions. The right
|
|
5
|
+
* column hosts the selected item's field pane and sub-pane stack. Both columns
|
|
6
|
+
* scroll inside a fixed-height frame; below the wide-layout threshold, only
|
|
7
|
+
* the focused column is shown. Typing on a value row overwrites, Enter tweaks
|
|
8
|
+
* or enters, ←/→ switch panes, and Esc cancels/pops/backs out.
|
|
13
9
|
*/
|
|
14
10
|
import "../keybindings.js";
|
|
15
11
|
import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
@@ -28,7 +24,8 @@ const LEFT_WIDTH_MIN = 16;
|
|
|
28
24
|
const LEFT_WIDTH_MAX = 40;
|
|
29
25
|
/** Fixed editor body height: both columns scroll inside it rather than resizing the frame. */
|
|
30
26
|
const BODY_ROWS = 14;
|
|
31
|
-
const
|
|
27
|
+
const DOUBLE_PANE_MIN_WIDTH = 72;
|
|
28
|
+
const MIN_WIDTH = 32;
|
|
32
29
|
function padTo(line, width) {
|
|
33
30
|
const missing = width - visibleWidth(line);
|
|
34
31
|
return missing > 0 ? line + " ".repeat(missing) : line;
|
|
@@ -40,6 +37,8 @@ function leftItemKey(item) {
|
|
|
40
37
|
switch (item.kind) {
|
|
41
38
|
case "model":
|
|
42
39
|
return `model:${item.modelId}`;
|
|
40
|
+
case "section":
|
|
41
|
+
return `section:${item.label}`;
|
|
43
42
|
default:
|
|
44
43
|
return item.kind;
|
|
45
44
|
}
|
|
@@ -60,6 +59,7 @@ export class ProviderEditorScreen {
|
|
|
60
59
|
this.edits = new ProviderEdits(options.store, options.providerId, options.refresher, () => this.refresh());
|
|
61
60
|
this.host = this.createHost();
|
|
62
61
|
this.rebuildLeftItems();
|
|
62
|
+
this.leftIndex = this.selectableIndex(0);
|
|
63
63
|
this.resetRightStack();
|
|
64
64
|
}
|
|
65
65
|
// ------------------------------------------------------------------
|
|
@@ -134,7 +134,10 @@ export class ProviderEditorScreen {
|
|
|
134
134
|
const selectedKey = leftItemKey(selected);
|
|
135
135
|
this.rebuildLeftItems();
|
|
136
136
|
const nextIndex = this.leftItems.findIndex((item) => leftItemKey(item) === selectedKey);
|
|
137
|
-
this.leftIndex =
|
|
137
|
+
this.leftIndex =
|
|
138
|
+
nextIndex >= 0
|
|
139
|
+
? nextIndex
|
|
140
|
+
: this.selectableIndex(Math.min(this.leftIndex, Math.max(0, this.leftItems.length - 1)));
|
|
138
141
|
// If the selected model vanished externally, rebuild the right column.
|
|
139
142
|
if (nextIndex < 0 && selected?.kind === "model") {
|
|
140
143
|
this.resetRightStack();
|
|
@@ -145,23 +148,28 @@ export class ProviderEditorScreen {
|
|
|
145
148
|
// Left column
|
|
146
149
|
// ------------------------------------------------------------------
|
|
147
150
|
rebuildLeftItems() {
|
|
148
|
-
const items = [
|
|
151
|
+
const items = [
|
|
152
|
+
{ kind: "section", label: "SETUP" },
|
|
153
|
+
{ kind: "apiAuth" },
|
|
154
|
+
{ kind: "fetch" },
|
|
155
|
+
{ kind: "section", label: "MODELS" },
|
|
156
|
+
];
|
|
149
157
|
for (const model of this.options.store.getModels(this.options.providerId)) {
|
|
150
158
|
items.push({ kind: "model", modelId: model.id });
|
|
151
159
|
}
|
|
152
160
|
if (this.draft)
|
|
153
161
|
items.push({ kind: "draft" });
|
|
154
|
-
items.push({ kind: "
|
|
162
|
+
items.push({ kind: "section", label: "MANAGE" }, { kind: "addModel" }, { kind: "deleteProvider" });
|
|
155
163
|
this.leftItems = items;
|
|
156
164
|
}
|
|
157
165
|
selectableIndex(start) {
|
|
158
|
-
const index = this.leftItems.findIndex((item, i) => i >= start && item.kind !== "
|
|
159
|
-
return index >= 0 ? index :
|
|
166
|
+
const index = this.leftItems.findIndex((item, i) => i >= start && item.kind !== "section");
|
|
167
|
+
return index >= 0 ? index : this.leftItems.findIndex((item) => item.kind !== "section");
|
|
160
168
|
}
|
|
161
169
|
moveLeft(delta) {
|
|
162
170
|
const selectable = this.leftItems
|
|
163
171
|
.map((item, index) => ({ item, index }))
|
|
164
|
-
.filter((entry) => entry.item.kind !== "
|
|
172
|
+
.filter((entry) => entry.item.kind !== "section");
|
|
165
173
|
if (selectable.length === 0)
|
|
166
174
|
return;
|
|
167
175
|
const position = selectable.findIndex((entry) => entry.index === this.leftIndex);
|
|
@@ -236,7 +244,7 @@ export class ProviderEditorScreen {
|
|
|
236
244
|
const builtin = isBuiltinProviderId(this.options.providerId);
|
|
237
245
|
this.host.confirm(`Delete provider "${this.options.providerId}" from models.json?` +
|
|
238
246
|
(builtin ? " The built-in catalog remains and its models may reappear." : "") +
|
|
239
|
-
" Stored credentials in auth.json are kept.", "Delete
|
|
247
|
+
" Stored credentials in auth.json are kept.", "Delete provider", () => {
|
|
240
248
|
this.edits.removeProvider();
|
|
241
249
|
this.done("deleted");
|
|
242
250
|
});
|
|
@@ -252,8 +260,8 @@ export class ProviderEditorScreen {
|
|
|
252
260
|
const rows = [];
|
|
253
261
|
const renderRow = (index) => {
|
|
254
262
|
const item = this.leftItems[index];
|
|
255
|
-
if (item.kind === "
|
|
256
|
-
return theme.fg("
|
|
263
|
+
if (item.kind === "section") {
|
|
264
|
+
return theme.fg("dim", item.label);
|
|
257
265
|
}
|
|
258
266
|
return this.renderLeftItem(item, index === this.leftIndex, focused, width);
|
|
259
267
|
};
|
|
@@ -267,7 +275,7 @@ export class ProviderEditorScreen {
|
|
|
267
275
|
const start = Math.max(0, Math.min(this.leftIndex - Math.floor(slots / 2), this.leftItems.length - slots));
|
|
268
276
|
for (let index = start; index < start + slots; index++)
|
|
269
277
|
rows.push(renderRow(index));
|
|
270
|
-
const selectable = this.leftItems.filter((item) => item.kind !== "
|
|
278
|
+
const selectable = this.leftItems.filter((item) => item.kind !== "section");
|
|
271
279
|
const position = selectable.indexOf(this.leftItems[this.leftIndex]);
|
|
272
280
|
rows.push(theme.fg("dim", ` (${position + 1}/${selectable.length})`));
|
|
273
281
|
}
|
|
@@ -298,10 +306,10 @@ export class ProviderEditorScreen {
|
|
|
298
306
|
break;
|
|
299
307
|
}
|
|
300
308
|
case "addModel":
|
|
301
|
-
text = "+ Add
|
|
309
|
+
text = "+ Add model";
|
|
302
310
|
break;
|
|
303
311
|
case "deleteProvider":
|
|
304
|
-
text = "Delete
|
|
312
|
+
text = "Delete provider";
|
|
305
313
|
break;
|
|
306
314
|
default:
|
|
307
315
|
text = "";
|
|
@@ -430,11 +438,11 @@ export class ProviderEditorScreen {
|
|
|
430
438
|
confirm: (message, actionLabel, action) => this.pushPane(new ConfirmPane(this.host, message, actionLabel, action)),
|
|
431
439
|
onModelRemoved: () => {
|
|
432
440
|
this.rebuildLeftItems();
|
|
433
|
-
// Land on the next row where the model was; walk back over
|
|
441
|
+
// Land on the next row where the model was; walk back over section labels.
|
|
434
442
|
this.leftIndex = Math.min(this.leftIndex, this.leftItems.length - 1);
|
|
435
|
-
while (this.leftIndex > 0 && this.leftItems[this.leftIndex]?.kind === "
|
|
443
|
+
while (this.leftIndex > 0 && this.leftItems[this.leftIndex]?.kind === "section")
|
|
436
444
|
this.leftIndex--;
|
|
437
|
-
if (this.leftItems[this.leftIndex]?.kind === "
|
|
445
|
+
if (this.leftItems[this.leftIndex]?.kind === "section")
|
|
438
446
|
this.leftIndex = this.selectableIndex(0);
|
|
439
447
|
this.focusPane = "left";
|
|
440
448
|
this.resetRightStack();
|
|
@@ -488,30 +496,66 @@ export class ProviderEditorScreen {
|
|
|
488
496
|
border,
|
|
489
497
|
];
|
|
490
498
|
}
|
|
491
|
-
const leftWidth = this.computeLeftWidth(width);
|
|
492
|
-
const rightWidth = width - leftWidth - 3;
|
|
493
|
-
const separator = theme.fg("border", " │ ");
|
|
494
499
|
const title = this.renderTitle(width);
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
const
|
|
504
|
-
const
|
|
505
|
-
body
|
|
500
|
+
let body;
|
|
501
|
+
if (width < DOUBLE_PANE_MIN_WIDTH) {
|
|
502
|
+
body = this.focusPane === "left" ? this.renderLeft(width) : this.renderRight(width);
|
|
503
|
+
}
|
|
504
|
+
else {
|
|
505
|
+
const leftWidth = this.computeLeftWidth(width);
|
|
506
|
+
const rightWidth = width - leftWidth - 3;
|
|
507
|
+
const separator = theme.fg("border", " │ ");
|
|
508
|
+
const leftLines = this.renderLeft(leftWidth);
|
|
509
|
+
const rightLines = this.renderRight(rightWidth);
|
|
510
|
+
body = [];
|
|
511
|
+
for (let row = 0; row < BODY_ROWS; row++) {
|
|
512
|
+
const left = padTo(truncateToWidth(leftLines[row] ?? "", leftWidth), leftWidth);
|
|
513
|
+
const right = truncateToWidth(rightLines[row] ?? "", rightWidth);
|
|
514
|
+
body.push(left + separator + right);
|
|
515
|
+
}
|
|
506
516
|
}
|
|
507
517
|
const footerLines = this.renderFooter(width);
|
|
508
518
|
return [border, title, border, ...body, border, ...footerLines, border];
|
|
509
519
|
}
|
|
520
|
+
renderRight(width) {
|
|
521
|
+
const pane = this.topPane();
|
|
522
|
+
const paneLines = pane ? windowLines(this.theme, pane.render(width), BODY_ROWS - 1, pane.scrollWindow?.()) : [];
|
|
523
|
+
return [this.renderPaneTitle(width), ...paneLines];
|
|
524
|
+
}
|
|
525
|
+
renderPaneTitle(width) {
|
|
526
|
+
const item = this.leftItems[this.leftIndex];
|
|
527
|
+
let base = "";
|
|
528
|
+
switch (item?.kind) {
|
|
529
|
+
case "apiAuth":
|
|
530
|
+
base = "Connection";
|
|
531
|
+
break;
|
|
532
|
+
case "fetch":
|
|
533
|
+
base = "Discover models";
|
|
534
|
+
break;
|
|
535
|
+
case "model": {
|
|
536
|
+
const model = this.options.store.getModel(this.options.providerId, item.modelId);
|
|
537
|
+
base = model ? modelDisplayName(model) : item.modelId;
|
|
538
|
+
break;
|
|
539
|
+
}
|
|
540
|
+
case "draft":
|
|
541
|
+
base = "New model";
|
|
542
|
+
break;
|
|
543
|
+
case "addModel":
|
|
544
|
+
base = "Add model";
|
|
545
|
+
break;
|
|
546
|
+
case "deleteProvider":
|
|
547
|
+
base = "Delete provider";
|
|
548
|
+
break;
|
|
549
|
+
}
|
|
550
|
+
const crumb = this.stack.length > 1 ? this.topPane()?.crumb : undefined;
|
|
551
|
+
const title = crumb ? [base, crumb].filter(Boolean).join(" / ") : base;
|
|
552
|
+
return truncateToWidth(this.theme.fg("text", this.theme.bold(title)), width);
|
|
553
|
+
}
|
|
510
554
|
/** Content-driven left width: fits the longest visible label, clamped to 16–40 and 45% of the terminal. */
|
|
511
555
|
computeLeftWidth(width) {
|
|
512
556
|
let longest = 12;
|
|
513
557
|
for (const item of this.leftItems) {
|
|
514
|
-
if (item.kind === "
|
|
558
|
+
if (item.kind === "section")
|
|
515
559
|
continue;
|
|
516
560
|
const { text, note } = this.leftItemContent(item);
|
|
517
561
|
const label = text + (note ? ` ${note}` : "");
|
|
@@ -522,17 +566,28 @@ export class ProviderEditorScreen {
|
|
|
522
566
|
}
|
|
523
567
|
renderTitle(width) {
|
|
524
568
|
const theme = this.theme;
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
569
|
+
const title = theme.fg("accent", theme.bold(` Providers / ${this.options.providerId}`));
|
|
570
|
+
const status = this.options.store.pendingCount === 0 ? "" : this.options.store.saveFailed ? "Save failed" : "Saving…";
|
|
571
|
+
if (!status)
|
|
572
|
+
return truncateToWidth(title, width);
|
|
573
|
+
const styledStatus = theme.fg(this.options.store.saveFailed ? "error" : "dim", status);
|
|
574
|
+
const statusWidth = visibleWidth(status);
|
|
575
|
+
if (statusWidth + 1 >= width)
|
|
576
|
+
return truncateToWidth(styledStatus, width);
|
|
577
|
+
const left = truncateToWidth(title, width - statusWidth - 1);
|
|
578
|
+
return padTo(left, width - statusWidth) + styledStatus;
|
|
529
579
|
}
|
|
530
580
|
renderFooter(width) {
|
|
531
581
|
if (this.focusPane === "right") {
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
.
|
|
535
|
-
|
|
582
|
+
const paneHints = this.topPane()?.hints() ?? "";
|
|
583
|
+
if (width < DOUBLE_PANE_MIN_WIDTH) {
|
|
584
|
+
// Esc already returns to navigation here; only add the arrow hint when it fits whole.
|
|
585
|
+
const arrowHint = keyHint("app.provider.switchPaneLeft", "nav");
|
|
586
|
+
const combined = [paneHints, arrowHint].filter(Boolean).join(" ");
|
|
587
|
+
return [truncateToWidth(visibleWidth(combined) <= width ? combined : paneHints, width)];
|
|
588
|
+
}
|
|
589
|
+
// The editor owns the way-back hint so every wide-layout pane footer is consistent.
|
|
590
|
+
const hints = [paneHints, keyHint("app.provider.switchPaneLeft", "focus left")].filter(Boolean).join(" ");
|
|
536
591
|
return [truncateToWidth(hints, width)];
|
|
537
592
|
}
|
|
538
593
|
const hints = [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor.js","sourceRoot":"","sources":["../../../../src/extensions/provider/ui/editor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Two-pane provider editor.\n *\n * Left column: API Auth / Fetch Models, the provider's\n * models (name → id → \"New Model\" fallback, one draft at a time), then\n * + Add Model and Delete Provider. Right column hosts the selected item's\n * field pane and sub-pane stack; both columns keep their own selection and\n * scroll position. The frame height is fixed: each column scrolls inside a\n * fixed window with a (n/N) position indicator instead of resizing, and the\n * selected row stays accent in both panes while the unfocused pane's other\n * rows dim back. Typing on a value row overwrites, Enter tweaks or enters,\n * ←/→ switch panes, Esc cancels/pops/backs out.\n */\n\nimport \"../keybindings.ts\";\nimport { type Component, type Focusable, type TUI, truncateToWidth, visibleWidth } from \"@earendil-works/pi-tui\";\nimport type { KeybindingsManager } from \"../../../core/keybindings.ts\";\nimport type { ModelsJsonModel } from \"../../../core/model-config.ts\";\nimport type { ModelRegistry } from \"../../../core/model-registry.ts\";\nimport type { ModelRuntime } from \"../../../core/model-runtime.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 { isBuiltinProviderId } from \"../catalog.ts\";\nimport { effectiveModelSettings, hasProviderSettings } from \"../configuration.ts\";\nimport { fetchProviderModels, importProviderModels } from \"../connection.ts\";\nimport { type DraftModelHandle, ProviderEdits } from \"../editing.ts\";\nimport type { RefreshCoordinator } from \"../refresh.ts\";\nimport type { ModelsJsonStore } from \"../store.ts\";\nimport { ConfirmPane, InfoPane } from \"./dialogs.ts\";\nimport { FetchModelsPane } from \"./fetch-models.ts\";\nimport { ModelFieldsPane } from \"./model-fields.ts\";\nimport type { EditorHost, EditorPane, ModelHandle } from \"./pane.ts\";\nimport { ApiAuthPane } from \"./provider-fields.ts\";\nimport { CURSOR, truncateMiddle, windowLines } from \"./value-row.ts\";\n\nexport interface ProviderEditorOptions {\n\tstore: ModelsJsonStore;\n\trefresher: RefreshCoordinator;\n\tproviderId: string;\n\t/** Session model at /provider open time; protects it and its provider from delete/rename. */\n\tcurrentModel?: { provider: string; id: string };\n\tregistry: Pick<ModelRegistry, \"getProviderAuthStatus\">;\n\truntime: Pick<ModelRuntime, \"getAuth\" | \"getProviderAuthStatus\">;\n\tnotify: (message: string, type: \"info\" | \"warning\" | \"error\") => void;\n}\n\nexport type ProviderEditorResult = \"back\" | \"deleted\";\n\ntype LeftItem =\n\t| { kind: \"apiAuth\" }\n\t| { kind: \"fetch\" }\n\t| { kind: \"separator\" }\n\t| { kind: \"model\"; modelId: string }\n\t| { kind: \"draft\" }\n\t| { kind: \"addModel\" }\n\t| { kind: \"deleteProvider\" };\n\nconst LEFT_WIDTH_MIN = 16;\nconst LEFT_WIDTH_MAX = 40;\n/** Fixed editor body height: both columns scroll inside it rather than resizing the frame. */\nconst BODY_ROWS = 14;\nconst MIN_WIDTH = 56;\n\nfunction padTo(line: string, width: number): string {\n\tconst missing = width - visibleWidth(line);\n\treturn missing > 0 ? line + \" \".repeat(missing) : line;\n}\n\n/** Stable identity across left-list rebuilds (a rename keeps the selection on the model). */\nfunction leftItemKey(item: LeftItem | undefined): string {\n\tif (!item) return \"\";\n\tswitch (item.kind) {\n\t\tcase \"model\":\n\t\t\treturn `model:${item.modelId}`;\n\t\tdefault:\n\t\t\treturn item.kind;\n\t}\n}\n\nexport class ProviderEditorScreen implements Component, Focusable {\n\tprivate readonly tui: TUI;\n\tprivate readonly theme: Theme;\n\tprivate readonly keybindings: KeybindingsManager;\n\tprivate readonly done: (result: ProviderEditorResult) => void;\n\tprivate readonly options: ProviderEditorOptions;\n\tprivate readonly host: EditorHost;\n\n\tprivate leftItems: LeftItem[] = [];\n\tprivate leftIndex = 0;\n\tprivate focusPane: \"left\" | \"right\" = \"left\";\n\tprivate stack: EditorPane[] = [];\n\tprivate draft: DraftModelHandle | undefined;\n\tprivate readonly edits: ProviderEdits;\n\tprivate fetchStatus: string | undefined;\n\tprivate disposed = false;\n\tprivate _focused = false;\n\tprivate cache: { width: number; lines: string[] } | undefined;\n\n\tconstructor(\n\t\ttui: TUI,\n\t\ttheme: Theme,\n\t\tkeybindings: KeybindingsManager,\n\t\tdone: (result: ProviderEditorResult) => void,\n\t\toptions: ProviderEditorOptions,\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.options = options;\n\t\tthis.edits = new ProviderEdits(options.store, options.providerId, options.refresher, () => this.refresh());\n\t\tthis.host = this.createHost();\n\t\tthis.rebuildLeftItems();\n\t\tthis.resetRightStack();\n\t}\n\n\t// ------------------------------------------------------------------\n\t// Component / Focusable\n\t// ------------------------------------------------------------------\n\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.topPane()?.setFocused(value && this.focusPane === \"right\");\n\t}\n\n\tinvalidate(): void {\n\t\tthis.cache = undefined;\n\t}\n\n\tdispose(): void {\n\t\tif (this.disposed) return;\n\t\tthis.disposed = true;\n\t\tfor (const pane of this.stack) pane.dispose?.();\n\t\tthis.stack = [];\n\t\t// An unsubmitted draft never reaches disk; leaving the editor drops it.\n\t\tif (!hasProviderSettings(this.options.store.getProvider(this.options.providerId))) {\n\t\t\tthis.options.store.discardProviderDraft(this.options.providerId);\n\t\t}\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.cache && this.cache.width === width) return this.cache.lines;\n\t\tconst lines = this.renderFrame(width);\n\t\tthis.cache = { width, lines };\n\t\treturn lines;\n\t}\n\n\thandleInput(data: string): void {\n\t\tif (this.focusPane === \"right\") {\n\t\t\tconst pane = this.topPane();\n\t\t\tif (pane && !pane.isEditing?.() && this.keybindings.matches(data, \"app.provider.switchPaneLeft\")) {\n\t\t\t\tpane.setFocused(false);\n\t\t\t\tthis.focusPane = \"left\";\n\t\t\t\tthis.refresh();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tpane?.handleInput(data);\n\t\t\treturn;\n\t\t}\n\t\tconst kb = this.keybindings;\n\t\tif (kb.matches(data, \"tui.select.up\")) {\n\t\t\tthis.moveLeft(-1);\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.down\")) {\n\t\t\tthis.moveLeft(1);\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"app.provider.switchPaneRight\")) {\n\t\t\tthis.activateLeftItem(\"inspect\");\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.confirm\")) {\n\t\t\tthis.activateLeftItem(\"activate\");\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.cancel\")) this.done(\"back\");\n\t}\n\n\t/** Rebuild from the store view after a save merged external changes. */\n\tsyncFromStore(): void {\n\t\tif (this.disposed || this.edits.renaming) return;\n\t\tconst selected = this.leftItems[this.leftIndex];\n\t\tconst selectedKey = leftItemKey(selected);\n\t\tthis.rebuildLeftItems();\n\t\tconst nextIndex = this.leftItems.findIndex((item) => leftItemKey(item) === selectedKey);\n\t\tthis.leftIndex = nextIndex >= 0 ? nextIndex : Math.min(this.leftIndex, this.selectableIndex(0));\n\t\t// If the selected model vanished externally, rebuild the right column.\n\t\tif (nextIndex < 0 && selected?.kind === \"model\") {\n\t\t\tthis.resetRightStack();\n\t\t}\n\t\tthis.refresh();\n\t}\n\n\t// ------------------------------------------------------------------\n\t// Left column\n\t// ------------------------------------------------------------------\n\n\tprivate rebuildLeftItems(): void {\n\t\tconst items: LeftItem[] = [{ kind: \"apiAuth\" }, { kind: \"fetch\" }, { kind: \"separator\" }];\n\t\tfor (const model of this.options.store.getModels(this.options.providerId)) {\n\t\t\titems.push({ kind: \"model\", modelId: model.id });\n\t\t}\n\t\tif (this.draft) items.push({ kind: \"draft\" });\n\t\titems.push({ kind: \"separator\" }, { kind: \"addModel\" }, { kind: \"deleteProvider\" });\n\t\tthis.leftItems = items;\n\t}\n\n\tprivate selectableIndex(start: number): number {\n\t\tconst index = this.leftItems.findIndex((item, i) => i >= start && item.kind !== \"separator\");\n\t\treturn index >= 0 ? index : 0;\n\t}\n\n\tprivate moveLeft(delta: number): void {\n\t\tconst selectable = this.leftItems\n\t\t\t.map((item, index) => ({ item, index }))\n\t\t\t.filter((entry) => entry.item.kind !== \"separator\");\n\t\tif (selectable.length === 0) return;\n\t\tconst position = selectable.findIndex((entry) => entry.index === this.leftIndex);\n\t\tconst next = selectable[(position + delta + selectable.length) % selectable.length]!;\n\t\tif (next.index === this.leftIndex) return;\n\t\tthis.leftIndex = next.index;\n\t\t// Moving the left selection replaces the right column (cancels fetch/edit state).\n\t\tthis.resetRightStack();\n\t\tthis.refresh();\n\t}\n\n\t/**\n\t * Enter activates the row; → only focuses its pane. Action rows therefore\n\t * never fire from a focus move, matching their InfoPane's \"Press Enter\".\n\t */\n\tprivate activateLeftItem(via: \"activate\" | \"inspect\"): void {\n\t\tconst item = this.leftItems[this.leftIndex];\n\t\tif (!item) return;\n\t\tswitch (item.kind) {\n\t\t\tcase \"apiAuth\":\n\t\t\tcase \"model\":\n\t\t\tcase \"draft\":\n\t\t\t\tthis.focusPane = \"right\";\n\t\t\t\tthis.topPane()?.setFocused(this._focused);\n\t\t\t\tthis.refresh();\n\t\t\t\treturn;\n\t\t\tcase \"fetch\":\n\t\t\t\tthis.focusPane = \"right\";\n\t\t\t\tif (via === \"activate\") {\n\t\t\t\t\tconst pane = this.topPane();\n\t\t\t\t\tif (pane instanceof FetchModelsPane) pane.start();\n\t\t\t\t}\n\t\t\t\tthis.topPane()?.setFocused(this._focused);\n\t\t\t\tthis.refresh();\n\t\t\t\treturn;\n\t\t\tcase \"addModel\": {\n\t\t\t\tif (via === \"inspect\") {\n\t\t\t\t\tthis.focusPane = \"right\";\n\t\t\t\t\tthis.topPane()?.setFocused(this._focused);\n\t\t\t\t\tthis.refresh();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!this.draft) {\n\t\t\t\t\tthis.draft = this.edits.draft();\n\t\t\t\t\tthis.rebuildLeftItems();\n\t\t\t\t}\n\t\t\t\tconst draftIndex = this.leftItems.findIndex((entry) => entry.kind === \"draft\");\n\t\t\t\tif (draftIndex >= 0) this.leftIndex = draftIndex;\n\t\t\t\tthis.resetRightStack();\n\t\t\t\tthis.focusPane = \"right\";\n\t\t\t\tconst pane = this.topPane();\n\t\t\t\tpane?.setFocused(this._focused);\n\t\t\t\tif (pane instanceof ModelFieldsPane && !this.draft.read().id) pane.startEditingId();\n\t\t\t\tthis.refresh();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"deleteProvider\": {\n\t\t\t\tif (via === \"inspect\") {\n\t\t\t\t\tthis.focusPane = \"right\";\n\t\t\t\t\tthis.topPane()?.setFocused(this._focused);\n\t\t\t\t\tthis.refresh();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (this.host.isCurrentProvider()) {\n\t\t\t\t\tthis.host.notify(\n\t\t\t\t\t\t\"The current model's provider cannot be deleted; switch models with /model first.\",\n\t\t\t\t\t\t\"error\",\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst builtin = isBuiltinProviderId(this.options.providerId);\n\t\t\t\tthis.host.confirm(\n\t\t\t\t\t`Delete provider \"${this.options.providerId}\" from models.json?` +\n\t\t\t\t\t\t(builtin ? \" The built-in catalog remains and its models may reappear.\" : \"\") +\n\t\t\t\t\t\t\" Stored credentials in auth.json are kept.\",\n\t\t\t\t\t\"Delete Provider\",\n\t\t\t\t\t() => {\n\t\t\t\t\t\tthis.edits.removeProvider();\n\t\t\t\t\t\tthis.done(\"deleted\");\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn;\n\t\t}\n\t}\n\n\tprivate renderLeft(width: number): string[] {\n\t\tconst theme = this.theme;\n\t\tconst focused = this.focusPane === \"left\";\n\t\tconst rows: string[] = [];\n\t\tconst renderRow = (index: number): string => {\n\t\t\tconst item = this.leftItems[index]!;\n\t\t\tif (item.kind === \"separator\") {\n\t\t\t\treturn theme.fg(\"borderMuted\", ` ${\"─\".repeat(Math.max(1, width - 4))}`);\n\t\t\t}\n\t\t\treturn this.renderLeftItem(item, index === this.leftIndex, focused, width);\n\t\t};\n\t\tif (this.leftItems.length <= BODY_ROWS) {\n\t\t\tfor (let index = 0; index < this.leftItems.length; index++) rows.push(renderRow(index));\n\t\t} else {\n\t\t\t// One row carries the (n/N) position indicator, like the /model selector.\n\t\t\tconst slots = BODY_ROWS - 1;\n\t\t\tconst start = Math.max(0, Math.min(this.leftIndex - Math.floor(slots / 2), this.leftItems.length - slots));\n\t\t\tfor (let index = start; index < start + slots; index++) rows.push(renderRow(index));\n\t\t\tconst selectable: LeftItem[] = this.leftItems.filter((item) => item.kind !== \"separator\");\n\t\t\tconst position = selectable.indexOf(this.leftItems[this.leftIndex]!);\n\t\t\trows.push(theme.fg(\"dim\", ` (${position + 1}/${selectable.length})`));\n\t\t}\n\t\twhile (rows.length < BODY_ROWS) rows.push(\"\");\n\t\treturn rows;\n\t}\n\n\tprivate leftItemContent(item: LeftItem): { text: string; note?: string; dim: boolean } {\n\t\tconst store = this.options.store;\n\t\tlet text: string;\n\t\tlet note: string | undefined;\n\t\tswitch (item.kind) {\n\t\t\tcase \"apiAuth\":\n\t\t\t\ttext = \"API Auth\";\n\t\t\t\tbreak;\n\t\t\tcase \"fetch\":\n\t\t\t\ttext = \"Fetch Models\";\n\t\t\t\tnote = this.fetchStatus;\n\t\t\t\tbreak;\n\t\t\tcase \"model\": {\n\t\t\t\tconst model = store.getModel(this.options.providerId, item.modelId);\n\t\t\t\ttext = model ? modelDisplayName(model) : item.modelId;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"draft\": {\n\t\t\t\ttext = this.draft?.read().name ?? this.draft?.read().id ?? \"New Model\";\n\t\t\t\tnote = \"· draft\";\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"addModel\":\n\t\t\t\ttext = \"+ Add Model\";\n\t\t\t\tbreak;\n\t\t\tcase \"deleteProvider\":\n\t\t\t\ttext = \"Delete Provider\";\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\ttext = \"\";\n\t\t}\n\t\tconst dim = item.kind === \"draft\" && !this.draft?.read().name && !this.draft?.read().id;\n\t\treturn { text, note, dim };\n\t}\n\n\tprivate renderLeftItem(item: LeftItem, active: boolean, focused: boolean, width: number): string {\n\t\tconst theme = this.theme;\n\t\t// Single-accent focus rule: the marker and accent exist only in the\n\t\t// focused column; an unfocused column keeps its content plain.\n\t\tconst lit = active && focused;\n\t\tconst marker = lit ? theme.fg(\"accent\", `${CURSOR} `) : \" \";\n\t\tconst style = (text: string, dim = false) => theme.fg(lit ? \"accent\" : dim ? \"dim\" : \"text\", text);\n\t\tconst { text: label, note, dim } = this.leftItemContent(item);\n\t\tlet text = label;\n\t\t// Long model names keep head and tail (the distinctive parts) instead of a hard cut.\n\t\tif (item.kind === \"model\" || item.kind === \"draft\") {\n\t\t\tconst budget = Math.max(8, width - 2 - (note ? visibleWidth(note) + 1 : 0));\n\t\t\ttext = truncateMiddle(text, budget);\n\t\t}\n\t\tconst noteText = note ? theme.fg(\"dim\", ` ${note}`) : \"\";\n\t\treturn truncateToWidth(marker + style(text, dim) + noteText, width);\n\t}\n\n\t// ------------------------------------------------------------------\n\t// Right column (pane stack)\n\t// ------------------------------------------------------------------\n\n\tprivate topPane(): EditorPane | undefined {\n\t\treturn this.stack[this.stack.length - 1];\n\t}\n\n\tprivate pushPane(pane: EditorPane): void {\n\t\tthis.topPane()?.setFocused(false);\n\t\tthis.focusPane = \"right\";\n\t\tthis.stack.push(pane);\n\t\tpane.setFocused(this._focused && this.focusPane === \"right\");\n\t\tthis.refresh();\n\t}\n\n\tprivate popPane(): void {\n\t\tif (this.stack.length <= 1) {\n\t\t\t// Esc on the base pane moves focus back to the left column.\n\t\t\tthis.topPane()?.setFocused(false);\n\t\t\tthis.focusPane = \"left\";\n\t\t\tthis.refresh();\n\t\t\treturn;\n\t\t}\n\t\tconst pane = this.stack.pop();\n\t\tpane?.setFocused(false);\n\t\tpane?.dispose?.();\n\t\tthis.topPane()?.setFocused(this._focused && this.focusPane === \"right\");\n\t\tthis.refresh();\n\t}\n\n\tprivate resetRightStack(): void {\n\t\tfor (const pane of this.stack) pane.dispose?.();\n\t\tconst item = this.leftItems[this.leftIndex];\n\t\tthis.stack = [this.createBasePane(item)];\n\t\tthis.topPane()?.setFocused(this._focused && this.focusPane === \"right\");\n\t}\n\n\tprivate createBasePane(item: LeftItem | undefined): EditorPane {\n\t\tswitch (item?.kind) {\n\t\t\tcase \"apiAuth\":\n\t\t\t\treturn new ApiAuthPane(this.host, this.options.registry);\n\t\t\tcase \"fetch\":\n\t\t\t\treturn new FetchModelsPane(this.host);\n\t\t\tcase \"model\":\n\t\t\t\treturn new ModelFieldsPane(this.host, this.persistedHandle(item.modelId));\n\t\t\tcase \"draft\":\n\t\t\t\treturn new ModelFieldsPane(this.host, this.draft!);\n\t\t\tcase \"addModel\":\n\t\t\t\treturn new InfoPane(\n\t\t\t\t\tthis.host,\n\t\t\t\t\t[\n\t\t\t\t\t\t\"Press Enter to create a model.\",\n\t\t\t\t\t\t\"A draft is kept in memory until its id is set; Esc on the draft discards it.\",\n\t\t\t\t\t],\n\t\t\t\t\t() => this.activateLeftItem(\"activate\"),\n\t\t\t\t);\n\t\t\tcase \"deleteProvider\":\n\t\t\t\treturn new InfoPane(this.host, [\"Press Enter to delete this provider from models.json.\"], () =>\n\t\t\t\t\tthis.activateLeftItem(\"activate\"),\n\t\t\t\t);\n\t\t\tdefault:\n\t\t\t\treturn new InfoPane(this.host, []);\n\t\t}\n\t}\n\n\tprivate persistedHandle(modelId: string): ModelHandle {\n\t\treturn this.edits.model(modelId, (oldId, newId) => {\n\t\t\tconst selected = this.leftItems[this.leftIndex];\n\t\t\tif (selected?.kind === \"model\" && selected.modelId === oldId) selected.modelId = newId;\n\t\t\tthis.syncFromStore();\n\t\t});\n\t}\n\n\t// ------------------------------------------------------------------\n\t// EditorHost implementation\n\t// ------------------------------------------------------------------\n\n\tprivate createHost(): EditorHost {\n\t\tconst store = this.options.store;\n\t\tconst providerId = this.options.providerId;\n\t\treturn {\n\t\t\ttui: this.tui,\n\t\t\ttheme: this.theme,\n\t\t\tkeybindings: this.keybindings,\n\t\t\tstore,\n\t\t\tedits: this.edits,\n\t\t\tproviderId,\n\t\t\tpushPane: (pane) => this.pushPane(pane),\n\t\t\tpopPane: () => this.popPane(),\n\t\t\trefresh: () => this.refresh(),\n\t\t\tnotify: (message, type) => this.options.notify(message, type),\n\t\t\teffectiveApi: (model) => {\n\t\t\t\treturn effectiveModelSettings(providerId, store.getProvider(providerId), model).api;\n\t\t\t},\n\t\t\teffectiveBaseUrl: (model) => {\n\t\t\t\treturn effectiveModelSettings(providerId, store.getProvider(providerId), model).baseUrl;\n\t\t\t},\n\t\t\tcommitModelDraft: () => this.commitModelDraft(),\n\t\t\tdiscardModelDraft: () => this.discardModelDraft(),\n\t\t\tisCurrentModel: (modelId) =>\n\t\t\t\tthis.options.currentModel?.provider === providerId && this.options.currentModel.id === modelId,\n\t\t\tisCurrentProvider: () => this.options.currentModel?.provider === providerId,\n\t\t\tsetFetchStatus: (status) => {\n\t\t\t\tthis.fetchStatus = status;\n\t\t\t\tthis.refresh();\n\t\t\t},\n\t\t\trunFetch: (signal) => fetchProviderModels(this.options, signal),\n\t\t\timportModels: async (models, signal) => {\n\t\t\t\tconst error = await importProviderModels({ ...this.options, edits: this.edits }, models, signal);\n\t\t\t\tif (!this.disposed) this.syncFromStore();\n\t\t\t\treturn error;\n\t\t\t},\n\t\t\tconfirm: (message, actionLabel, action) =>\n\t\t\t\tthis.pushPane(new ConfirmPane(this.host, message, actionLabel, action)),\n\t\t\tonModelRemoved: () => {\n\t\t\t\tthis.rebuildLeftItems();\n\t\t\t\t// Land on the next row where the model was; walk back over separators.\n\t\t\t\tthis.leftIndex = Math.min(this.leftIndex, this.leftItems.length - 1);\n\t\t\t\twhile (this.leftIndex > 0 && this.leftItems[this.leftIndex]?.kind === \"separator\") this.leftIndex--;\n\t\t\t\tif (this.leftItems[this.leftIndex]?.kind === \"separator\") this.leftIndex = this.selectableIndex(0);\n\t\t\t\tthis.focusPane = \"left\";\n\t\t\t\tthis.resetRightStack();\n\t\t\t\tthis.refresh();\n\t\t\t},\n\t\t};\n\t}\n\n\t/** Drop the in-memory draft: the selection returns to + Add Model with focus on the left. */\n\tprivate discardModelDraft(): void {\n\t\tif (!this.draft) return;\n\t\tthis.draft = undefined;\n\t\tthis.rebuildLeftItems();\n\t\tconst addIndex = this.leftItems.findIndex((item) => item.kind === \"addModel\");\n\t\tthis.leftIndex = addIndex >= 0 ? addIndex : this.selectableIndex(0);\n\t\tthis.focusPane = \"left\";\n\t\tthis.resetRightStack();\n\t\tthis.refresh();\n\t}\n\n\tprivate commitModelDraft(): string | undefined {\n\t\tconst draft = this.draft;\n\t\tif (!draft) return \"No model draft.\";\n\t\tconst error = this.edits.commitDraft(draft);\n\t\tif (error) return error;\n\t\tconst id = draft.read().id!.trim();\n\t\tthis.draft = undefined;\n\t\tthis.rebuildLeftItems();\n\t\tconst index = this.leftItems.findIndex((item) => item.kind === \"model\" && item.modelId === id);\n\t\tif (index >= 0) this.leftIndex = index;\n\t\tthis.resetRightStack();\n\t\tthis.refresh();\n\t\treturn undefined;\n\t}\n\n\t// ------------------------------------------------------------------\n\t// Frame rendering\n\t// ------------------------------------------------------------------\n\n\tprivate refresh(): void {\n\t\tthis.invalidate();\n\t\tthis.tui.requestRender();\n\t}\n\n\tprivate renderFrame(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\tif (width < MIN_WIDTH) {\n\t\t\treturn [\n\t\t\t\tborder,\n\t\t\t\ttruncateToWidth(theme.fg(\"warning\", ` /provider needs at least ${MIN_WIDTH} columns`), width),\n\t\t\t\tborder,\n\t\t\t];\n\t\t}\n\t\tconst leftWidth = this.computeLeftWidth(width);\n\t\tconst rightWidth = width - leftWidth - 3;\n\t\tconst separator = theme.fg(\"border\", \" │ \");\n\n\t\tconst title = this.renderTitle(width);\n\t\t// The crumb marks drill-down depth only; base rows are already named by the left selection.\n\t\tconst crumb = truncateToWidth(this.theme.fg(\"muted\", this.topPane()?.crumb ?? \"\"), rightWidth);\n\t\tconst leftLines = this.renderLeft(leftWidth);\n\t\tconst pane = this.topPane();\n\t\tconst paneLines = pane ? windowLines(theme, pane.render(rightWidth), BODY_ROWS - 1, pane.scrollWindow?.()) : [];\n\t\tconst rightLines = [crumb, ...paneLines];\n\t\tconst body: string[] = [];\n\t\tfor (let row = 0; row < BODY_ROWS; row++) {\n\t\t\tconst left = padTo(truncateToWidth(leftLines[row] ?? \"\", leftWidth), leftWidth);\n\t\t\tconst right = truncateToWidth(rightLines[row] ?? \"\", rightWidth);\n\t\t\tbody.push(left + separator + right);\n\t\t}\n\n\t\tconst footerLines = this.renderFooter(width);\n\t\treturn [border, title, border, ...body, border, ...footerLines, border];\n\t}\n\n\t/** Content-driven left width: fits the longest visible label, clamped to 16–40 and 45% of the terminal. */\n\tprivate computeLeftWidth(width: number): number {\n\t\tlet longest = 12;\n\t\tfor (const item of this.leftItems) {\n\t\t\tif (item.kind === \"separator\") continue;\n\t\t\tconst { text, note } = this.leftItemContent(item);\n\t\t\tconst label = text + (note ? ` ${note}` : \"\");\n\t\t\tlongest = Math.max(longest, visibleWidth(label));\n\t\t}\n\t\tconst fit = Math.max(LEFT_WIDTH_MIN, Math.min(LEFT_WIDTH_MAX, longest + 2));\n\t\treturn Math.min(fit, Math.max(LEFT_WIDTH_MIN, Math.floor(width * 0.45)));\n\t}\n\n\tprivate renderTitle(width: number): string {\n\t\tconst theme = this.theme;\n\t\tlet title = ` /provider · ${this.options.providerId}`;\n\t\tif (isBuiltinProviderId(this.options.providerId)) title += \" · overlays built-in catalog\";\n\t\treturn truncateToWidth(theme.fg(\"accent\", theme.bold(title)), width);\n\t}\n\n\tprivate renderFooter(width: number): string[] {\n\t\tif (this.focusPane === \"right\") {\n\t\t\t// The editor owns the way-back hint so every pane's footer is consistent.\n\t\t\tconst hints = [this.topPane()?.hints() ?? \"\", keyHint(\"app.provider.switchPaneLeft\", \"focus left\")]\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.join(\" \");\n\t\t\treturn [truncateToWidth(hints, width)];\n\t\t}\n\t\tconst hints = [\n\t\t\trawKeyHint(\"↑↓\", \"move\"),\n\t\t\tkeyHint(\"tui.select.confirm\", this.leftActivateLabel()),\n\t\t\tkeyHint(\"app.provider.switchPaneRight\", \"focus right\"),\n\t\t\tkeyHint(\"tui.select.cancel\", \"back\"),\n\t\t].join(\" \");\n\t\treturn [truncateToWidth(hints, width)];\n\t}\n\n\t/** What Enter does to the selected left-column row, so the footer never lies about action rows. */\n\tprivate leftActivateLabel(): string {\n\t\tswitch (this.leftItems[this.leftIndex]?.kind) {\n\t\t\tcase \"fetch\":\n\t\t\t\treturn \"fetch\";\n\t\t\tcase \"addModel\":\n\t\t\t\treturn \"create\";\n\t\t\tcase \"deleteProvider\":\n\t\t\t\treturn \"delete\";\n\t\t\tdefault:\n\t\t\t\treturn \"open\";\n\t\t}\n\t}\n}\n\nfunction modelDisplayName(model: ModelsJsonModel): string {\n\treturn model.name ?? model.id;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"editor.js","sourceRoot":"","sources":["../../../../src/extensions/provider/ui/editor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Two-pane provider editor.\n *\n * Left column groups connection, models, and management actions. The right\n * column hosts the selected item's field pane and sub-pane stack. Both columns\n * scroll inside a fixed-height frame; below the wide-layout threshold, only\n * the focused column is shown. Typing on a value row overwrites, Enter tweaks\n * or enters, ←/→ switch panes, and Esc cancels/pops/backs out.\n */\n\nimport \"../keybindings.ts\";\nimport { type Component, type Focusable, type TUI, truncateToWidth, visibleWidth } from \"@earendil-works/pi-tui\";\nimport type { KeybindingsManager } from \"../../../core/keybindings.ts\";\nimport type { ModelsJsonModel } from \"../../../core/model-config.ts\";\nimport type { ModelRegistry } from \"../../../core/model-registry.ts\";\nimport type { ModelRuntime } from \"../../../core/model-runtime.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 { isBuiltinProviderId } from \"../catalog.ts\";\nimport { effectiveModelSettings, hasProviderSettings } from \"../configuration.ts\";\nimport { fetchProviderModels, importProviderModels } from \"../connection.ts\";\nimport { type DraftModelHandle, ProviderEdits } from \"../editing.ts\";\nimport type { RefreshCoordinator } from \"../refresh.ts\";\nimport type { ModelsJsonStore } from \"../store.ts\";\nimport { ConfirmPane, InfoPane } from \"./dialogs.ts\";\nimport { FetchModelsPane } from \"./fetch-models.ts\";\nimport { ModelFieldsPane } from \"./model-fields.ts\";\nimport type { EditorHost, EditorPane, ModelHandle } from \"./pane.ts\";\nimport { ApiAuthPane } from \"./provider-fields.ts\";\nimport { CURSOR, truncateMiddle, windowLines } from \"./value-row.ts\";\n\nexport interface ProviderEditorOptions {\n\tstore: ModelsJsonStore;\n\trefresher: RefreshCoordinator;\n\tproviderId: string;\n\t/** Session model at /provider open time; protects it and its provider from delete/rename. */\n\tcurrentModel?: { provider: string; id: string };\n\tregistry: Pick<ModelRegistry, \"getProviderAuthStatus\">;\n\truntime: Pick<ModelRuntime, \"getAuth\" | \"getProviderAuthStatus\">;\n\tnotify: (message: string, type: \"info\" | \"warning\" | \"error\") => void;\n}\n\nexport type ProviderEditorResult = \"back\" | \"deleted\";\n\ntype LeftItem =\n\t| { kind: \"apiAuth\" }\n\t| { kind: \"fetch\" }\n\t| { kind: \"section\"; label: \"SETUP\" | \"MODELS\" | \"MANAGE\" }\n\t| { kind: \"model\"; modelId: string }\n\t| { kind: \"draft\" }\n\t| { kind: \"addModel\" }\n\t| { kind: \"deleteProvider\" };\n\nconst LEFT_WIDTH_MIN = 16;\nconst LEFT_WIDTH_MAX = 40;\n/** Fixed editor body height: both columns scroll inside it rather than resizing the frame. */\nconst BODY_ROWS = 14;\nconst DOUBLE_PANE_MIN_WIDTH = 72;\nconst MIN_WIDTH = 32;\n\nfunction padTo(line: string, width: number): string {\n\tconst missing = width - visibleWidth(line);\n\treturn missing > 0 ? line + \" \".repeat(missing) : line;\n}\n\n/** Stable identity across left-list rebuilds (a rename keeps the selection on the model). */\nfunction leftItemKey(item: LeftItem | undefined): string {\n\tif (!item) return \"\";\n\tswitch (item.kind) {\n\t\tcase \"model\":\n\t\t\treturn `model:${item.modelId}`;\n\t\tcase \"section\":\n\t\t\treturn `section:${item.label}`;\n\t\tdefault:\n\t\t\treturn item.kind;\n\t}\n}\n\nexport class ProviderEditorScreen implements Component, Focusable {\n\tprivate readonly tui: TUI;\n\tprivate readonly theme: Theme;\n\tprivate readonly keybindings: KeybindingsManager;\n\tprivate readonly done: (result: ProviderEditorResult) => void;\n\tprivate readonly options: ProviderEditorOptions;\n\tprivate readonly host: EditorHost;\n\n\tprivate leftItems: LeftItem[] = [];\n\tprivate leftIndex = 0;\n\tprivate focusPane: \"left\" | \"right\" = \"left\";\n\tprivate stack: EditorPane[] = [];\n\tprivate draft: DraftModelHandle | undefined;\n\tprivate readonly edits: ProviderEdits;\n\tprivate fetchStatus: string | undefined;\n\tprivate disposed = false;\n\tprivate _focused = false;\n\tprivate cache: { width: number; lines: string[] } | undefined;\n\n\tconstructor(\n\t\ttui: TUI,\n\t\ttheme: Theme,\n\t\tkeybindings: KeybindingsManager,\n\t\tdone: (result: ProviderEditorResult) => void,\n\t\toptions: ProviderEditorOptions,\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.options = options;\n\t\tthis.edits = new ProviderEdits(options.store, options.providerId, options.refresher, () => this.refresh());\n\t\tthis.host = this.createHost();\n\t\tthis.rebuildLeftItems();\n\t\tthis.leftIndex = this.selectableIndex(0);\n\t\tthis.resetRightStack();\n\t}\n\n\t// ------------------------------------------------------------------\n\t// Component / Focusable\n\t// ------------------------------------------------------------------\n\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.topPane()?.setFocused(value && this.focusPane === \"right\");\n\t}\n\n\tinvalidate(): void {\n\t\tthis.cache = undefined;\n\t}\n\n\tdispose(): void {\n\t\tif (this.disposed) return;\n\t\tthis.disposed = true;\n\t\tfor (const pane of this.stack) pane.dispose?.();\n\t\tthis.stack = [];\n\t\t// An unsubmitted draft never reaches disk; leaving the editor drops it.\n\t\tif (!hasProviderSettings(this.options.store.getProvider(this.options.providerId))) {\n\t\t\tthis.options.store.discardProviderDraft(this.options.providerId);\n\t\t}\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.cache && this.cache.width === width) return this.cache.lines;\n\t\tconst lines = this.renderFrame(width);\n\t\tthis.cache = { width, lines };\n\t\treturn lines;\n\t}\n\n\thandleInput(data: string): void {\n\t\tif (this.focusPane === \"right\") {\n\t\t\tconst pane = this.topPane();\n\t\t\tif (pane && !pane.isEditing?.() && this.keybindings.matches(data, \"app.provider.switchPaneLeft\")) {\n\t\t\t\tpane.setFocused(false);\n\t\t\t\tthis.focusPane = \"left\";\n\t\t\t\tthis.refresh();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tpane?.handleInput(data);\n\t\t\treturn;\n\t\t}\n\t\tconst kb = this.keybindings;\n\t\tif (kb.matches(data, \"tui.select.up\")) {\n\t\t\tthis.moveLeft(-1);\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.down\")) {\n\t\t\tthis.moveLeft(1);\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"app.provider.switchPaneRight\")) {\n\t\t\tthis.activateLeftItem(\"inspect\");\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.confirm\")) {\n\t\t\tthis.activateLeftItem(\"activate\");\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.cancel\")) this.done(\"back\");\n\t}\n\n\t/** Rebuild from the store view after a save merged external changes. */\n\tsyncFromStore(): void {\n\t\tif (this.disposed || this.edits.renaming) return;\n\t\tconst selected = this.leftItems[this.leftIndex];\n\t\tconst selectedKey = leftItemKey(selected);\n\t\tthis.rebuildLeftItems();\n\t\tconst nextIndex = this.leftItems.findIndex((item) => leftItemKey(item) === selectedKey);\n\t\tthis.leftIndex =\n\t\t\tnextIndex >= 0\n\t\t\t\t? nextIndex\n\t\t\t\t: this.selectableIndex(Math.min(this.leftIndex, Math.max(0, this.leftItems.length - 1)));\n\t\t// If the selected model vanished externally, rebuild the right column.\n\t\tif (nextIndex < 0 && selected?.kind === \"model\") {\n\t\t\tthis.resetRightStack();\n\t\t}\n\t\tthis.refresh();\n\t}\n\n\t// ------------------------------------------------------------------\n\t// Left column\n\t// ------------------------------------------------------------------\n\n\tprivate rebuildLeftItems(): void {\n\t\tconst items: LeftItem[] = [\n\t\t\t{ kind: \"section\", label: \"SETUP\" },\n\t\t\t{ kind: \"apiAuth\" },\n\t\t\t{ kind: \"fetch\" },\n\t\t\t{ kind: \"section\", label: \"MODELS\" },\n\t\t];\n\t\tfor (const model of this.options.store.getModels(this.options.providerId)) {\n\t\t\titems.push({ kind: \"model\", modelId: model.id });\n\t\t}\n\t\tif (this.draft) items.push({ kind: \"draft\" });\n\t\titems.push({ kind: \"section\", label: \"MANAGE\" }, { kind: \"addModel\" }, { kind: \"deleteProvider\" });\n\t\tthis.leftItems = items;\n\t}\n\n\tprivate selectableIndex(start: number): number {\n\t\tconst index = this.leftItems.findIndex((item, i) => i >= start && item.kind !== \"section\");\n\t\treturn index >= 0 ? index : this.leftItems.findIndex((item) => item.kind !== \"section\");\n\t}\n\n\tprivate moveLeft(delta: number): void {\n\t\tconst selectable = this.leftItems\n\t\t\t.map((item, index) => ({ item, index }))\n\t\t\t.filter((entry) => entry.item.kind !== \"section\");\n\t\tif (selectable.length === 0) return;\n\t\tconst position = selectable.findIndex((entry) => entry.index === this.leftIndex);\n\t\tconst next = selectable[(position + delta + selectable.length) % selectable.length]!;\n\t\tif (next.index === this.leftIndex) return;\n\t\tthis.leftIndex = next.index;\n\t\t// Moving the left selection replaces the right column (cancels fetch/edit state).\n\t\tthis.resetRightStack();\n\t\tthis.refresh();\n\t}\n\n\t/**\n\t * Enter activates the row; → only focuses its pane. Action rows therefore\n\t * never fire from a focus move, matching their InfoPane's \"Press Enter\".\n\t */\n\tprivate activateLeftItem(via: \"activate\" | \"inspect\"): void {\n\t\tconst item = this.leftItems[this.leftIndex];\n\t\tif (!item) return;\n\t\tswitch (item.kind) {\n\t\t\tcase \"apiAuth\":\n\t\t\tcase \"model\":\n\t\t\tcase \"draft\":\n\t\t\t\tthis.focusPane = \"right\";\n\t\t\t\tthis.topPane()?.setFocused(this._focused);\n\t\t\t\tthis.refresh();\n\t\t\t\treturn;\n\t\t\tcase \"fetch\":\n\t\t\t\tthis.focusPane = \"right\";\n\t\t\t\tif (via === \"activate\") {\n\t\t\t\t\tconst pane = this.topPane();\n\t\t\t\t\tif (pane instanceof FetchModelsPane) pane.start();\n\t\t\t\t}\n\t\t\t\tthis.topPane()?.setFocused(this._focused);\n\t\t\t\tthis.refresh();\n\t\t\t\treturn;\n\t\t\tcase \"addModel\": {\n\t\t\t\tif (via === \"inspect\") {\n\t\t\t\t\tthis.focusPane = \"right\";\n\t\t\t\t\tthis.topPane()?.setFocused(this._focused);\n\t\t\t\t\tthis.refresh();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!this.draft) {\n\t\t\t\t\tthis.draft = this.edits.draft();\n\t\t\t\t\tthis.rebuildLeftItems();\n\t\t\t\t}\n\t\t\t\tconst draftIndex = this.leftItems.findIndex((entry) => entry.kind === \"draft\");\n\t\t\t\tif (draftIndex >= 0) this.leftIndex = draftIndex;\n\t\t\t\tthis.resetRightStack();\n\t\t\t\tthis.focusPane = \"right\";\n\t\t\t\tconst pane = this.topPane();\n\t\t\t\tpane?.setFocused(this._focused);\n\t\t\t\tif (pane instanceof ModelFieldsPane && !this.draft.read().id) pane.startEditingId();\n\t\t\t\tthis.refresh();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"deleteProvider\": {\n\t\t\t\tif (via === \"inspect\") {\n\t\t\t\t\tthis.focusPane = \"right\";\n\t\t\t\t\tthis.topPane()?.setFocused(this._focused);\n\t\t\t\t\tthis.refresh();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (this.host.isCurrentProvider()) {\n\t\t\t\t\tthis.host.notify(\n\t\t\t\t\t\t\"The current model's provider cannot be deleted; switch models with /model first.\",\n\t\t\t\t\t\t\"error\",\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst builtin = isBuiltinProviderId(this.options.providerId);\n\t\t\t\tthis.host.confirm(\n\t\t\t\t\t`Delete provider \"${this.options.providerId}\" from models.json?` +\n\t\t\t\t\t\t(builtin ? \" The built-in catalog remains and its models may reappear.\" : \"\") +\n\t\t\t\t\t\t\" Stored credentials in auth.json are kept.\",\n\t\t\t\t\t\"Delete provider\",\n\t\t\t\t\t() => {\n\t\t\t\t\t\tthis.edits.removeProvider();\n\t\t\t\t\t\tthis.done(\"deleted\");\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn;\n\t\t}\n\t}\n\n\tprivate renderLeft(width: number): string[] {\n\t\tconst theme = this.theme;\n\t\tconst focused = this.focusPane === \"left\";\n\t\tconst rows: string[] = [];\n\t\tconst renderRow = (index: number): string => {\n\t\t\tconst item = this.leftItems[index]!;\n\t\t\tif (item.kind === \"section\") {\n\t\t\t\treturn theme.fg(\"dim\", item.label);\n\t\t\t}\n\t\t\treturn this.renderLeftItem(item, index === this.leftIndex, focused, width);\n\t\t};\n\t\tif (this.leftItems.length <= BODY_ROWS) {\n\t\t\tfor (let index = 0; index < this.leftItems.length; index++) rows.push(renderRow(index));\n\t\t} else {\n\t\t\t// One row carries the (n/N) position indicator, like the /model selector.\n\t\t\tconst slots = BODY_ROWS - 1;\n\t\t\tconst start = Math.max(0, Math.min(this.leftIndex - Math.floor(slots / 2), this.leftItems.length - slots));\n\t\t\tfor (let index = start; index < start + slots; index++) rows.push(renderRow(index));\n\t\t\tconst selectable: LeftItem[] = this.leftItems.filter((item) => item.kind !== \"section\");\n\t\t\tconst position = selectable.indexOf(this.leftItems[this.leftIndex]!);\n\t\t\trows.push(theme.fg(\"dim\", ` (${position + 1}/${selectable.length})`));\n\t\t}\n\t\twhile (rows.length < BODY_ROWS) rows.push(\"\");\n\t\treturn rows;\n\t}\n\n\tprivate leftItemContent(item: LeftItem): { text: string; note?: string; dim: boolean } {\n\t\tconst store = this.options.store;\n\t\tlet text: string;\n\t\tlet note: string | undefined;\n\t\tswitch (item.kind) {\n\t\t\tcase \"apiAuth\":\n\t\t\t\ttext = \"API Auth\";\n\t\t\t\tbreak;\n\t\t\tcase \"fetch\":\n\t\t\t\ttext = \"Fetch Models\";\n\t\t\t\tnote = this.fetchStatus;\n\t\t\t\tbreak;\n\t\t\tcase \"model\": {\n\t\t\t\tconst model = store.getModel(this.options.providerId, item.modelId);\n\t\t\t\ttext = model ? modelDisplayName(model) : item.modelId;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"draft\": {\n\t\t\t\ttext = this.draft?.read().name ?? this.draft?.read().id ?? \"New Model\";\n\t\t\t\tnote = \"· draft\";\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"addModel\":\n\t\t\t\ttext = \"+ Add model\";\n\t\t\t\tbreak;\n\t\t\tcase \"deleteProvider\":\n\t\t\t\ttext = \"Delete provider\";\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\ttext = \"\";\n\t\t}\n\t\tconst dim = item.kind === \"draft\" && !this.draft?.read().name && !this.draft?.read().id;\n\t\treturn { text, note, dim };\n\t}\n\n\tprivate renderLeftItem(item: LeftItem, active: boolean, focused: boolean, width: number): string {\n\t\tconst theme = this.theme;\n\t\t// Single-accent focus rule: the marker and accent exist only in the\n\t\t// focused column; an unfocused column keeps its content plain.\n\t\tconst lit = active && focused;\n\t\tconst marker = lit ? theme.fg(\"accent\", `${CURSOR} `) : \" \";\n\t\tconst style = (text: string, dim = false) => theme.fg(lit ? \"accent\" : dim ? \"dim\" : \"text\", text);\n\t\tconst { text: label, note, dim } = this.leftItemContent(item);\n\t\tlet text = label;\n\t\t// Long model names keep head and tail (the distinctive parts) instead of a hard cut.\n\t\tif (item.kind === \"model\" || item.kind === \"draft\") {\n\t\t\tconst budget = Math.max(8, width - 2 - (note ? visibleWidth(note) + 1 : 0));\n\t\t\ttext = truncateMiddle(text, budget);\n\t\t}\n\t\tconst noteText = note ? theme.fg(\"dim\", ` ${note}`) : \"\";\n\t\treturn truncateToWidth(marker + style(text, dim) + noteText, width);\n\t}\n\n\t// ------------------------------------------------------------------\n\t// Right column (pane stack)\n\t// ------------------------------------------------------------------\n\n\tprivate topPane(): EditorPane | undefined {\n\t\treturn this.stack[this.stack.length - 1];\n\t}\n\n\tprivate pushPane(pane: EditorPane): void {\n\t\tthis.topPane()?.setFocused(false);\n\t\tthis.focusPane = \"right\";\n\t\tthis.stack.push(pane);\n\t\tpane.setFocused(this._focused && this.focusPane === \"right\");\n\t\tthis.refresh();\n\t}\n\n\tprivate popPane(): void {\n\t\tif (this.stack.length <= 1) {\n\t\t\t// Esc on the base pane moves focus back to the left column.\n\t\t\tthis.topPane()?.setFocused(false);\n\t\t\tthis.focusPane = \"left\";\n\t\t\tthis.refresh();\n\t\t\treturn;\n\t\t}\n\t\tconst pane = this.stack.pop();\n\t\tpane?.setFocused(false);\n\t\tpane?.dispose?.();\n\t\tthis.topPane()?.setFocused(this._focused && this.focusPane === \"right\");\n\t\tthis.refresh();\n\t}\n\n\tprivate resetRightStack(): void {\n\t\tfor (const pane of this.stack) pane.dispose?.();\n\t\tconst item = this.leftItems[this.leftIndex];\n\t\tthis.stack = [this.createBasePane(item)];\n\t\tthis.topPane()?.setFocused(this._focused && this.focusPane === \"right\");\n\t}\n\n\tprivate createBasePane(item: LeftItem | undefined): EditorPane {\n\t\tswitch (item?.kind) {\n\t\t\tcase \"apiAuth\":\n\t\t\t\treturn new ApiAuthPane(this.host, this.options.registry);\n\t\t\tcase \"fetch\":\n\t\t\t\treturn new FetchModelsPane(this.host);\n\t\t\tcase \"model\":\n\t\t\t\treturn new ModelFieldsPane(this.host, this.persistedHandle(item.modelId));\n\t\t\tcase \"draft\":\n\t\t\t\treturn new ModelFieldsPane(this.host, this.draft!);\n\t\t\tcase \"addModel\":\n\t\t\t\treturn new InfoPane(\n\t\t\t\t\tthis.host,\n\t\t\t\t\t[\n\t\t\t\t\t\t\"Press Enter to create a model.\",\n\t\t\t\t\t\t\"A draft is kept in memory until its id is set; Esc on the draft discards it.\",\n\t\t\t\t\t],\n\t\t\t\t\t() => this.activateLeftItem(\"activate\"),\n\t\t\t\t);\n\t\t\tcase \"deleteProvider\":\n\t\t\t\treturn new InfoPane(this.host, [\"Press Enter to delete this provider from models.json.\"], () =>\n\t\t\t\t\tthis.activateLeftItem(\"activate\"),\n\t\t\t\t);\n\t\t\tdefault:\n\t\t\t\treturn new InfoPane(this.host, []);\n\t\t}\n\t}\n\n\tprivate persistedHandle(modelId: string): ModelHandle {\n\t\treturn this.edits.model(modelId, (oldId, newId) => {\n\t\t\tconst selected = this.leftItems[this.leftIndex];\n\t\t\tif (selected?.kind === \"model\" && selected.modelId === oldId) selected.modelId = newId;\n\t\t\tthis.syncFromStore();\n\t\t});\n\t}\n\n\t// ------------------------------------------------------------------\n\t// EditorHost implementation\n\t// ------------------------------------------------------------------\n\n\tprivate createHost(): EditorHost {\n\t\tconst store = this.options.store;\n\t\tconst providerId = this.options.providerId;\n\t\treturn {\n\t\t\ttui: this.tui,\n\t\t\ttheme: this.theme,\n\t\t\tkeybindings: this.keybindings,\n\t\t\tstore,\n\t\t\tedits: this.edits,\n\t\t\tproviderId,\n\t\t\tpushPane: (pane) => this.pushPane(pane),\n\t\t\tpopPane: () => this.popPane(),\n\t\t\trefresh: () => this.refresh(),\n\t\t\tnotify: (message, type) => this.options.notify(message, type),\n\t\t\teffectiveApi: (model) => {\n\t\t\t\treturn effectiveModelSettings(providerId, store.getProvider(providerId), model).api;\n\t\t\t},\n\t\t\teffectiveBaseUrl: (model) => {\n\t\t\t\treturn effectiveModelSettings(providerId, store.getProvider(providerId), model).baseUrl;\n\t\t\t},\n\t\t\tcommitModelDraft: () => this.commitModelDraft(),\n\t\t\tdiscardModelDraft: () => this.discardModelDraft(),\n\t\t\tisCurrentModel: (modelId) =>\n\t\t\t\tthis.options.currentModel?.provider === providerId && this.options.currentModel.id === modelId,\n\t\t\tisCurrentProvider: () => this.options.currentModel?.provider === providerId,\n\t\t\tsetFetchStatus: (status) => {\n\t\t\t\tthis.fetchStatus = status;\n\t\t\t\tthis.refresh();\n\t\t\t},\n\t\t\trunFetch: (signal) => fetchProviderModels(this.options, signal),\n\t\t\timportModels: async (models, signal) => {\n\t\t\t\tconst error = await importProviderModels({ ...this.options, edits: this.edits }, models, signal);\n\t\t\t\tif (!this.disposed) this.syncFromStore();\n\t\t\t\treturn error;\n\t\t\t},\n\t\t\tconfirm: (message, actionLabel, action) =>\n\t\t\t\tthis.pushPane(new ConfirmPane(this.host, message, actionLabel, action)),\n\t\t\tonModelRemoved: () => {\n\t\t\t\tthis.rebuildLeftItems();\n\t\t\t\t// Land on the next row where the model was; walk back over section labels.\n\t\t\t\tthis.leftIndex = Math.min(this.leftIndex, this.leftItems.length - 1);\n\t\t\t\twhile (this.leftIndex > 0 && this.leftItems[this.leftIndex]?.kind === \"section\") this.leftIndex--;\n\t\t\t\tif (this.leftItems[this.leftIndex]?.kind === \"section\") this.leftIndex = this.selectableIndex(0);\n\t\t\t\tthis.focusPane = \"left\";\n\t\t\t\tthis.resetRightStack();\n\t\t\t\tthis.refresh();\n\t\t\t},\n\t\t};\n\t}\n\n\t/** Drop the in-memory draft: the selection returns to + Add Model with focus on the left. */\n\tprivate discardModelDraft(): void {\n\t\tif (!this.draft) return;\n\t\tthis.draft = undefined;\n\t\tthis.rebuildLeftItems();\n\t\tconst addIndex = this.leftItems.findIndex((item) => item.kind === \"addModel\");\n\t\tthis.leftIndex = addIndex >= 0 ? addIndex : this.selectableIndex(0);\n\t\tthis.focusPane = \"left\";\n\t\tthis.resetRightStack();\n\t\tthis.refresh();\n\t}\n\n\tprivate commitModelDraft(): string | undefined {\n\t\tconst draft = this.draft;\n\t\tif (!draft) return \"No model draft.\";\n\t\tconst error = this.edits.commitDraft(draft);\n\t\tif (error) return error;\n\t\tconst id = draft.read().id!.trim();\n\t\tthis.draft = undefined;\n\t\tthis.rebuildLeftItems();\n\t\tconst index = this.leftItems.findIndex((item) => item.kind === \"model\" && item.modelId === id);\n\t\tif (index >= 0) this.leftIndex = index;\n\t\tthis.resetRightStack();\n\t\tthis.refresh();\n\t\treturn undefined;\n\t}\n\n\t// ------------------------------------------------------------------\n\t// Frame rendering\n\t// ------------------------------------------------------------------\n\n\tprivate refresh(): void {\n\t\tthis.invalidate();\n\t\tthis.tui.requestRender();\n\t}\n\n\tprivate renderFrame(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\tif (width < MIN_WIDTH) {\n\t\t\treturn [\n\t\t\t\tborder,\n\t\t\t\ttruncateToWidth(theme.fg(\"warning\", ` /provider needs at least ${MIN_WIDTH} columns`), width),\n\t\t\t\tborder,\n\t\t\t];\n\t\t}\n\t\tconst title = this.renderTitle(width);\n\t\tlet body: string[];\n\t\tif (width < DOUBLE_PANE_MIN_WIDTH) {\n\t\t\tbody = this.focusPane === \"left\" ? this.renderLeft(width) : this.renderRight(width);\n\t\t} else {\n\t\t\tconst leftWidth = this.computeLeftWidth(width);\n\t\t\tconst rightWidth = width - leftWidth - 3;\n\t\t\tconst separator = theme.fg(\"border\", \" │ \");\n\t\t\tconst leftLines = this.renderLeft(leftWidth);\n\t\t\tconst rightLines = this.renderRight(rightWidth);\n\t\t\tbody = [];\n\t\t\tfor (let row = 0; row < BODY_ROWS; row++) {\n\t\t\t\tconst left = padTo(truncateToWidth(leftLines[row] ?? \"\", leftWidth), leftWidth);\n\t\t\t\tconst right = truncateToWidth(rightLines[row] ?? \"\", rightWidth);\n\t\t\t\tbody.push(left + separator + right);\n\t\t\t}\n\t\t}\n\n\t\tconst footerLines = this.renderFooter(width);\n\t\treturn [border, title, border, ...body, border, ...footerLines, border];\n\t}\n\n\tprivate renderRight(width: number): string[] {\n\t\tconst pane = this.topPane();\n\t\tconst paneLines = pane ? windowLines(this.theme, pane.render(width), BODY_ROWS - 1, pane.scrollWindow?.()) : [];\n\t\treturn [this.renderPaneTitle(width), ...paneLines];\n\t}\n\n\tprivate renderPaneTitle(width: number): string {\n\t\tconst item = this.leftItems[this.leftIndex];\n\t\tlet base = \"\";\n\t\tswitch (item?.kind) {\n\t\t\tcase \"apiAuth\":\n\t\t\t\tbase = \"Connection\";\n\t\t\t\tbreak;\n\t\t\tcase \"fetch\":\n\t\t\t\tbase = \"Discover models\";\n\t\t\t\tbreak;\n\t\t\tcase \"model\": {\n\t\t\t\tconst model = this.options.store.getModel(this.options.providerId, item.modelId);\n\t\t\t\tbase = model ? modelDisplayName(model) : item.modelId;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"draft\":\n\t\t\t\tbase = \"New model\";\n\t\t\t\tbreak;\n\t\t\tcase \"addModel\":\n\t\t\t\tbase = \"Add model\";\n\t\t\t\tbreak;\n\t\t\tcase \"deleteProvider\":\n\t\t\t\tbase = \"Delete provider\";\n\t\t\t\tbreak;\n\t\t}\n\t\tconst crumb = this.stack.length > 1 ? this.topPane()?.crumb : undefined;\n\t\tconst title = crumb ? [base, crumb].filter(Boolean).join(\" / \") : base;\n\t\treturn truncateToWidth(this.theme.fg(\"text\", this.theme.bold(title)), width);\n\t}\n\n\t/** Content-driven left width: fits the longest visible label, clamped to 16–40 and 45% of the terminal. */\n\tprivate computeLeftWidth(width: number): number {\n\t\tlet longest = 12;\n\t\tfor (const item of this.leftItems) {\n\t\t\tif (item.kind === \"section\") continue;\n\t\t\tconst { text, note } = this.leftItemContent(item);\n\t\t\tconst label = text + (note ? ` ${note}` : \"\");\n\t\t\tlongest = Math.max(longest, visibleWidth(label));\n\t\t}\n\t\tconst fit = Math.max(LEFT_WIDTH_MIN, Math.min(LEFT_WIDTH_MAX, longest + 2));\n\t\treturn Math.min(fit, Math.max(LEFT_WIDTH_MIN, Math.floor(width * 0.45)));\n\t}\n\n\tprivate renderTitle(width: number): string {\n\t\tconst theme = this.theme;\n\t\tconst title = theme.fg(\"accent\", theme.bold(` Providers / ${this.options.providerId}`));\n\t\tconst status =\n\t\t\tthis.options.store.pendingCount === 0 ? \"\" : this.options.store.saveFailed ? \"Save failed\" : \"Saving…\";\n\t\tif (!status) return truncateToWidth(title, width);\n\t\tconst styledStatus = theme.fg(this.options.store.saveFailed ? \"error\" : \"dim\", status);\n\t\tconst statusWidth = visibleWidth(status);\n\t\tif (statusWidth + 1 >= width) return truncateToWidth(styledStatus, width);\n\t\tconst left = truncateToWidth(title, width - statusWidth - 1);\n\t\treturn padTo(left, width - statusWidth) + styledStatus;\n\t}\n\n\tprivate renderFooter(width: number): string[] {\n\t\tif (this.focusPane === \"right\") {\n\t\t\tconst paneHints = this.topPane()?.hints() ?? \"\";\n\t\t\tif (width < DOUBLE_PANE_MIN_WIDTH) {\n\t\t\t\t// Esc already returns to navigation here; only add the arrow hint when it fits whole.\n\t\t\t\tconst arrowHint = keyHint(\"app.provider.switchPaneLeft\", \"nav\");\n\t\t\t\tconst combined = [paneHints, arrowHint].filter(Boolean).join(\" \");\n\t\t\t\treturn [truncateToWidth(visibleWidth(combined) <= width ? combined : paneHints, width)];\n\t\t\t}\n\t\t\t// The editor owns the way-back hint so every wide-layout pane footer is consistent.\n\t\t\tconst hints = [paneHints, keyHint(\"app.provider.switchPaneLeft\", \"focus left\")].filter(Boolean).join(\" \");\n\t\t\treturn [truncateToWidth(hints, width)];\n\t\t}\n\t\tconst hints = [\n\t\t\trawKeyHint(\"↑↓\", \"move\"),\n\t\t\tkeyHint(\"tui.select.confirm\", this.leftActivateLabel()),\n\t\t\tkeyHint(\"app.provider.switchPaneRight\", \"focus right\"),\n\t\t\tkeyHint(\"tui.select.cancel\", \"back\"),\n\t\t].join(\" \");\n\t\treturn [truncateToWidth(hints, width)];\n\t}\n\n\t/** What Enter does to the selected left-column row, so the footer never lies about action rows. */\n\tprivate leftActivateLabel(): string {\n\t\tswitch (this.leftItems[this.leftIndex]?.kind) {\n\t\t\tcase \"fetch\":\n\t\t\t\treturn \"fetch\";\n\t\t\tcase \"addModel\":\n\t\t\t\treturn \"create\";\n\t\t\tcase \"deleteProvider\":\n\t\t\t\treturn \"delete\";\n\t\t\tdefault:\n\t\t\t\treturn \"open\";\n\t\t}\n\t}\n}\n\nfunction modelDisplayName(model: ModelsJsonModel): string {\n\treturn model.name ?? model.id;\n}\n"]}
|
|
@@ -1 +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;
|
|
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;AACvE,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;IAyE/B,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAuB/B,OAAO,CAAC,OAAO;IAsBf,OAAO,CAAC,MAAM;CAUd"}
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import { fuzzyFilter, truncateToWidth } from "@earendil-works/pi-tui";
|
|
3
3
|
import { DynamicBorder } from "../../../modes/interactive/components/dynamic-border.js";
|
|
4
4
|
import { keyHint, rawKeyHint } from "../../../modes/interactive/components/keybinding-hints.js";
|
|
5
|
-
import { plural } from "../constants.js";
|
|
6
5
|
import { renderInfoLine, renderKeyValueLine, renderPlainLine, ValueEditor, windowLines } from "./value-row.js";
|
|
7
6
|
/** Fixed list-area height: the screen frame matches the provider editor's. */
|
|
8
7
|
const LIST_ROWS = 12;
|
|
@@ -34,9 +33,10 @@ export class ProviderListScreen {
|
|
|
34
33
|
render(width) {
|
|
35
34
|
const theme = this.theme;
|
|
36
35
|
const border = new DynamicBorder((text) => theme.fg("border", text)).render(width)[0] ?? "";
|
|
36
|
+
const title = this.mode === "list" ? " Providers" : " New provider";
|
|
37
37
|
const lines = [
|
|
38
38
|
border,
|
|
39
|
-
truncateToWidth(theme.fg("accent", theme.bold(
|
|
39
|
+
truncateToWidth(theme.fg("accent", theme.bold(title)), width),
|
|
40
40
|
border,
|
|
41
41
|
renderKeyValueLine(theme, {
|
|
42
42
|
keyLabel: this.mode === "list" ? "Search" : "Provider id",
|
|
@@ -57,30 +57,24 @@ export class ProviderListScreen {
|
|
|
57
57
|
const rows = [];
|
|
58
58
|
for (let row = 0; row < total; row++) {
|
|
59
59
|
const id = entries[row - 1];
|
|
60
|
-
|
|
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, {
|
|
60
|
+
rows.push(renderPlainLine(theme, row === 0 ? "+ Add provider" : id, {
|
|
72
61
|
active: row === this.index,
|
|
73
62
|
paneFocused: this.active,
|
|
74
|
-
note,
|
|
75
63
|
width,
|
|
76
64
|
}));
|
|
77
65
|
}
|
|
78
|
-
if (entries.length === 0)
|
|
79
|
-
|
|
66
|
+
if (entries.length === 0) {
|
|
67
|
+
const query = this.query.trim();
|
|
68
|
+
rows.push(renderInfoLine(theme, query ? `No providers match “${query}”.` : "No providers configured.", width));
|
|
69
|
+
rows.push(renderInfoLine(theme, query ? `Enter will create provider “${query}”.` : "Enter starts a new provider.", width));
|
|
70
|
+
}
|
|
80
71
|
area.push(...windowLines(theme, rows, LIST_ROWS, { cursor: this.index }));
|
|
81
72
|
}
|
|
82
|
-
else
|
|
83
|
-
|
|
73
|
+
else {
|
|
74
|
+
const id = this.input.value.trim();
|
|
75
|
+
area.push(renderInfoLine(theme, id ? `This becomes the providers.${id} key in models.json.` : "Choose a unique provider id.", width));
|
|
76
|
+
if (this.error)
|
|
77
|
+
area.push(truncateToWidth(theme.fg("error", this.error), width));
|
|
84
78
|
}
|
|
85
79
|
while (area.length < LIST_ROWS)
|
|
86
80
|
area.push("");
|