pi-one-ui 0.2.0 → 0.2.1
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/extensions/app/panel.ts +77 -26
- package/package.json +9 -1
package/extensions/app/panel.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
type ExtensionCommandContext,
|
|
2
3
|
type ExtensionContext,
|
|
3
4
|
getSettingsListTheme,
|
|
4
5
|
} from "@earendil-works/pi-coding-agent";
|
|
@@ -84,6 +85,26 @@ function renderTabs(theme: any, active: number, width: number): string {
|
|
|
84
85
|
return truncateToWidth(text, Math.max(0, width));
|
|
85
86
|
}
|
|
86
87
|
|
|
88
|
+
/** Adds a stable chrome frame around the settings content. */
|
|
89
|
+
function renderPanelFrame(theme: any, width: number, rows: string[]): string[] {
|
|
90
|
+
const safeWidth = Math.max(1, width);
|
|
91
|
+
const border = (text: string) => theme.fg("border", text);
|
|
92
|
+
if (safeWidth === 1)
|
|
93
|
+
return [border("│"), ...rows.map(() => border("│")), border("│")];
|
|
94
|
+
|
|
95
|
+
const innerWidth = safeWidth - 2;
|
|
96
|
+
const content = rows.map(
|
|
97
|
+
(row) =>
|
|
98
|
+
`${border("│")}${truncateToWidth(row, innerWidth, "", true)}${border("│")}`,
|
|
99
|
+
);
|
|
100
|
+
if (safeWidth === 2) return [border("╭╮"), ...content, border("╰╯")];
|
|
101
|
+
return [
|
|
102
|
+
border(`╭${"─".repeat(innerWidth)}╮`),
|
|
103
|
+
...content,
|
|
104
|
+
border(`╰${"─".repeat(innerWidth)}╯`),
|
|
105
|
+
];
|
|
106
|
+
}
|
|
107
|
+
|
|
87
108
|
function sectionDescription(section: SectionId): string {
|
|
88
109
|
switch (section) {
|
|
89
110
|
case "header":
|
|
@@ -554,7 +575,7 @@ let unifiedPanelOpen = false;
|
|
|
554
575
|
* @param deps Runtime controllers used for live updates.
|
|
555
576
|
*/
|
|
556
577
|
export async function showOneUiPanel(
|
|
557
|
-
ctx:
|
|
578
|
+
ctx: ExtensionCommandContext,
|
|
558
579
|
deps: UnifiedPanelDeps = {},
|
|
559
580
|
): Promise<void> {
|
|
560
581
|
if (
|
|
@@ -572,9 +593,10 @@ export async function showOneUiPanel(
|
|
|
572
593
|
|
|
573
594
|
unifiedPanelOpen = true;
|
|
574
595
|
try {
|
|
596
|
+
let panelHandle: { focus: () => void } | undefined;
|
|
575
597
|
await overlayManager.run(() =>
|
|
576
598
|
ctx.ui.custom(
|
|
577
|
-
(tui
|
|
599
|
+
(tui, theme, _keybindings, done) => {
|
|
578
600
|
let activeIndex = 0;
|
|
579
601
|
let list: SettingsList;
|
|
580
602
|
const createList = () => {
|
|
@@ -583,11 +605,29 @@ export async function showOneUiPanel(
|
|
|
583
605
|
10,
|
|
584
606
|
getSettingsListTheme(),
|
|
585
607
|
(id, value) => {
|
|
608
|
+
// Replacing Pi's editor synchronously moves focus away from
|
|
609
|
+
// this overlay. Restore the overlay handle after the editor
|
|
610
|
+
// has been reconciled so the panel remains interactive.
|
|
611
|
+
if (id === "editorEnabled") {
|
|
612
|
+
try {
|
|
613
|
+
updateSetting(id, value, ctx, deps);
|
|
614
|
+
list.updateValue(id, value);
|
|
615
|
+
} catch (error) {
|
|
616
|
+
ctx.ui?.notify?.(
|
|
617
|
+
`Could not update Editor setting: ${error instanceof Error ? error.message : String(error)}`,
|
|
618
|
+
"error",
|
|
619
|
+
);
|
|
620
|
+
} finally {
|
|
621
|
+
panelHandle?.focus();
|
|
622
|
+
tui.requestRender();
|
|
623
|
+
}
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
586
626
|
updateSetting(id, value, ctx, deps);
|
|
587
627
|
list.updateValue(id, value);
|
|
588
628
|
tui.requestRender();
|
|
589
629
|
},
|
|
590
|
-
done,
|
|
630
|
+
() => done(undefined),
|
|
591
631
|
);
|
|
592
632
|
};
|
|
593
633
|
createList();
|
|
@@ -600,29 +640,32 @@ export async function showOneUiPanel(
|
|
|
600
640
|
};
|
|
601
641
|
|
|
602
642
|
return {
|
|
603
|
-
render: (width: number) =>
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
"
|
|
608
|
-
` ${sectionDescription(SECTIONS[activeIndex].id)}`,
|
|
609
|
-
),
|
|
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(
|
|
643
|
+
render: (width: number) => {
|
|
644
|
+
const contentWidth = Math.max(0, width - 2);
|
|
645
|
+
return renderPanelFrame(theme, width, [
|
|
646
|
+
renderTabs(theme, activeIndex, contentWidth),
|
|
647
|
+
theme.fg("dim", "─".repeat(contentWidth)),
|
|
619
648
|
theme.fg(
|
|
620
|
-
"
|
|
621
|
-
|
|
649
|
+
"muted",
|
|
650
|
+
` ${sectionDescription(SECTIONS[activeIndex].id)}`,
|
|
651
|
+
),
|
|
652
|
+
"",
|
|
653
|
+
...list.render(contentWidth),
|
|
654
|
+
...(SECTIONS[activeIndex].id === "editor"
|
|
655
|
+
? renderEditorPreview(theme, contentWidth)
|
|
656
|
+
: SECTIONS[activeIndex].id === "context"
|
|
657
|
+
? renderContextPreview(theme, contentWidth)
|
|
658
|
+
: []),
|
|
659
|
+
"",
|
|
660
|
+
truncateToWidth(
|
|
661
|
+
theme.fg(
|
|
662
|
+
"dim",
|
|
663
|
+
" Tab/Shift+Tab switch sections · Enter/Space change · Esc close",
|
|
664
|
+
),
|
|
665
|
+
contentWidth,
|
|
622
666
|
),
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
],
|
|
667
|
+
]);
|
|
668
|
+
},
|
|
626
669
|
invalidate: () => list.invalidate(),
|
|
627
670
|
handleInput: (data: string) => {
|
|
628
671
|
if (data === "\x1b[Z" || matchesKey(data, "shift+tab")) {
|
|
@@ -640,10 +683,18 @@ export async function showOneUiPanel(
|
|
|
640
683
|
{
|
|
641
684
|
overlay: true,
|
|
642
685
|
overlayOptions: {
|
|
643
|
-
anchor: "center",
|
|
686
|
+
anchor: "top-center",
|
|
644
687
|
width: "85%",
|
|
645
688
|
maxHeight: "90%",
|
|
646
|
-
margin:
|
|
689
|
+
margin: {
|
|
690
|
+
top: 10,
|
|
691
|
+
right: 1,
|
|
692
|
+
bottom: 1,
|
|
693
|
+
left: 1,
|
|
694
|
+
},
|
|
695
|
+
},
|
|
696
|
+
onHandle: (handle: { focus: () => void }) => {
|
|
697
|
+
panelHandle = handle;
|
|
647
698
|
},
|
|
648
699
|
},
|
|
649
700
|
),
|
package/package.json
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-one-ui",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "A single, customizable Pi UI package with layout-oriented Context and Shell rendering for Pi.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/kerolt/pi-one-ui"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/kerolt/pi-one-ui/issues"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/kerolt/pi-one-ui#readme",
|
|
7
15
|
"files": [
|
|
8
16
|
"extensions",
|
|
9
17
|
"themes",
|