pi-one-ui 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -39
- package/extensions/{shell → app/commands}/settings-previews.ts +7 -7
- package/extensions/app/config/renderer.ts +13 -63
- package/extensions/app/config/shell.ts +24 -138
- package/extensions/app/config/store.ts +290 -0
- package/extensions/app/host/pi-extension-port.ts +25 -0
- package/extensions/app/host/pi-ui-port.ts +52 -0
- package/extensions/app/host/tui-capabilities.ts +27 -0
- package/extensions/app/overlay/input-router.ts +63 -0
- package/extensions/app/overlay/overlay-manager.ts +39 -0
- package/extensions/{shell → app/overlay}/selector-border.ts +3 -3
- package/extensions/app/overlay/selector-controller.ts +104 -0
- package/extensions/app/ownership/layout-registry.ts +65 -0
- package/extensions/app/ownership.ts +21 -7
- package/extensions/app/panel.ts +261 -140
- package/extensions/app/runtime/event-coordinator.ts +84 -0
- package/extensions/app/runtime/render-scheduler.ts +56 -0
- package/extensions/app/runtime/runtime-state.ts +83 -0
- package/extensions/app/runtime/tui-runtime.ts +546 -0
- package/extensions/features/{context.ts → context-inspector/index.ts} +30 -23
- package/extensions/features/{shell/flush-docked-bash.ts → flush-docked-bash.ts} +1 -4
- package/extensions/index.ts +2 -48
- package/extensions/layouts/context/index.ts +188 -0
- package/extensions/{shell → layouts/context/message}/user-message-styles.ts +2 -2
- package/extensions/{shell → layouts/context/message}/user-message.ts +2 -2
- package/extensions/{transcript → layouts/context}/renderer/compact-mode.ts +17 -13
- package/extensions/layouts/context/renderer/context-refresh.ts +79 -0
- package/extensions/{transcript → layouts/context}/renderer/default-mode.ts +3 -3
- package/extensions/{transcript → layouts/context}/renderer/index.ts +14 -14
- package/extensions/{transcript → layouts/context}/renderer/mouse/hover.ts +2 -2
- package/extensions/{transcript → layouts/context}/renderer/mouse/interaction.ts +26 -7
- package/extensions/{transcript → layouts/context}/renderer/mouse/layout.ts +1 -1
- package/extensions/{transcript → layouts/context}/renderer/mouse/packets.ts +3 -3
- package/extensions/{transcript → layouts/context}/renderer/mouse/scroll.ts +12 -7
- package/extensions/{transcript → layouts/context}/renderer/tool/diff/diff-component.ts +2 -2
- package/extensions/{transcript → layouts/context}/renderer/tool/diff/diff-edit-render.ts +1 -1
- package/extensions/{transcript → layouts/context}/renderer/tool/diff/diff-highlight.ts +1 -1
- package/extensions/{transcript → layouts/context}/renderer/tool/diff/diff-layout.ts +1 -1
- package/extensions/{transcript → layouts/context}/renderer/tool/diff/diff-limits.ts +1 -1
- package/extensions/{transcript → layouts/context}/renderer/tool/diff/diff-palette.ts +1 -1
- package/extensions/{transcript → layouts/context}/renderer/tool/diff/diff-presentation.ts +1 -1
- package/extensions/{transcript → layouts/context}/renderer/tool/diff/diff-renderer.ts +1 -1
- package/extensions/{transcript → layouts/context}/renderer/tool/diff/diff-write-render.ts +1 -1
- package/extensions/{transcript → layouts/context}/renderer/tool/diff/index.ts +2 -2
- package/extensions/{transcript → layouts/context}/renderer/tool/grouping.ts +4 -4
- package/extensions/{transcript → layouts/context}/renderer/tool/message-display.ts +6 -4
- package/extensions/{transcript → layouts/context}/renderer/tool/names.ts +2 -2
- package/extensions/{transcript → layouts/context}/renderer/tool/result.ts +3 -3
- package/extensions/{features/agent-summary → layouts/context/summary}/core.ts +1 -1
- package/extensions/{features → layouts/context/thinking}/compact-thinking.ts +7 -7
- package/extensions/{shell → layouts/editor}/accent-rail-editor.ts +8 -8
- package/extensions/{shell → layouts/editor}/completion-menu.ts +3 -6
- package/extensions/layouts/editor/controller.ts +613 -0
- package/extensions/{shell → layouts/editor}/editor-metadata-format.ts +6 -3
- package/extensions/layouts/editor/factory.ts +159 -0
- package/extensions/layouts/editor/index.ts +16 -0
- package/extensions/{shell → layouts/editor}/minimalist-editor.ts +4 -4
- package/extensions/layouts/editor/ownership.ts +103 -0
- package/extensions/{shell → layouts/editor}/ui.ts +2 -2
- package/extensions/layouts/footer/controller.ts +392 -0
- package/extensions/layouts/footer/data.ts +41 -0
- package/extensions/{shell → layouts/footer}/extension-status.ts +2 -2
- package/extensions/{shell → layouts/footer}/footer-layout.ts +1 -1
- package/extensions/{shell → layouts/footer}/footer.ts +11 -8
- package/extensions/layouts/footer/index.ts +24 -0
- package/extensions/layouts/header/index.ts +5 -0
- package/extensions/{features/shell → layouts/header}/startup-header.ts +105 -19
- package/extensions/layouts/working-line/controller.ts +291 -0
- package/extensions/{shell → layouts/working-line}/interaction-summary.ts +3 -3
- package/extensions/{shell → layouts/working-line}/working-line-spinners.ts +1 -1
- package/extensions/{shell → layouts/working-line}/working-line.ts +4 -4
- package/extensions/{shell → services}/live-context.ts +29 -1
- package/extensions/services/project-refresh.ts +374 -0
- package/extensions/{shell → services}/project-state.ts +5 -5
- package/extensions/{shell/state.ts → services/session-state.ts} +75 -5
- package/extensions/{shell → shared}/format.ts +4 -4
- package/extensions/tools/component-tree.ts +6 -6
- package/package.json +4 -4
- package/extensions/shell/index.ts +0 -1659
- package/extensions/shell/project-refresh.ts +0 -130
- package/extensions/shell/settings-command.ts +0 -2144
- package/extensions/transcript/index.ts +0 -65
- package/extensions/transcript/renderer/transcript-refresh.ts +0 -79
- /package/extensions/{shell → app/ownership}/prototype-patch-registry.ts +0 -0
- /package/extensions/{shell → app/runtime}/session-lifecycle.ts +0 -0
- /package/extensions/features/{shell/aliases.ts → aliases.ts} +0 -0
- /package/extensions/features/{shell → legacy}/working-message.ts +0 -0
- /package/extensions/features/{reference → session-reference}/index.ts +0 -0
- /package/extensions/features/{reference → session-reference}/session.ts +0 -0
- /package/extensions/features/{reference/subagent.ts → subagent-autocomplete.ts} +0 -0
- /package/extensions/{shell → layouts/context/message}/user-message-osc.ts +0 -0
- /package/extensions/{transcript → layouts/context}/renderer/markdown-enhance.ts +0 -0
- /package/extensions/{transcript → layouts/context}/renderer/tool/diff/ATTRIBUTION.md +0 -0
- /package/extensions/{transcript → layouts/context}/renderer/tool/diff/ansi-utils.ts +0 -0
- /package/extensions/{transcript → layouts/context}/renderer/tool/diff/diff-header.ts +0 -0
- /package/extensions/{transcript → layouts/context}/renderer/tool/diff/diff-inline.ts +0 -0
- /package/extensions/{transcript → layouts/context}/renderer/tool/diff/diff-parse.ts +0 -0
- /package/extensions/{transcript → layouts/context}/renderer/tool/diff/diff-text.ts +0 -0
- /package/extensions/{transcript → layouts/context}/renderer/tool/diff/line-width-safety.ts +0 -0
- /package/extensions/{transcript → layouts/context}/renderer/tool/diff/shiki-highlight.ts +0 -0
- /package/extensions/{transcript → layouts/context}/renderer/tool/diff/write-execution.ts +0 -0
- /package/extensions/{transcript → layouts/context}/renderer/tool/show-more-hint.ts +0 -0
- /package/extensions/{features/agent-summary → layouts/context/summary}/index.ts +0 -0
- /package/extensions/{shell → layouts/editor}/accent-rail-layout-patch.ts +0 -0
- /package/extensions/{shell → layouts/editor}/editor-transfer.ts +0 -0
- /package/extensions/{shell → layouts/footer}/footer-format.ts +0 -0
- /package/extensions/{shell → layouts/working-line}/working-line-messages.ts +0 -0
- /package/extensions/{shell/git.ts → services/git-data.ts} +0 -0
- /package/extensions/{shell/package-version.ts → services/package-data.ts} +0 -0
- /package/extensions/{shell/runtime.ts → services/runtime-data.ts} +0 -0
- /package/extensions/{shell → services}/telemetry.ts +0 -0
- /package/extensions/{shell → shared}/icons.ts +0 -0
- /package/extensions/{shell → shared}/style.ts +0 -0
|
@@ -1,18 +1,32 @@
|
|
|
1
|
+
/** Legacy slot map retained for existing callers during Layout extraction. */
|
|
1
2
|
export const UI_OWNERSHIP = {
|
|
2
|
-
editor: "
|
|
3
|
-
userMessage: "
|
|
3
|
+
editor: "editor",
|
|
4
|
+
userMessage: "context",
|
|
4
5
|
footer: "shell",
|
|
5
6
|
workingLine: "shell",
|
|
6
|
-
selector: "
|
|
7
|
-
toolRenderer: "
|
|
8
|
-
diffRenderer: "
|
|
9
|
-
thinking: "
|
|
10
|
-
agentSummary: "
|
|
7
|
+
selector: "overlay",
|
|
8
|
+
toolRenderer: "context",
|
|
9
|
+
diffRenderer: "context",
|
|
10
|
+
thinking: "context",
|
|
11
|
+
agentSummary: "context",
|
|
11
12
|
} as const;
|
|
12
13
|
|
|
13
14
|
export type UiSlot = keyof typeof UI_OWNERSHIP;
|
|
14
15
|
export type UiOwner = (typeof UI_OWNERSHIP)[UiSlot];
|
|
15
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Returns the canonical visual owner for a Pi UI slot.
|
|
19
|
+
*
|
|
20
|
+
* @param slot UI slot to resolve.
|
|
21
|
+
* @returns Canonical owner identifier.
|
|
22
|
+
*/
|
|
16
23
|
export function ownerFor(slot: UiSlot): UiOwner {
|
|
17
24
|
return UI_OWNERSHIP[slot];
|
|
18
25
|
}
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
LAYOUT_OWNERSHIP,
|
|
29
|
+
LayoutRegistry,
|
|
30
|
+
type LayoutId,
|
|
31
|
+
type LayoutOwner,
|
|
32
|
+
} from "./ownership/layout-registry.ts";
|
package/extensions/app/panel.ts
CHANGED
|
@@ -1,26 +1,29 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type ExtensionContext,
|
|
3
|
+
getSettingsListTheme,
|
|
4
|
+
} from "@earendil-works/pi-coding-agent";
|
|
2
5
|
import {
|
|
3
6
|
matchesKey,
|
|
4
7
|
type SettingItem,
|
|
5
8
|
SettingsList,
|
|
6
9
|
truncateToWidth,
|
|
7
10
|
} from "@earendil-works/pi-tui";
|
|
8
|
-
import type { ShellRuntimeController } from "../shell/index.ts";
|
|
9
11
|
import {
|
|
10
12
|
renderEditorSettingsPreview,
|
|
11
13
|
renderUserMessageSettingsPreview,
|
|
12
|
-
} from "
|
|
13
|
-
import type { TranscriptRuntimeController } from "../transcript/index.ts";
|
|
14
|
+
} from "./commands/settings-previews.ts";
|
|
14
15
|
import {
|
|
15
16
|
type CompactStyleMode,
|
|
17
|
+
type Config as ContextConfig,
|
|
16
18
|
DIFF_INDICATOR_MODES,
|
|
17
19
|
DIFF_VIEW_MODES,
|
|
18
|
-
type Config as RendererConfig,
|
|
19
20
|
config as rendererConfig,
|
|
20
|
-
updateConfig as
|
|
21
|
+
updateConfig as updateContextConfig,
|
|
21
22
|
} from "./config/renderer.ts";
|
|
22
23
|
import {
|
|
24
|
+
type EditorComponentConfig,
|
|
23
25
|
type EditorStyle,
|
|
26
|
+
type FooterComponentConfig,
|
|
24
27
|
type FooterStyle,
|
|
25
28
|
loadConfig as loadShellConfig,
|
|
26
29
|
saveEditorComponentPatch,
|
|
@@ -28,8 +31,11 @@ import {
|
|
|
28
31
|
saveUserMessagesComponentPatch,
|
|
29
32
|
saveWorkingLineComponentPatch,
|
|
30
33
|
type UserMessageStyle,
|
|
34
|
+
type UserMessagesComponentConfig,
|
|
35
|
+
type WorkingLineComponentPatch,
|
|
31
36
|
type WorkingLineSpinner,
|
|
32
37
|
} from "./config/shell.ts";
|
|
38
|
+
import { overlayManager } from "./overlay/overlay-manager.ts";
|
|
33
39
|
import { ownerFor } from "./ownership.ts";
|
|
34
40
|
import { applyPreset, PRESET_VALUES, type Preset } from "./presets.ts";
|
|
35
41
|
|
|
@@ -56,8 +62,11 @@ const WORKING_SPINNERS: WorkingLineSpinner[] = [
|
|
|
56
62
|
const PREVIEW_LINES = ["0", "1", "3", "5", "10"];
|
|
57
63
|
|
|
58
64
|
const SECTIONS = [
|
|
59
|
-
{ id: "
|
|
60
|
-
{ id: "
|
|
65
|
+
{ id: "header", label: "Header" },
|
|
66
|
+
{ id: "context", label: "Context" },
|
|
67
|
+
{ id: "workingLine", label: "WorkingLine" },
|
|
68
|
+
{ id: "editor", label: "Editor" },
|
|
69
|
+
{ id: "footer", label: "Footer" },
|
|
61
70
|
{ id: "features", label: "Features" },
|
|
62
71
|
{ id: "presets", label: "Presets" },
|
|
63
72
|
] as const;
|
|
@@ -77,10 +86,16 @@ function renderTabs(theme: any, active: number, width: number): string {
|
|
|
77
86
|
|
|
78
87
|
function sectionDescription(section: SectionId): string {
|
|
79
88
|
switch (section) {
|
|
80
|
-
case "
|
|
81
|
-
return
|
|
82
|
-
case "
|
|
83
|
-
return `${ownerFor("toolRenderer")} owns tool cards,
|
|
89
|
+
case "header":
|
|
90
|
+
return "Header owns startup branding and startup guidance.";
|
|
91
|
+
case "context":
|
|
92
|
+
return `${ownerFor("toolRenderer")} owns messages, tool cards, diffs, thinking, and summaries.`;
|
|
93
|
+
case "workingLine":
|
|
94
|
+
return "WorkingLine is the sole owner of Pi's unkeyed working row.";
|
|
95
|
+
case "editor":
|
|
96
|
+
return `${ownerFor("editor")} owns the input editor factory and its styles.`;
|
|
97
|
+
case "footer":
|
|
98
|
+
return `${ownerFor("footer")} owns footer rendering and project status segments.`;
|
|
84
99
|
case "features":
|
|
85
100
|
return "Feature switches are saved immediately and applied after /reload.";
|
|
86
101
|
case "presets":
|
|
@@ -88,13 +103,16 @@ function sectionDescription(section: SectionId): string {
|
|
|
88
103
|
}
|
|
89
104
|
}
|
|
90
105
|
|
|
91
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Builds settings owned by the Editor layout.
|
|
108
|
+
*/
|
|
109
|
+
function editorItems(): SettingItem[] {
|
|
92
110
|
const config = loadShellConfig();
|
|
93
111
|
return [
|
|
94
112
|
{
|
|
95
113
|
id: "editorEnabled",
|
|
96
114
|
label: "Editor",
|
|
97
|
-
description: "Enable
|
|
115
|
+
description: "Enable the custom input editor.",
|
|
98
116
|
currentValue: onOff(config.components.editor.enabled),
|
|
99
117
|
values: ["on", "off"],
|
|
100
118
|
},
|
|
@@ -105,24 +123,19 @@ function shellItems(): SettingItem[] {
|
|
|
105
123
|
currentValue: config.components.editor.style,
|
|
106
124
|
values: EDITOR_STYLES,
|
|
107
125
|
},
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
label: "Message style",
|
|
118
|
-
description: "Choose the previous user message treatment.",
|
|
119
|
-
currentValue: config.components.userMessages.style,
|
|
120
|
-
values: MESSAGE_STYLES,
|
|
121
|
-
},
|
|
126
|
+
];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Builds settings owned by the WorkingLine layout.
|
|
131
|
+
*/
|
|
132
|
+
function workingLineItems(): SettingItem[] {
|
|
133
|
+
const config = loadShellConfig();
|
|
134
|
+
return [
|
|
122
135
|
{
|
|
123
136
|
id: "workingLineEnabled",
|
|
124
137
|
label: "Working line",
|
|
125
|
-
description: "
|
|
138
|
+
description: "Enable the sole owner of Pi's working row.",
|
|
126
139
|
currentValue: onOff(config.components.workingLine.enabled),
|
|
127
140
|
values: ["on", "off"],
|
|
128
141
|
},
|
|
@@ -133,6 +146,15 @@ function shellItems(): SettingItem[] {
|
|
|
133
146
|
currentValue: config.components.workingLine.spinner,
|
|
134
147
|
values: WORKING_SPINNERS,
|
|
135
148
|
},
|
|
149
|
+
];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Builds settings owned by the Footer layout.
|
|
154
|
+
*/
|
|
155
|
+
function footerItems(): SettingItem[] {
|
|
156
|
+
const config = loadShellConfig();
|
|
157
|
+
return [
|
|
136
158
|
{
|
|
137
159
|
id: "footerStyle",
|
|
138
160
|
label: "Footer",
|
|
@@ -143,10 +165,28 @@ function shellItems(): SettingItem[] {
|
|
|
143
165
|
];
|
|
144
166
|
}
|
|
145
167
|
|
|
146
|
-
|
|
168
|
+
/**
|
|
169
|
+
* Builds settings owned by the Context layout.
|
|
170
|
+
*/
|
|
171
|
+
function contextItems(config: ContextConfig): SettingItem[] {
|
|
172
|
+
const shellConfig = loadShellConfig();
|
|
147
173
|
return [
|
|
148
174
|
{
|
|
149
|
-
id: "
|
|
175
|
+
id: "userMessagesEnabled",
|
|
176
|
+
label: "User messages",
|
|
177
|
+
description: "Enable custom rendering for previous user messages.",
|
|
178
|
+
currentValue: onOff(shellConfig.components.userMessages.enabled),
|
|
179
|
+
values: ["on", "off"],
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
id: "userMessagesStyle",
|
|
183
|
+
label: "Message style",
|
|
184
|
+
description: "Choose the previous user message treatment.",
|
|
185
|
+
currentValue: shellConfig.components.userMessages.style,
|
|
186
|
+
values: MESSAGE_STYLES,
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
id: "contextMode",
|
|
150
190
|
label: "Tool style",
|
|
151
191
|
description:
|
|
152
192
|
"on = rich cards, compact = one summary per assistant message, off = native.",
|
|
@@ -191,7 +231,25 @@ function rendererItems(config: RendererConfig): SettingItem[] {
|
|
|
191
231
|
];
|
|
192
232
|
}
|
|
193
233
|
|
|
194
|
-
|
|
234
|
+
/**
|
|
235
|
+
* Builds settings owned by the Header layout.
|
|
236
|
+
*/
|
|
237
|
+
function headerItems(config: ContextConfig): SettingItem[] {
|
|
238
|
+
return [
|
|
239
|
+
{
|
|
240
|
+
id: "showStartupHeader",
|
|
241
|
+
label: "Startup header",
|
|
242
|
+
description: "Show the custom startup header on new sessions.",
|
|
243
|
+
currentValue: onOff(config.showStartupHeader),
|
|
244
|
+
values: ["on", "off"],
|
|
245
|
+
},
|
|
246
|
+
];
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Builds non-visual feature switches.
|
|
251
|
+
*/
|
|
252
|
+
function featureItems(config: ContextConfig): SettingItem[] {
|
|
195
253
|
return [
|
|
196
254
|
{
|
|
197
255
|
id: "enableSessionReference",
|
|
@@ -228,13 +286,6 @@ function featureItems(config: RendererConfig): SettingItem[] {
|
|
|
228
286
|
currentValue: onOff(config.enableAliases),
|
|
229
287
|
values: ["on", "off"],
|
|
230
288
|
},
|
|
231
|
-
{
|
|
232
|
-
id: "showStartupHeader",
|
|
233
|
-
label: "Startup header",
|
|
234
|
-
description: "Show CC Style's startup header on new sessions.",
|
|
235
|
-
currentValue: onOff(config.showStartupHeader),
|
|
236
|
-
values: ["on", "off"],
|
|
237
|
-
},
|
|
238
289
|
];
|
|
239
290
|
}
|
|
240
291
|
|
|
@@ -244,10 +295,10 @@ function presetItems(): SettingItem[] {
|
|
|
244
295
|
label: preset,
|
|
245
296
|
description:
|
|
246
297
|
preset === "balanced"
|
|
247
|
-
? "Zentui shell + rich CC Style
|
|
298
|
+
? "Zentui shell + rich CC Style context renderer."
|
|
248
299
|
: preset === "compact"
|
|
249
|
-
? "Zentui shell + compact CC Style
|
|
250
|
-
: "Disable custom shell and
|
|
300
|
+
? "Zentui shell + compact CC Style context."
|
|
301
|
+
: "Disable custom shell and context rendering.",
|
|
251
302
|
currentValue: "apply",
|
|
252
303
|
values: ["apply"],
|
|
253
304
|
}));
|
|
@@ -255,10 +306,16 @@ function presetItems(): SettingItem[] {
|
|
|
255
306
|
|
|
256
307
|
function itemsFor(section: SectionId): SettingItem[] {
|
|
257
308
|
switch (section) {
|
|
258
|
-
case "
|
|
259
|
-
return
|
|
260
|
-
case "
|
|
261
|
-
return
|
|
309
|
+
case "header":
|
|
310
|
+
return headerItems(rendererConfig);
|
|
311
|
+
case "context":
|
|
312
|
+
return contextItems(rendererConfig);
|
|
313
|
+
case "workingLine":
|
|
314
|
+
return workingLineItems();
|
|
315
|
+
case "editor":
|
|
316
|
+
return editorItems();
|
|
317
|
+
case "footer":
|
|
318
|
+
return footerItems();
|
|
262
319
|
case "features":
|
|
263
320
|
return featureItems(rendererConfig);
|
|
264
321
|
case "presets":
|
|
@@ -270,12 +327,38 @@ function isOn(value: string): boolean {
|
|
|
270
327
|
return value === "on";
|
|
271
328
|
}
|
|
272
329
|
|
|
330
|
+
export type TuiPanelRuntime = {
|
|
331
|
+
setEditorComponent: (
|
|
332
|
+
patch: Partial<EditorComponentConfig>,
|
|
333
|
+
ctx: ExtensionContext,
|
|
334
|
+
) => { applied: boolean; reason?: string };
|
|
335
|
+
setUserMessagesComponent: (
|
|
336
|
+
patch: Partial<UserMessagesComponentConfig>,
|
|
337
|
+
ctx: ExtensionContext,
|
|
338
|
+
) => void;
|
|
339
|
+
setWorkingLineComponent: (
|
|
340
|
+
patch: WorkingLineComponentPatch,
|
|
341
|
+
ctx: ExtensionContext,
|
|
342
|
+
) => { applied: boolean; reason?: string };
|
|
343
|
+
setFooterComponent: (
|
|
344
|
+
patch: Partial<FooterComponentConfig>,
|
|
345
|
+
ctx: ExtensionContext,
|
|
346
|
+
) => void;
|
|
347
|
+
setContextMode: (mode: CompactStyleMode, ctx: ExtensionContext) => void;
|
|
348
|
+
updateContextConfig: (
|
|
349
|
+
patch: Partial<ContextConfig>,
|
|
350
|
+
ctx: ExtensionContext,
|
|
351
|
+
) => void;
|
|
352
|
+
};
|
|
353
|
+
|
|
273
354
|
type UnifiedPanelDeps = {
|
|
274
|
-
|
|
275
|
-
renderer?: TranscriptRuntimeController;
|
|
355
|
+
runtime?: TuiPanelRuntime;
|
|
276
356
|
};
|
|
277
357
|
|
|
278
|
-
|
|
358
|
+
/**
|
|
359
|
+
* Renders the Editor layout preview for the settings panel.
|
|
360
|
+
*/
|
|
361
|
+
function renderEditorPreview(theme: any, width: number): string[] {
|
|
279
362
|
const config = loadShellConfig();
|
|
280
363
|
const previewWidth = Math.max(20, Math.min(72, width - 2));
|
|
281
364
|
return [
|
|
@@ -284,6 +367,16 @@ function renderShellPreview(theme: any, width: number): string[] {
|
|
|
284
367
|
...renderEditorSettingsPreview(config, theme, previewWidth).map(
|
|
285
368
|
(line) => ` ${line}`,
|
|
286
369
|
),
|
|
370
|
+
];
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Renders the Context layout User Message preview for the settings panel.
|
|
375
|
+
*/
|
|
376
|
+
function renderContextPreview(theme: any, width: number): string[] {
|
|
377
|
+
const config = loadShellConfig();
|
|
378
|
+
const previewWidth = Math.max(20, Math.min(72, width - 2));
|
|
379
|
+
return [
|
|
287
380
|
"",
|
|
288
381
|
theme.fg("muted", " User message preview"),
|
|
289
382
|
...renderUserMessageSettingsPreview(config, theme, previewWidth).map(
|
|
@@ -299,6 +392,14 @@ function saveNotice(ctx: any, label: string, value: string): void {
|
|
|
299
392
|
);
|
|
300
393
|
}
|
|
301
394
|
|
|
395
|
+
/**
|
|
396
|
+
* Persists one panel setting and reconciles its owning runtime layout.
|
|
397
|
+
*
|
|
398
|
+
* @param id Stable settings item identifier.
|
|
399
|
+
* @param value Selected settings value.
|
|
400
|
+
* @param ctx Active Pi extension context.
|
|
401
|
+
* @param deps Live runtime controllers available to the panel.
|
|
402
|
+
*/
|
|
302
403
|
function updateSetting(
|
|
303
404
|
id: string,
|
|
304
405
|
value: string,
|
|
@@ -306,22 +407,22 @@ function updateSetting(
|
|
|
306
407
|
deps: UnifiedPanelDeps,
|
|
307
408
|
): void {
|
|
308
409
|
if (id === "editorEnabled") {
|
|
309
|
-
if (deps.
|
|
310
|
-
deps.
|
|
410
|
+
if (deps.runtime)
|
|
411
|
+
deps.runtime.setEditorComponent({ enabled: isOn(value) }, ctx);
|
|
311
412
|
else saveEditorComponentPatch({ enabled: isOn(value) });
|
|
312
413
|
saveNotice(ctx, "Editor", value);
|
|
313
414
|
return;
|
|
314
415
|
}
|
|
315
416
|
if (id === "editorStyle" && EDITOR_STYLES.includes(value as EditorStyle)) {
|
|
316
|
-
if (deps.
|
|
317
|
-
deps.
|
|
417
|
+
if (deps.runtime)
|
|
418
|
+
deps.runtime.setEditorComponent({ style: value as EditorStyle }, ctx);
|
|
318
419
|
else saveEditorComponentPatch({ style: value as EditorStyle });
|
|
319
420
|
saveNotice(ctx, "Editor style", value);
|
|
320
421
|
return;
|
|
321
422
|
}
|
|
322
423
|
if (id === "userMessagesEnabled") {
|
|
323
|
-
if (deps.
|
|
324
|
-
deps.
|
|
424
|
+
if (deps.runtime)
|
|
425
|
+
deps.runtime.setUserMessagesComponent({ enabled: isOn(value) }, ctx);
|
|
325
426
|
else saveUserMessagesComponentPatch({ enabled: isOn(value) });
|
|
326
427
|
saveNotice(ctx, "User messages", value);
|
|
327
428
|
return;
|
|
@@ -330,8 +431,8 @@ function updateSetting(
|
|
|
330
431
|
id === "userMessagesStyle" &&
|
|
331
432
|
MESSAGE_STYLES.includes(value as UserMessageStyle)
|
|
332
433
|
) {
|
|
333
|
-
if (deps.
|
|
334
|
-
deps.
|
|
434
|
+
if (deps.runtime)
|
|
435
|
+
deps.runtime.setUserMessagesComponent(
|
|
335
436
|
{ style: value as UserMessageStyle },
|
|
336
437
|
ctx,
|
|
337
438
|
);
|
|
@@ -340,8 +441,8 @@ function updateSetting(
|
|
|
340
441
|
return;
|
|
341
442
|
}
|
|
342
443
|
if (id === "workingLineEnabled") {
|
|
343
|
-
if (deps.
|
|
344
|
-
deps.
|
|
444
|
+
if (deps.runtime)
|
|
445
|
+
deps.runtime.setWorkingLineComponent({ enabled: isOn(value) }, ctx);
|
|
345
446
|
else saveWorkingLineComponentPatch({ enabled: isOn(value) });
|
|
346
447
|
saveNotice(ctx, "Working line", value);
|
|
347
448
|
return;
|
|
@@ -350,8 +451,8 @@ function updateSetting(
|
|
|
350
451
|
id === "workingLineSpinner" &&
|
|
351
452
|
WORKING_SPINNERS.includes(value as WorkingLineSpinner)
|
|
352
453
|
) {
|
|
353
|
-
if (deps.
|
|
354
|
-
deps.
|
|
454
|
+
if (deps.runtime)
|
|
455
|
+
deps.runtime.setWorkingLineComponent(
|
|
355
456
|
{ spinner: value as WorkingLineSpinner },
|
|
356
457
|
ctx,
|
|
357
458
|
);
|
|
@@ -361,22 +462,23 @@ function updateSetting(
|
|
|
361
462
|
return;
|
|
362
463
|
}
|
|
363
464
|
if (id === "footerStyle" && FOOTER_STYLES.includes(value as FooterStyle)) {
|
|
364
|
-
if (deps.
|
|
365
|
-
deps.
|
|
465
|
+
if (deps.runtime)
|
|
466
|
+
deps.runtime.setFooterComponent({ style: value as FooterStyle }, ctx);
|
|
366
467
|
else saveFooterComponentPatch({ style: value as FooterStyle });
|
|
367
468
|
saveNotice(ctx, "Footer", value);
|
|
368
469
|
return;
|
|
369
470
|
}
|
|
370
|
-
if (id === "
|
|
371
|
-
if (deps.
|
|
372
|
-
|
|
471
|
+
if (id === "contextMode") {
|
|
472
|
+
if (deps.runtime)
|
|
473
|
+
deps.runtime.setContextMode(value as CompactStyleMode, ctx);
|
|
474
|
+
else updateContextConfig({ mode: value as CompactStyleMode });
|
|
373
475
|
saveNotice(ctx, "Tool style", value);
|
|
374
476
|
return;
|
|
375
477
|
}
|
|
376
478
|
if (id === "diffViewMode" && DIFF_VIEW_MODES.includes(value as never)) {
|
|
377
|
-
const patch = { diffViewMode: value as
|
|
378
|
-
if (deps.
|
|
379
|
-
else
|
|
479
|
+
const patch = { diffViewMode: value as ContextConfig["diffViewMode"] };
|
|
480
|
+
if (deps.runtime) deps.runtime.updateContextConfig(patch, ctx);
|
|
481
|
+
else updateContextConfig(patch);
|
|
380
482
|
saveNotice(ctx, "Diff layout", value);
|
|
381
483
|
return;
|
|
382
484
|
}
|
|
@@ -385,31 +487,31 @@ function updateSetting(
|
|
|
385
487
|
DIFF_INDICATOR_MODES.includes(value as never)
|
|
386
488
|
) {
|
|
387
489
|
const patch = {
|
|
388
|
-
diffIndicatorMode: value as
|
|
490
|
+
diffIndicatorMode: value as ContextConfig["diffIndicatorMode"],
|
|
389
491
|
};
|
|
390
|
-
if (deps.
|
|
391
|
-
else
|
|
492
|
+
if (deps.runtime) deps.runtime.updateContextConfig(patch, ctx);
|
|
493
|
+
else updateContextConfig(patch);
|
|
392
494
|
saveNotice(ctx, "Diff indicator", value);
|
|
393
495
|
return;
|
|
394
496
|
}
|
|
395
497
|
if (id === "diffWordWrap") {
|
|
396
498
|
const patch = { diffWordWrap: isOn(value) };
|
|
397
|
-
if (deps.
|
|
398
|
-
else
|
|
499
|
+
if (deps.runtime) deps.runtime.updateContextConfig(patch, ctx);
|
|
500
|
+
else updateContextConfig(patch);
|
|
399
501
|
saveNotice(ctx, "Diff word wrap", value);
|
|
400
502
|
return;
|
|
401
503
|
}
|
|
402
504
|
if (id === "thinkingPreviewLines") {
|
|
403
505
|
const patch = { previewLines: Number(value) };
|
|
404
|
-
if (deps.
|
|
405
|
-
else
|
|
506
|
+
if (deps.runtime) deps.runtime.updateContextConfig(patch, ctx);
|
|
507
|
+
else updateContextConfig(patch);
|
|
406
508
|
saveNotice(ctx, "Thinking preview", value);
|
|
407
509
|
return;
|
|
408
510
|
}
|
|
409
511
|
if (id === "dimThinkingText") {
|
|
410
512
|
const patch = { dimThinkingText: isOn(value) };
|
|
411
|
-
if (deps.
|
|
412
|
-
else
|
|
513
|
+
if (deps.runtime) deps.runtime.updateContextConfig(patch, ctx);
|
|
514
|
+
else updateContextConfig(patch);
|
|
413
515
|
saveNotice(ctx, "Thinking text", value);
|
|
414
516
|
return;
|
|
415
517
|
}
|
|
@@ -421,9 +523,9 @@ function updateSetting(
|
|
|
421
523
|
id === "enableAliases" ||
|
|
422
524
|
id === "showStartupHeader"
|
|
423
525
|
) {
|
|
424
|
-
const patch = { [id]: isOn(value) } as Partial<
|
|
425
|
-
if (deps.
|
|
426
|
-
else
|
|
526
|
+
const patch = { [id]: isOn(value) } as Partial<ContextConfig>;
|
|
527
|
+
if (deps.runtime) deps.runtime.updateContextConfig(patch, ctx);
|
|
528
|
+
else updateContextConfig(patch);
|
|
427
529
|
saveNotice(ctx, id, value);
|
|
428
530
|
return;
|
|
429
531
|
}
|
|
@@ -431,8 +533,8 @@ function updateSetting(
|
|
|
431
533
|
const preset = id.slice("preset:".length);
|
|
432
534
|
if (PRESET_VALUES.includes(preset as Preset)) {
|
|
433
535
|
applyPreset(preset as Preset);
|
|
434
|
-
if (deps.
|
|
435
|
-
deps.
|
|
536
|
+
if (deps.runtime) {
|
|
537
|
+
deps.runtime.setContextMode(
|
|
436
538
|
preset === "compact" ? "compact" : preset === "native" ? "off" : "on",
|
|
437
539
|
ctx,
|
|
438
540
|
);
|
|
@@ -445,6 +547,12 @@ function updateSetting(
|
|
|
445
547
|
|
|
446
548
|
let unifiedPanelOpen = false;
|
|
447
549
|
|
|
550
|
+
/**
|
|
551
|
+
* Opens the unified settings panel as a managed overlay.
|
|
552
|
+
*
|
|
553
|
+
* @param ctx Active TUI extension context.
|
|
554
|
+
* @param deps Runtime controllers used for live updates.
|
|
555
|
+
*/
|
|
448
556
|
export async function showOneUiPanel(
|
|
449
557
|
ctx: any,
|
|
450
558
|
deps: UnifiedPanelDeps = {},
|
|
@@ -464,68 +572,81 @@ export async function showOneUiPanel(
|
|
|
464
572
|
|
|
465
573
|
unifiedPanelOpen = true;
|
|
466
574
|
try {
|
|
467
|
-
await
|
|
468
|
-
(
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
const switchSection = (delta: number) => {
|
|
487
|
-
activeIndex =
|
|
488
|
-
(activeIndex + delta + SECTIONS.length) % SECTIONS.length;
|
|
575
|
+
await overlayManager.run(() =>
|
|
576
|
+
ctx.ui.custom(
|
|
577
|
+
(tui: any, theme: any, _keybindings: any, done: () => void) => {
|
|
578
|
+
let activeIndex = 0;
|
|
579
|
+
let list: SettingsList;
|
|
580
|
+
const createList = () => {
|
|
581
|
+
list = new SettingsList(
|
|
582
|
+
itemsFor(SECTIONS[activeIndex].id),
|
|
583
|
+
10,
|
|
584
|
+
getSettingsListTheme(),
|
|
585
|
+
(id, value) => {
|
|
586
|
+
updateSetting(id, value, ctx, deps);
|
|
587
|
+
list.updateValue(id, value);
|
|
588
|
+
tui.requestRender();
|
|
589
|
+
},
|
|
590
|
+
done,
|
|
591
|
+
);
|
|
592
|
+
};
|
|
489
593
|
createList();
|
|
490
|
-
tui.requestRender();
|
|
491
|
-
};
|
|
492
594
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
? renderShellPreview(theme, width)
|
|
505
|
-
: []),
|
|
506
|
-
"",
|
|
507
|
-
truncateToWidth(
|
|
595
|
+
const switchSection = (delta: number) => {
|
|
596
|
+
activeIndex =
|
|
597
|
+
(activeIndex + delta + SECTIONS.length) % SECTIONS.length;
|
|
598
|
+
createList();
|
|
599
|
+
tui.requestRender();
|
|
600
|
+
};
|
|
601
|
+
|
|
602
|
+
return {
|
|
603
|
+
render: (width: number) => [
|
|
604
|
+
renderTabs(theme, activeIndex, width),
|
|
605
|
+
theme.fg("dim", "─".repeat(Math.max(0, width))),
|
|
508
606
|
theme.fg(
|
|
509
|
-
"
|
|
510
|
-
|
|
607
|
+
"muted",
|
|
608
|
+
` ${sectionDescription(SECTIONS[activeIndex].id)}`,
|
|
511
609
|
),
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
610
|
+
"",
|
|
611
|
+
...list.render(width),
|
|
612
|
+
...(SECTIONS[activeIndex].id === "editor"
|
|
613
|
+
? renderEditorPreview(theme, width)
|
|
614
|
+
: SECTIONS[activeIndex].id === "context"
|
|
615
|
+
? renderContextPreview(theme, width)
|
|
616
|
+
: []),
|
|
617
|
+
"",
|
|
618
|
+
truncateToWidth(
|
|
619
|
+
theme.fg(
|
|
620
|
+
"dim",
|
|
621
|
+
" Tab/Shift+Tab switch sections · Enter/Space change · Esc close",
|
|
622
|
+
),
|
|
623
|
+
width,
|
|
624
|
+
),
|
|
625
|
+
],
|
|
626
|
+
invalidate: () => list.invalidate(),
|
|
627
|
+
handleInput: (data: string) => {
|
|
628
|
+
if (data === "\x1b[Z" || matchesKey(data, "shift+tab")) {
|
|
629
|
+
switchSection(-1);
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
632
|
+
if (matchesKey(data, "tab")) {
|
|
633
|
+
switchSection(1);
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
list.handleInput(data);
|
|
637
|
+
},
|
|
638
|
+
};
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
overlay: true,
|
|
642
|
+
overlayOptions: {
|
|
643
|
+
anchor: "center",
|
|
644
|
+
width: "85%",
|
|
645
|
+
maxHeight: "90%",
|
|
646
|
+
margin: 1,
|
|
526
647
|
},
|
|
527
|
-
}
|
|
528
|
-
|
|
648
|
+
},
|
|
649
|
+
),
|
|
529
650
|
);
|
|
530
651
|
} finally {
|
|
531
652
|
unifiedPanelOpen = false;
|