@xynogen/pix-toolbox 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/package.json +4 -1
- package/src/toolbox.ts +40 -34
package/README.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xynogen/pix-toolbox",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Pi tool — gated tool toggle UI (/toolbox)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -33,6 +33,9 @@
|
|
|
33
33
|
"publishConfig": {
|
|
34
34
|
"access": "public"
|
|
35
35
|
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@xynogen/pix-pretty": "*"
|
|
38
|
+
},
|
|
36
39
|
"peerDependencies": {
|
|
37
40
|
"@earendil-works/pi-coding-agent": "*",
|
|
38
41
|
"@earendil-works/pi-tui": "*"
|
package/src/toolbox.ts
CHANGED
|
@@ -21,9 +21,8 @@ import type {
|
|
|
21
21
|
Theme,
|
|
22
22
|
ToolInfo,
|
|
23
23
|
} from "@earendil-works/pi-coding-agent";
|
|
24
|
-
import {
|
|
24
|
+
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
25
25
|
import {
|
|
26
|
-
Container,
|
|
27
26
|
decodeKittyPrintable,
|
|
28
27
|
fuzzyFilter,
|
|
29
28
|
Input,
|
|
@@ -32,10 +31,10 @@ import {
|
|
|
32
31
|
matchesKey,
|
|
33
32
|
type SelectItem,
|
|
34
33
|
SelectList,
|
|
35
|
-
Text,
|
|
36
34
|
type TUI,
|
|
37
35
|
visibleWidth,
|
|
38
36
|
} from "@earendil-works/pi-tui";
|
|
37
|
+
import { frameLines, modalWidth } from "@xynogen/pix-pretty/modal-frame";
|
|
39
38
|
|
|
40
39
|
// ─── Constants ──────────────────────────────────────────────────────────────
|
|
41
40
|
|
|
@@ -337,7 +336,17 @@ export default function registerToolbox(pi: ExtensionAPI): void {
|
|
|
337
336
|
|
|
338
337
|
async function showPicker(ctx: {
|
|
339
338
|
ui: {
|
|
340
|
-
custom: <T>(
|
|
339
|
+
custom: <T>(
|
|
340
|
+
f: unknown,
|
|
341
|
+
opts?: {
|
|
342
|
+
overlay?: boolean;
|
|
343
|
+
overlayOptions?: {
|
|
344
|
+
anchor?: string;
|
|
345
|
+
maxHeight?: number | string;
|
|
346
|
+
width?: number | string;
|
|
347
|
+
};
|
|
348
|
+
},
|
|
349
|
+
) => Promise<T>;
|
|
341
350
|
notify: (m: string, t?: "info" | "warning" | "error") => void;
|
|
342
351
|
};
|
|
343
352
|
}): Promise<void> {
|
|
@@ -350,7 +359,6 @@ export default function registerToolbox(pi: ExtensionAPI): void {
|
|
|
350
359
|
) => {
|
|
351
360
|
const accent = "accent";
|
|
352
361
|
const mute = (s: string) => theme.fg("muted", s);
|
|
353
|
-
const container = new Container();
|
|
354
362
|
|
|
355
363
|
type RowState = "active" | "gated";
|
|
356
364
|
const stateOf = (name: string): RowState =>
|
|
@@ -414,7 +422,7 @@ export default function registerToolbox(pi: ExtensionAPI): void {
|
|
|
414
422
|
};
|
|
415
423
|
|
|
416
424
|
const search = new Input();
|
|
417
|
-
|
|
425
|
+
let statusText = "";
|
|
418
426
|
|
|
419
427
|
const refreshLabels = () => {
|
|
420
428
|
for (const it of internal.items) {
|
|
@@ -424,7 +432,6 @@ export default function registerToolbox(pi: ExtensionAPI): void {
|
|
|
424
432
|
it.description = descFor(r);
|
|
425
433
|
}
|
|
426
434
|
list.invalidate();
|
|
427
|
-
container.invalidate();
|
|
428
435
|
tui.requestRender?.();
|
|
429
436
|
};
|
|
430
437
|
|
|
@@ -432,7 +439,7 @@ export default function registerToolbox(pi: ExtensionAPI): void {
|
|
|
432
439
|
const sel = list.getSelectedItem();
|
|
433
440
|
if (!sel) return;
|
|
434
441
|
const msg = toggleTool(action, sel.value, rows, ops);
|
|
435
|
-
|
|
442
|
+
statusText = theme.fg("muted", msg);
|
|
436
443
|
refreshLabels();
|
|
437
444
|
};
|
|
438
445
|
|
|
@@ -455,41 +462,39 @@ export default function registerToolbox(pi: ExtensionAPI): void {
|
|
|
455
462
|
);
|
|
456
463
|
internal.selectedIndex = 0;
|
|
457
464
|
list.invalidate();
|
|
458
|
-
container.invalidate();
|
|
459
465
|
};
|
|
460
466
|
|
|
461
467
|
list.onSelect = () => done(null);
|
|
462
468
|
list.onCancel = () => done(null);
|
|
463
469
|
search.onEscape = () => done(null);
|
|
464
470
|
|
|
465
|
-
container.addChild(
|
|
466
|
-
new DynamicBorder((s: string) => theme.fg(accent, s)),
|
|
467
|
-
);
|
|
468
|
-
container.addChild(
|
|
469
|
-
new Text(theme.fg(accent, theme.bold("🧰 Toolbox"))),
|
|
470
|
-
);
|
|
471
|
-
container.addChild(new Text(theme.fg("muted", "Search:")));
|
|
472
|
-
container.addChild(search);
|
|
473
|
-
container.addChild(list);
|
|
474
|
-
container.addChild(statusLine);
|
|
475
|
-
container.addChild(
|
|
476
|
-
new Text(
|
|
477
|
-
theme.fg(
|
|
478
|
-
"dim",
|
|
479
|
-
"↑↓ navigate · e enable · d disable · space toggle · esc close",
|
|
480
|
-
),
|
|
481
|
-
),
|
|
482
|
-
);
|
|
483
|
-
container.addChild(
|
|
484
|
-
new DynamicBorder((s: string) => theme.fg(accent, s)),
|
|
485
|
-
);
|
|
486
|
-
|
|
487
471
|
return {
|
|
488
472
|
render(w: number) {
|
|
489
|
-
|
|
473
|
+
const mw = modalWidth(w);
|
|
474
|
+
const inner = mw - 4; // CHROME = 2 border + 2 padding
|
|
475
|
+
const lines: string[] = [
|
|
476
|
+
theme.fg(accent, theme.bold("🧰 Toolbox")),
|
|
477
|
+
theme.fg("muted", "Search:"),
|
|
478
|
+
...search.render(inner),
|
|
479
|
+
...list.render(inner),
|
|
480
|
+
];
|
|
481
|
+
if (statusText) lines.push(statusText);
|
|
482
|
+
lines.push(
|
|
483
|
+
theme.fg(
|
|
484
|
+
"dim",
|
|
485
|
+
"↑↓ navigate · e enable · d disable · space toggle · esc close",
|
|
486
|
+
),
|
|
487
|
+
);
|
|
488
|
+
return frameLines({
|
|
489
|
+
width: mw,
|
|
490
|
+
lines,
|
|
491
|
+
color: (s) => theme.fg(accent, s),
|
|
492
|
+
bg: (s) => theme.bg("customMessageBg", s),
|
|
493
|
+
});
|
|
490
494
|
},
|
|
491
495
|
invalidate() {
|
|
492
|
-
|
|
496
|
+
list.invalidate();
|
|
497
|
+
search.invalidate();
|
|
493
498
|
},
|
|
494
499
|
handleInput(data: string) {
|
|
495
500
|
if (matchesKey(data, Key.up) || matchesKey(data, Key.down)) {
|
|
@@ -521,11 +526,12 @@ export default function registerToolbox(pi: ExtensionAPI): void {
|
|
|
521
526
|
applyFilter(search.getValue?.() ?? "");
|
|
522
527
|
}
|
|
523
528
|
}
|
|
524
|
-
|
|
529
|
+
list.invalidate();
|
|
525
530
|
tui.requestRender?.();
|
|
526
531
|
},
|
|
527
532
|
};
|
|
528
533
|
},
|
|
534
|
+
{ overlay: true, overlayOptions: { anchor: "center", maxHeight: "80%" } },
|
|
529
535
|
);
|
|
530
536
|
}
|
|
531
537
|
|