@noir-ai/cli 1.11.0 → 1.11.1-beta.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/README.md +4 -3
- package/dist/bin.js +19 -16
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-CN3KUSQT.js → chunk-CT6TYLHN.js} +4 -3
- package/dist/chunk-CT6TYLHN.js.map +1 -0
- package/dist/{chunk-S2PDLS4C.js → chunk-I2R55ACD.js} +4 -2
- package/dist/{chunk-S2PDLS4C.js.map → chunk-I2R55ACD.js.map} +1 -1
- package/dist/{chunk-Y4M2YC6U.js → chunk-QIVHIKYD.js} +3 -3
- package/dist/{chunk-US567S5T.js → chunk-RON2XESF.js} +2 -2
- package/dist/{create-DJ6B5K36.js → create-VK2QMXYS.js} +3 -3
- package/dist/index.js +2 -2
- package/dist/{install-X7QSYLLS.js → install-4U4UDDNE.js} +3 -3
- package/dist/{sync-FKWXQOWT.js → sync-VXZKODQA.js} +3 -3
- package/dist/tui/{chunk-2KJ27HGA.js → chunk-F6XRS72N.js} +4 -3
- package/dist/tui/chunk-F6XRS72N.js.map +1 -0
- package/dist/tui/{chunk-4OBUMHF6.js → chunk-NLK6UNIA.js} +3 -3
- package/dist/tui/{chunk-R6246ISQ.js → chunk-QF6777NJ.js} +2 -2
- package/dist/tui/{chunk-MD6WXZBF.js → chunk-R5YX44UL.js} +4 -2
- package/dist/tui/{chunk-MD6WXZBF.js.map → chunk-R5YX44UL.js.map} +1 -1
- package/dist/tui/{create-CFAXIIYW.js → create-WKFVM237.js} +3 -3
- package/dist/tui/index.js +185 -153
- package/dist/tui/index.js.map +1 -1
- package/dist/tui/{install-HZKZXBQD.js → install-JR6ZXNYA.js} +3 -3
- package/dist/tui/{sync-Y7MTQ4JC.js → sync-DUWJAF7Z.js} +3 -3
- package/dist/tui/{update-OM2EP2F5.js → update-PGAM6OVL.js} +4 -4
- package/dist/{update-S3IZXXKO.js → update-ZDAVLOXB.js} +4 -4
- package/package.json +12 -12
- package/dist/chunk-CN3KUSQT.js.map +0 -1
- package/dist/tui/chunk-2KJ27HGA.js.map +0 -1
- /package/dist/{chunk-Y4M2YC6U.js.map → chunk-QIVHIKYD.js.map} +0 -0
- /package/dist/{chunk-US567S5T.js.map → chunk-RON2XESF.js.map} +0 -0
- /package/dist/{create-DJ6B5K36.js.map → create-VK2QMXYS.js.map} +0 -0
- /package/dist/{install-X7QSYLLS.js.map → install-4U4UDDNE.js.map} +0 -0
- /package/dist/{sync-FKWXQOWT.js.map → sync-VXZKODQA.js.map} +0 -0
- /package/dist/tui/{chunk-4OBUMHF6.js.map → chunk-NLK6UNIA.js.map} +0 -0
- /package/dist/tui/{chunk-R6246ISQ.js.map → chunk-QF6777NJ.js.map} +0 -0
- /package/dist/tui/{create-CFAXIIYW.js.map → create-WKFVM237.js.map} +0 -0
- /package/dist/tui/{install-HZKZXBQD.js.map → install-JR6ZXNYA.js.map} +0 -0
- /package/dist/tui/{sync-Y7MTQ4JC.js.map → sync-DUWJAF7Z.js.map} +0 -0
- /package/dist/tui/{update-OM2EP2F5.js.map → update-PGAM6OVL.js.map} +0 -0
- /package/dist/{update-S3IZXXKO.js.map → update-ZDAVLOXB.js.map} +0 -0
package/dist/tui/index.js
CHANGED
|
@@ -2,12 +2,12 @@ import {
|
|
|
2
2
|
DEFAULT_UPDATE_CONFIG,
|
|
3
3
|
buildUpdateNotice,
|
|
4
4
|
runAsyncUpdateCheck
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-NLK6UNIA.js";
|
|
6
|
+
import "./chunk-QF6777NJ.js";
|
|
7
7
|
import {
|
|
8
8
|
doctor,
|
|
9
9
|
init
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-F6XRS72N.js";
|
|
11
11
|
import {
|
|
12
12
|
EXIT,
|
|
13
13
|
NoirCliError,
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
tip,
|
|
31
31
|
useColor,
|
|
32
32
|
warn
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-R5YX44UL.js";
|
|
34
34
|
|
|
35
35
|
// src/tui/index.tsx
|
|
36
36
|
import { loadProjectInfo as loadProjectInfo9 } from "@noir-ai/core";
|
|
@@ -2965,7 +2965,7 @@ function createProgram() {
|
|
|
2965
2965
|
const force = opts.force === true;
|
|
2966
2966
|
const host = parseHost(opts.host);
|
|
2967
2967
|
const dryRun = opts.dryRun === true || opts.preview === true;
|
|
2968
|
-
const { create } = await import("./create-
|
|
2968
|
+
const { create } = await import("./create-WKFVM237.js");
|
|
2969
2969
|
const result = await create(dir, {
|
|
2970
2970
|
transport,
|
|
2971
2971
|
url: opts.url,
|
|
@@ -3004,7 +3004,7 @@ function createProgram() {
|
|
|
3004
3004
|
).choices(SUPPORTED_HOSTS2)
|
|
3005
3005
|
).action(
|
|
3006
3006
|
async (opts, cmd) => {
|
|
3007
|
-
const { sync } = await import("./sync-
|
|
3007
|
+
const { sync } = await import("./sync-DUWJAF7Z.js");
|
|
3008
3008
|
const host = parseHost(opts.host);
|
|
3009
3009
|
const force = opts.force === true;
|
|
3010
3010
|
const merge = opts.merge === true;
|
|
@@ -3066,7 +3066,7 @@ function createProgram() {
|
|
|
3066
3066
|
program2.command("status").description("project + daemon + workflow + store snapshot").action(async (...args) => {
|
|
3067
3067
|
await status(toStatusOptions(actionGlobals(args)));
|
|
3068
3068
|
});
|
|
3069
|
-
const contextGrp = program2.command("context").description("context engine
|
|
3069
|
+
const contextGrp = program2.command("context").description("context engine");
|
|
3070
3070
|
contextGrp.command("search").description("hybrid search over the indexed context").argument("<query>", "search query").option("--limit <n>", "max results", "10").action(async (...args) => {
|
|
3071
3071
|
const cmd = trailingCmd(args);
|
|
3072
3072
|
const g = cmd.optsWithGlobals();
|
|
@@ -3155,17 +3155,17 @@ function createProgram() {
|
|
|
3155
3155
|
"Usage: noir memory recall|save|sessions|forget|consolidate"
|
|
3156
3156
|
);
|
|
3157
3157
|
});
|
|
3158
|
-
const skillsGrp = program2.command("skills").description("builtin skills
|
|
3158
|
+
const skillsGrp = program2.command("skills").description("builtin skills");
|
|
3159
3159
|
skillsGrp.command("list").description("list installed Noir skills").action(async (...args) => {
|
|
3160
3160
|
await skillsList(toCliOptions(actionGlobals(args)));
|
|
3161
3161
|
});
|
|
3162
3162
|
skillsGrp.command("sync").description("re-emit skills to the host skills dir").action(async (...args) => {
|
|
3163
3163
|
await skillsSync(toCliOptions(actionGlobals(args)));
|
|
3164
3164
|
});
|
|
3165
|
-
skillsGrp.command("lint").description("structural quality gate over the shipped pack
|
|
3165
|
+
skillsGrp.command("lint").description("structural quality gate over the shipped pack").action(async (...args) => {
|
|
3166
3166
|
await skillsLint(toCliOptions(actionGlobals(args)));
|
|
3167
3167
|
});
|
|
3168
|
-
skillsGrp.command("registry").description("emit the runtime-derived skill registry
|
|
3168
|
+
skillsGrp.command("registry").description("emit the runtime-derived skill registry").action(async (...args) => {
|
|
3169
3169
|
await skillsRegistry(toCliOptions(actionGlobals(args)));
|
|
3170
3170
|
});
|
|
3171
3171
|
skillsGrp.action(() => {
|
|
@@ -3215,7 +3215,7 @@ function createProgram() {
|
|
|
3215
3215
|
});
|
|
3216
3216
|
taskGrp.command("decompose").description(
|
|
3217
3217
|
"decompose a capability into buildable slices (template-only offline; see the spec)"
|
|
3218
|
-
).argument("<capability>", "capability id
|
|
3218
|
+
).argument("<capability>", "capability id").option("--out <path>", "output path for the slice-plan JSON").action(async (...args) => {
|
|
3219
3219
|
const cmd = trailingCmd(args);
|
|
3220
3220
|
const g = cmd.optsWithGlobals();
|
|
3221
3221
|
const capability = typeof args[0] === "string" ? args[0] : "";
|
|
@@ -3307,7 +3307,7 @@ function createProgram() {
|
|
|
3307
3307
|
"dismiss the migration banner for the current version (persists in install.json)"
|
|
3308
3308
|
).argument("[spec]", "channel ('latest'|'beta') or exact version (default: latest)").action(
|
|
3309
3309
|
async (spec, opts, cmd) => {
|
|
3310
|
-
const { install } = await import("./install-
|
|
3310
|
+
const { install } = await import("./install-JR6ZXNYA.js");
|
|
3311
3311
|
const cli = cmd.optsWithGlobals();
|
|
3312
3312
|
await install({
|
|
3313
3313
|
...cli,
|
|
@@ -3320,7 +3320,7 @@ function createProgram() {
|
|
|
3320
3320
|
);
|
|
3321
3321
|
installCmd.alias("migrate");
|
|
3322
3322
|
program2.command("update").description("update Noir to the latest version via the active install method").option("--check", "check for a new version without changing anything").argument("[spec]", "channel ('latest'|'beta') or exact version (default: latest)").action(async (spec, opts, cmd) => {
|
|
3323
|
-
const { update } = await import("./update-
|
|
3323
|
+
const { update } = await import("./update-PGAM6OVL.js");
|
|
3324
3324
|
const cli = cmd.optsWithGlobals();
|
|
3325
3325
|
await update({ ...cli, spec, check: opts.check === true });
|
|
3326
3326
|
});
|
|
@@ -3348,6 +3348,7 @@ function createProgram() {
|
|
|
3348
3348
|
const opts = toCliOptions(g);
|
|
3349
3349
|
requireInteractive(opts, "`noir tui`");
|
|
3350
3350
|
const tuiUrl = new URL("./tui/index.js", import.meta.url).href;
|
|
3351
|
+
process.env.NODE_ENV ||= "production";
|
|
3351
3352
|
const { runTui: runTui2 } = await import(
|
|
3352
3353
|
/* @vite-ignore */
|
|
3353
3354
|
tuiUrl
|
|
@@ -3367,6 +3368,7 @@ function createProgram() {
|
|
|
3367
3368
|
const opts = toCliOptions(g);
|
|
3368
3369
|
requireInteractive(opts, "`noir palette`");
|
|
3369
3370
|
const tuiUrl = new URL("./tui/index.js", import.meta.url).href;
|
|
3371
|
+
process.env.NODE_ENV ||= "production";
|
|
3370
3372
|
const { runPalette: runPalette2 } = await import(
|
|
3371
3373
|
/* @vite-ignore */
|
|
3372
3374
|
tuiUrl
|
|
@@ -3381,9 +3383,10 @@ function createProgram() {
|
|
|
3381
3383
|
};
|
|
3382
3384
|
await runPalette2(opts, dispatch);
|
|
3383
3385
|
});
|
|
3384
|
-
program2.command("run").description("
|
|
3385
|
-
const
|
|
3386
|
-
const
|
|
3386
|
+
program2.command("run").description("ask the host agent a question and print the answer").argument("[prompt...]", "prompt to send to the host").addOption(new Option("--host <id>", "host to drive (default claude)").choices(SUPPORTED_HOSTS2)).option("--command <binary>", "custom host binary (e.g. claude-work)").action(async (...args) => {
|
|
3387
|
+
const cmd = trailingCmd(args);
|
|
3388
|
+
const g = cmd.optsWithGlobals();
|
|
3389
|
+
const prompt = cmd.args.join(" ").trim();
|
|
3387
3390
|
const opts = {
|
|
3388
3391
|
...toCliOptions(g),
|
|
3389
3392
|
...typeof g.host === "string" ? { host: g.host } : {},
|
|
@@ -3443,7 +3446,7 @@ if (isMainModule) {
|
|
|
3443
3446
|
|
|
3444
3447
|
// src/tui/App.tsx
|
|
3445
3448
|
import { Box as Box5, Text as Text8, useApp, useInput } from "ink";
|
|
3446
|
-
import { useEffect, useState as useState2 } from "react";
|
|
3449
|
+
import { useEffect, useMemo, useState as useState2 } from "react";
|
|
3447
3450
|
|
|
3448
3451
|
// src/tui/CommandInput.tsx
|
|
3449
3452
|
import { Box, Text } from "ink";
|
|
@@ -3554,17 +3557,18 @@ function Header({ tagline }) {
|
|
|
3554
3557
|
}
|
|
3555
3558
|
|
|
3556
3559
|
// src/tui/hooks/useInputBuffer.ts
|
|
3557
|
-
import { useRef, useState } from "react";
|
|
3560
|
+
import { useCallback, useRef, useState } from "react";
|
|
3561
|
+
var MAX_HISTORY = 50;
|
|
3558
3562
|
function useInputBuffer() {
|
|
3559
3563
|
const [buffer, setBuffer] = useState("");
|
|
3560
3564
|
const historyRef = useRef([]);
|
|
3561
3565
|
const cursorRef = useRef(-1);
|
|
3562
|
-
|
|
3566
|
+
const pushHistory = useCallback((text) => {
|
|
3563
3567
|
if (text.length === 0) return;
|
|
3564
3568
|
const history = historyRef.current.filter((e) => e !== text);
|
|
3565
|
-
historyRef.current = [text, ...history];
|
|
3566
|
-
}
|
|
3567
|
-
|
|
3569
|
+
historyRef.current = [text, ...history].slice(0, MAX_HISTORY);
|
|
3570
|
+
}, []);
|
|
3571
|
+
const recall = useCallback((dir) => {
|
|
3568
3572
|
const history = historyRef.current;
|
|
3569
3573
|
if (history.length === 0) return null;
|
|
3570
3574
|
let cursor = cursorRef.current;
|
|
@@ -3575,51 +3579,37 @@ function useInputBuffer() {
|
|
|
3575
3579
|
}
|
|
3576
3580
|
cursorRef.current = cursor;
|
|
3577
3581
|
return cursor === -1 ? null : history[cursor] ?? null;
|
|
3578
|
-
}
|
|
3579
|
-
|
|
3582
|
+
}, []);
|
|
3583
|
+
const clear = useCallback(() => {
|
|
3580
3584
|
setBuffer(() => "");
|
|
3581
3585
|
cursorRef.current = -1;
|
|
3582
|
-
}
|
|
3583
|
-
|
|
3586
|
+
}, []);
|
|
3587
|
+
const seed = useCallback((entries) => {
|
|
3584
3588
|
historyRef.current = [...entries];
|
|
3585
3589
|
cursorRef.current = -1;
|
|
3586
|
-
}
|
|
3590
|
+
}, []);
|
|
3587
3591
|
return { buffer, setBuffer, pushHistory, recall, clear, seed };
|
|
3588
3592
|
}
|
|
3589
3593
|
|
|
3590
3594
|
// src/tui/OutputPane.tsx
|
|
3591
3595
|
import { Text as Text4 } from "ink";
|
|
3592
3596
|
import { Fragment, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
3593
|
-
function toRows(visible
|
|
3597
|
+
function toRows(visible) {
|
|
3594
3598
|
const rows = [];
|
|
3595
3599
|
const seen = /* @__PURE__ */ new Map();
|
|
3596
3600
|
for (let i = 0; i < visible.length; i++) {
|
|
3597
3601
|
const text = visible[i] ?? "";
|
|
3598
3602
|
const n = (seen.get(text) ?? 0) + 1;
|
|
3599
3603
|
seen.set(text, n);
|
|
3600
|
-
rows.push({
|
|
3601
|
-
key: n === 1 ? text || "_blank" : `${text || "_blank"}#${n}`,
|
|
3602
|
-
text,
|
|
3603
|
-
index: baseIndex + i
|
|
3604
|
-
});
|
|
3604
|
+
rows.push({ key: n === 1 ? text || "_blank" : `${text || "_blank"}#${n}`, text });
|
|
3605
3605
|
}
|
|
3606
3606
|
return rows;
|
|
3607
3607
|
}
|
|
3608
|
-
function highlightFirst(text, query) {
|
|
3609
|
-
if (query.length === 0) return text;
|
|
3610
|
-
const idx = text.toLowerCase().indexOf(query.toLowerCase());
|
|
3611
|
-
if (idx < 0) return text;
|
|
3612
|
-
return `${text.slice(0, idx)}${c.bold(text.slice(idx, idx + query.length))}${text.slice(
|
|
3613
|
-
idx + query.length
|
|
3614
|
-
)}`;
|
|
3615
|
-
}
|
|
3616
3608
|
function OutputPane({
|
|
3617
3609
|
lines,
|
|
3618
3610
|
scrollOffset,
|
|
3619
3611
|
height = 12,
|
|
3620
|
-
title
|
|
3621
|
-
highlightQuery,
|
|
3622
|
-
activeLine
|
|
3612
|
+
title
|
|
3623
3613
|
}) {
|
|
3624
3614
|
const width = contentWidth();
|
|
3625
3615
|
if (lines.length === 0) {
|
|
@@ -3627,18 +3617,12 @@ function OutputPane({
|
|
|
3627
3617
|
}
|
|
3628
3618
|
const maxOffset = Math.max(0, lines.length - height);
|
|
3629
3619
|
const offset = Math.min(Math.max(0, scrollOffset), maxOffset);
|
|
3630
|
-
const rows = toRows(lines.slice(offset, offset + height)
|
|
3620
|
+
const rows = toRows(lines.slice(offset, offset + height));
|
|
3631
3621
|
return /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
3632
3622
|
title !== void 0 ? /* @__PURE__ */ jsx4(Text4, { wrap: "truncate-end", children: c.dim(`\u2500\u2500 ${title} \u2500\u2500`) }) : null,
|
|
3633
3623
|
rows.map((row) => {
|
|
3634
3624
|
const truncated = row.text.length > width ? `${row.text.slice(0, Math.max(1, width - 1))}\u2026` : row.text;
|
|
3635
|
-
|
|
3636
|
-
if (activeLine !== void 0 && row.index === activeLine) {
|
|
3637
|
-
body = c.accent(truncated);
|
|
3638
|
-
} else if (highlightQuery !== void 0 && highlightQuery.length > 0) {
|
|
3639
|
-
body = highlightFirst(truncated, highlightQuery);
|
|
3640
|
-
}
|
|
3641
|
-
return /* @__PURE__ */ jsx4(Text4, { wrap: "truncate-end", children: body }, row.key);
|
|
3625
|
+
return /* @__PURE__ */ jsx4(Text4, { wrap: "truncate-end", children: truncated }, row.key);
|
|
3642
3626
|
})
|
|
3643
3627
|
] });
|
|
3644
3628
|
}
|
|
@@ -3758,66 +3742,6 @@ var handRolledMatcher = {
|
|
|
3758
3742
|
|
|
3759
3743
|
// src/tui/palette/Palette.tsx
|
|
3760
3744
|
import { Box as Box4, Text as Text6 } from "ink";
|
|
3761
|
-
import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
3762
|
-
var PALETTE_WIDTH = 64;
|
|
3763
|
-
var VISIBLE_ROWS = 10;
|
|
3764
|
-
function highlight(label, matchedIndices) {
|
|
3765
|
-
if (matchedIndices.length === 0) return /* @__PURE__ */ jsx7(Fragment2, { children: label });
|
|
3766
|
-
const set = new Set(matchedIndices);
|
|
3767
|
-
const chars = [];
|
|
3768
|
-
for (let i = 0; i < label.length; i++) {
|
|
3769
|
-
const ch = label[i] ?? "";
|
|
3770
|
-
chars.push(set.has(i) ? /* @__PURE__ */ jsx7(Text6, { children: c.accent(ch) }, i) : /* @__PURE__ */ jsx7(Text6, { children: ch }, i));
|
|
3771
|
-
}
|
|
3772
|
-
return /* @__PURE__ */ jsx7(Fragment2, { children: chars });
|
|
3773
|
-
}
|
|
3774
|
-
function truncate2(label) {
|
|
3775
|
-
const max = Math.max(20, PALETTE_WIDTH - 8);
|
|
3776
|
-
return label.length > max ? `${label.slice(0, max - 1)}\u2026` : label;
|
|
3777
|
-
}
|
|
3778
|
-
function placeholder(corpus) {
|
|
3779
|
-
if (corpus === "commands") return "type to search commands";
|
|
3780
|
-
if (corpus === "output") return "type to filter output";
|
|
3781
|
-
return "keybindings";
|
|
3782
|
-
}
|
|
3783
|
-
function Palette({ corpus, query, active, rows }) {
|
|
3784
|
-
const visible = rows.slice(0, VISIBLE_ROWS);
|
|
3785
|
-
const activeIndex = Math.min(Math.max(active, 0), Math.max(0, visible.length - 1));
|
|
3786
|
-
const elements = [
|
|
3787
|
-
/* @__PURE__ */ jsx7(Box4, { paddingX: 1, children: /* @__PURE__ */ jsxs5(Text6, { children: [
|
|
3788
|
-
c.bold("\u25B8 palette "),
|
|
3789
|
-
/* @__PURE__ */ jsx7(Text6, { children: c.dim(`(${corpus} \xB7 ${visible.length} shown)`) })
|
|
3790
|
-
] }) }, "header"),
|
|
3791
|
-
/* @__PURE__ */ jsx7(Box4, { paddingX: 1, children: /* @__PURE__ */ jsxs5(Text6, { children: [
|
|
3792
|
-
c.dim("> "),
|
|
3793
|
-
query.length > 0 ? query : c.dim(placeholder(corpus)),
|
|
3794
|
-
/* @__PURE__ */ jsx7(Text6, { children: c.dim("\u258C") })
|
|
3795
|
-
] }) }, "query")
|
|
3796
|
-
];
|
|
3797
|
-
let lastGroup = null;
|
|
3798
|
-
for (let i = 0; i < visible.length; i++) {
|
|
3799
|
-
const row = visible[i];
|
|
3800
|
-
if (!row) continue;
|
|
3801
|
-
if (row.group !== null && row.group !== lastGroup) {
|
|
3802
|
-
elements.push(
|
|
3803
|
-
/* @__PURE__ */ jsx7(Box4, { paddingX: 1, children: /* @__PURE__ */ jsx7(Text6, { children: c.dim(`\u2500\u2500 ${row.group} \u2500\u2500`) }) }, `cat:${row.group}`)
|
|
3804
|
-
);
|
|
3805
|
-
lastGroup = row.group;
|
|
3806
|
-
}
|
|
3807
|
-
const isActive = i === activeIndex;
|
|
3808
|
-
elements.push(
|
|
3809
|
-
/* @__PURE__ */ jsx7(Box4, { paddingX: 1, children: /* @__PURE__ */ jsxs5(Text6, { children: [
|
|
3810
|
-
isActive ? "\u25B8 " : " ",
|
|
3811
|
-
isActive ? c.accent(truncate2(row.primary)) : highlight(truncate2(row.primary), row.indices),
|
|
3812
|
-
/* @__PURE__ */ jsx7(Text6, { children: c.dim(` ${row.secondary}`) })
|
|
3813
|
-
] }) }, row.key)
|
|
3814
|
-
);
|
|
3815
|
-
}
|
|
3816
|
-
return /* @__PURE__ */ jsxs5(Box4, { flexDirection: "column", children: [
|
|
3817
|
-
/* @__PURE__ */ jsx7(Panel, { maxWidth: PALETTE_WIDTH, children: elements }),
|
|
3818
|
-
/* @__PURE__ */ jsx7(Text6, { children: c.dim(LIST_NAV_HINT) })
|
|
3819
|
-
] });
|
|
3820
|
-
}
|
|
3821
3745
|
|
|
3822
3746
|
// src/tui/palette/output.ts
|
|
3823
3747
|
function computeMatches(lines, query) {
|
|
@@ -3833,6 +3757,7 @@ function computeMatches(lines, query) {
|
|
|
3833
3757
|
// src/tui/palette/rows.ts
|
|
3834
3758
|
var CORPORA = ["commands", "output", "help"];
|
|
3835
3759
|
var MATCH_LIMIT = 20;
|
|
3760
|
+
var VISIBLE_ROWS = 10;
|
|
3836
3761
|
function flattenHome(sections) {
|
|
3837
3762
|
const out = [];
|
|
3838
3763
|
for (const section of sections) {
|
|
@@ -3853,12 +3778,23 @@ function buildPaletteRows(input) {
|
|
|
3853
3778
|
secondary: e.desc,
|
|
3854
3779
|
argv: null,
|
|
3855
3780
|
destructive: false,
|
|
3856
|
-
indices: [],
|
|
3857
3781
|
group: "keybindings"
|
|
3858
3782
|
}));
|
|
3859
3783
|
}
|
|
3860
3784
|
if (corpus === "output") {
|
|
3861
3785
|
const matches = computeMatches(outputLines, query);
|
|
3786
|
+
if (query.length > 0 && matches.length === 0) {
|
|
3787
|
+
return [
|
|
3788
|
+
{
|
|
3789
|
+
key: "empty",
|
|
3790
|
+
primary: "(no matches)",
|
|
3791
|
+
secondary: `nothing matches "${query}"`,
|
|
3792
|
+
argv: null,
|
|
3793
|
+
destructive: false,
|
|
3794
|
+
group: null
|
|
3795
|
+
}
|
|
3796
|
+
];
|
|
3797
|
+
}
|
|
3862
3798
|
if (matches.length === 0) {
|
|
3863
3799
|
if (outputLines.length === 0) {
|
|
3864
3800
|
return [
|
|
@@ -3868,7 +3804,6 @@ function buildPaletteRows(input) {
|
|
|
3868
3804
|
secondary: "run a /command first",
|
|
3869
3805
|
argv: null,
|
|
3870
3806
|
destructive: false,
|
|
3871
|
-
indices: [],
|
|
3872
3807
|
group: null
|
|
3873
3808
|
}
|
|
3874
3809
|
];
|
|
@@ -3879,8 +3814,7 @@ function buildPaletteRows(input) {
|
|
|
3879
3814
|
secondary: String(i + 1),
|
|
3880
3815
|
argv: null,
|
|
3881
3816
|
destructive: false,
|
|
3882
|
-
|
|
3883
|
-
group: query.length === 0 ? null : "matches"
|
|
3817
|
+
group: null
|
|
3884
3818
|
}));
|
|
3885
3819
|
}
|
|
3886
3820
|
return matches.map((i) => ({
|
|
@@ -3889,7 +3823,6 @@ function buildPaletteRows(input) {
|
|
|
3889
3823
|
secondary: String(i + 1),
|
|
3890
3824
|
argv: null,
|
|
3891
3825
|
destructive: false,
|
|
3892
|
-
indices: [],
|
|
3893
3826
|
group: "matches"
|
|
3894
3827
|
}));
|
|
3895
3828
|
}
|
|
@@ -3904,12 +3837,12 @@ function buildPaletteRows(input) {
|
|
|
3904
3837
|
secondary: cmd.description,
|
|
3905
3838
|
argv: cmd.argv,
|
|
3906
3839
|
destructive: cmd.destructive,
|
|
3907
|
-
indices: [],
|
|
3908
3840
|
group: "recent"
|
|
3909
3841
|
});
|
|
3910
3842
|
}
|
|
3911
3843
|
const homeIds = /* @__PURE__ */ new Set();
|
|
3912
3844
|
for (const { group, action } of flattenHome(homeSections)) {
|
|
3845
|
+
if (recentIds.has(action.id)) continue;
|
|
3913
3846
|
const argv = action.dispatch ?? [action.id];
|
|
3914
3847
|
homeIds.add(action.id);
|
|
3915
3848
|
rows.push({
|
|
@@ -3918,7 +3851,6 @@ function buildPaletteRows(input) {
|
|
|
3918
3851
|
secondary: action.hint,
|
|
3919
3852
|
argv,
|
|
3920
3853
|
destructive: action.destructive ?? false,
|
|
3921
|
-
indices: [],
|
|
3922
3854
|
group
|
|
3923
3855
|
});
|
|
3924
3856
|
}
|
|
@@ -3930,7 +3862,6 @@ function buildPaletteRows(input) {
|
|
|
3930
3862
|
secondary: cmd.description,
|
|
3931
3863
|
argv: cmd.argv,
|
|
3932
3864
|
destructive: cmd.destructive,
|
|
3933
|
-
indices: [],
|
|
3934
3865
|
group: cmd.category
|
|
3935
3866
|
});
|
|
3936
3867
|
}
|
|
@@ -3942,11 +3873,105 @@ function buildPaletteRows(input) {
|
|
|
3942
3873
|
secondary: m.item.description,
|
|
3943
3874
|
argv: m.item.argv,
|
|
3944
3875
|
destructive: m.item.destructive,
|
|
3945
|
-
indices: m.matchedIndices,
|
|
3946
3876
|
group: null
|
|
3947
3877
|
}));
|
|
3948
3878
|
}
|
|
3949
3879
|
|
|
3880
|
+
// src/tui/palette/Palette.tsx
|
|
3881
|
+
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
3882
|
+
var PALETTE_WIDTH = 64;
|
|
3883
|
+
var LABEL_WIDTH = 26;
|
|
3884
|
+
var HINT_WIDTH = 34;
|
|
3885
|
+
function wrap(text, width) {
|
|
3886
|
+
const words = text.split(/\s+/).filter((w) => w.length > 0);
|
|
3887
|
+
const lines = [];
|
|
3888
|
+
let cur = "";
|
|
3889
|
+
for (const w of words) {
|
|
3890
|
+
if (cur.length === 0) cur = w;
|
|
3891
|
+
else if ((cur + " " + w).length <= width) cur = `${cur} ${w}`;
|
|
3892
|
+
else {
|
|
3893
|
+
lines.push(cur);
|
|
3894
|
+
cur = w;
|
|
3895
|
+
}
|
|
3896
|
+
}
|
|
3897
|
+
if (cur) lines.push(cur);
|
|
3898
|
+
return lines;
|
|
3899
|
+
}
|
|
3900
|
+
function truncateLabel(label) {
|
|
3901
|
+
const max = LABEL_WIDTH - 2;
|
|
3902
|
+
return label.length > max ? `${label.slice(0, max - 1)}\u2026` : label;
|
|
3903
|
+
}
|
|
3904
|
+
function placeholder(corpus) {
|
|
3905
|
+
if (corpus === "commands") return "type to search commands";
|
|
3906
|
+
if (corpus === "output") return "type to filter output";
|
|
3907
|
+
return "keybindings";
|
|
3908
|
+
}
|
|
3909
|
+
function Palette({ corpus, query, active, rows }) {
|
|
3910
|
+
const total = rows.length;
|
|
3911
|
+
const scroll = Math.max(0, Math.min(active - (VISIBLE_ROWS - 1), total - VISIBLE_ROWS));
|
|
3912
|
+
const visible = rows.slice(scroll, scroll + VISIBLE_ROWS);
|
|
3913
|
+
const activeIndex = Math.min(Math.max(active - scroll, 0), Math.max(0, visible.length - 1));
|
|
3914
|
+
const elements = [
|
|
3915
|
+
/* @__PURE__ */ jsx7(Box4, { paddingX: 1, children: /* @__PURE__ */ jsxs5(Text6, { children: [
|
|
3916
|
+
c.bold("\u25B8 palette "),
|
|
3917
|
+
/* @__PURE__ */ jsx7(Text6, { children: c.dim(`\xB7 ${corpus}`) })
|
|
3918
|
+
] }) }, "header"),
|
|
3919
|
+
/* @__PURE__ */ jsx7(Box4, { paddingX: 1, children: /* @__PURE__ */ jsxs5(Text6, { children: [
|
|
3920
|
+
c.dim("> "),
|
|
3921
|
+
query.length > 0 ? query : c.dim(placeholder(corpus)),
|
|
3922
|
+
/* @__PURE__ */ jsx7(Text6, { children: c.dim("\u258C") })
|
|
3923
|
+
] }) }, "query")
|
|
3924
|
+
];
|
|
3925
|
+
let lastGroup = null;
|
|
3926
|
+
for (let i = 0; i < visible.length; i++) {
|
|
3927
|
+
const row = visible[i];
|
|
3928
|
+
if (!row) continue;
|
|
3929
|
+
if (row.group !== null && row.group !== lastGroup) {
|
|
3930
|
+
if (lastGroup !== null) {
|
|
3931
|
+
elements.push(
|
|
3932
|
+
/* @__PURE__ */ jsx7(Box4, { children: /* @__PURE__ */ jsx7(Text6, { children: " " }) }, `gap:${row.group}`)
|
|
3933
|
+
);
|
|
3934
|
+
}
|
|
3935
|
+
elements.push(
|
|
3936
|
+
/* @__PURE__ */ jsx7(Box4, { paddingX: 1, children: /* @__PURE__ */ jsx7(Text6, { children: c.bold(`\u2500\u2500 ${row.group} \u2500\u2500`) }) }, `cat:${row.group}`)
|
|
3937
|
+
);
|
|
3938
|
+
lastGroup = row.group;
|
|
3939
|
+
}
|
|
3940
|
+
const isActive = i === activeIndex;
|
|
3941
|
+
const prefix = isActive ? "\u25B8 " : " ";
|
|
3942
|
+
const label = truncateLabel(row.primary);
|
|
3943
|
+
const labelCol = (prefix + label).padEnd(LABEL_WIDTH);
|
|
3944
|
+
const hintRaw = row.argv ? `/${row.argv.join(" ")}` : row.secondary;
|
|
3945
|
+
const hint = hintRaw.length > HINT_WIDTH ? `${hintRaw.slice(0, HINT_WIDTH - 1)}\u2026` : hintRaw;
|
|
3946
|
+
if (isActive) {
|
|
3947
|
+
elements.push(
|
|
3948
|
+
/* @__PURE__ */ jsx7(Box4, { paddingX: 1, children: /* @__PURE__ */ jsx7(Text6, { children: c.inverse(`${labelCol}${hint}`) }) }, row.key)
|
|
3949
|
+
);
|
|
3950
|
+
} else {
|
|
3951
|
+
elements.push(
|
|
3952
|
+
/* @__PURE__ */ jsx7(Box4, { paddingX: 1, children: /* @__PURE__ */ jsxs5(Text6, { children: [
|
|
3953
|
+
c.bold(labelCol),
|
|
3954
|
+
hint.length > 0 ? c.dim(hint) : null
|
|
3955
|
+
] }) }, row.key)
|
|
3956
|
+
);
|
|
3957
|
+
}
|
|
3958
|
+
if (isActive && row.argv && row.secondary) {
|
|
3959
|
+
const detailLines = wrap(row.secondary, PALETTE_WIDTH - 12);
|
|
3960
|
+
for (let di = 0; di < detailLines.length; di++) {
|
|
3961
|
+
const line = detailLines[di] ?? "";
|
|
3962
|
+
const prefix2 = di === 0 ? " \u21B3 " : " ";
|
|
3963
|
+
elements.push(
|
|
3964
|
+
/* @__PURE__ */ jsx7(Box4, { paddingX: 1, children: /* @__PURE__ */ jsx7(Text6, { children: c.dim(`${prefix2}${line}`) }) }, `${row.key}:d:${di}`)
|
|
3965
|
+
);
|
|
3966
|
+
}
|
|
3967
|
+
}
|
|
3968
|
+
}
|
|
3969
|
+
return /* @__PURE__ */ jsxs5(Box4, { flexDirection: "column", children: [
|
|
3970
|
+
/* @__PURE__ */ jsx7(Panel, { maxWidth: PALETTE_WIDTH, children: elements }),
|
|
3971
|
+
/* @__PURE__ */ jsx7(Text6, { children: c.dim(LIST_NAV_HINT) })
|
|
3972
|
+
] });
|
|
3973
|
+
}
|
|
3974
|
+
|
|
3950
3975
|
// src/tui/StatusBar.tsx
|
|
3951
3976
|
import { Text as Text7 } from "ink";
|
|
3952
3977
|
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
@@ -4030,31 +4055,30 @@ function App({
|
|
|
4030
4055
|
};
|
|
4031
4056
|
}, [deps.commands]);
|
|
4032
4057
|
useEffect(() => {
|
|
4033
|
-
if (running) return;
|
|
4058
|
+
if (running || mode.kind !== "dashboard") return;
|
|
4034
4059
|
let cancelled = false;
|
|
4060
|
+
let inFlight = false;
|
|
4061
|
+
const fetched = (p) => {
|
|
4062
|
+
inFlight = false;
|
|
4063
|
+
if (cancelled) return;
|
|
4064
|
+
setPayload(p);
|
|
4065
|
+
setLoading(false);
|
|
4066
|
+
};
|
|
4035
4067
|
setLoading(true);
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
setPayload(p);
|
|
4039
|
-
setLoading(false);
|
|
4040
|
-
}
|
|
4041
|
-
}).catch(() => {
|
|
4042
|
-
if (!cancelled) {
|
|
4043
|
-
setPayload(null);
|
|
4044
|
-
setLoading(false);
|
|
4045
|
-
}
|
|
4046
|
-
});
|
|
4068
|
+
inFlight = true;
|
|
4069
|
+
void deps.fetchStatus().then(fetched).catch(() => fetched(null));
|
|
4047
4070
|
const id = setInterval(() => {
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4071
|
+
if (inFlight) return;
|
|
4072
|
+
inFlight = true;
|
|
4073
|
+
void deps.fetchStatus().then(fetched).catch(() => {
|
|
4074
|
+
inFlight = false;
|
|
4051
4075
|
});
|
|
4052
4076
|
}, refreshMs);
|
|
4053
4077
|
return () => {
|
|
4054
4078
|
cancelled = true;
|
|
4055
4079
|
clearInterval(id);
|
|
4056
4080
|
};
|
|
4057
|
-
}, [running, refreshMs, deps]);
|
|
4081
|
+
}, [running, mode.kind, refreshMs, deps.fetchStatus]);
|
|
4058
4082
|
useEffect(() => {
|
|
4059
4083
|
if (pending === null) return;
|
|
4060
4084
|
const argv = pending;
|
|
@@ -4076,7 +4100,7 @@ function App({
|
|
|
4076
4100
|
return () => {
|
|
4077
4101
|
active = false;
|
|
4078
4102
|
};
|
|
4079
|
-
}, [pending, deps]);
|
|
4103
|
+
}, [pending, deps.dispatch]);
|
|
4080
4104
|
function dispatchCmd(argv) {
|
|
4081
4105
|
setOutput(null);
|
|
4082
4106
|
setRunning(true);
|
|
@@ -4188,9 +4212,15 @@ function App({
|
|
|
4188
4212
|
setBuffer((b) => b + input);
|
|
4189
4213
|
}
|
|
4190
4214
|
}
|
|
4215
|
+
function moveActive(delta) {
|
|
4216
|
+
const max = Math.max(0, paletteRows.length - 1);
|
|
4217
|
+
setPaletteActive((a) => Math.min(max, Math.max(0, a + delta)));
|
|
4218
|
+
}
|
|
4191
4219
|
function handlePaletteInput(input, key) {
|
|
4192
4220
|
if (mode.kind !== "palette") return;
|
|
4193
4221
|
if (key.escape) {
|
|
4222
|
+
setPaletteQuery("");
|
|
4223
|
+
setPaletteActive(0);
|
|
4194
4224
|
setMode({ kind: "dashboard" });
|
|
4195
4225
|
return;
|
|
4196
4226
|
}
|
|
@@ -4201,8 +4231,8 @@ function App({
|
|
|
4201
4231
|
return;
|
|
4202
4232
|
}
|
|
4203
4233
|
if (mode.corpus === "help") {
|
|
4204
|
-
if (key.upArrow)
|
|
4205
|
-
else if (key.downArrow)
|
|
4234
|
+
if (key.upArrow) moveActive(-1);
|
|
4235
|
+
else if (key.downArrow) moveActive(1);
|
|
4206
4236
|
return;
|
|
4207
4237
|
}
|
|
4208
4238
|
if (key.return) {
|
|
@@ -4210,16 +4240,16 @@ function App({
|
|
|
4210
4240
|
const row = paletteRows[paletteActive];
|
|
4211
4241
|
if (row?.argv) handleRun(row.argv, row.destructive);
|
|
4212
4242
|
} else {
|
|
4213
|
-
|
|
4243
|
+
moveActive(1);
|
|
4214
4244
|
}
|
|
4215
4245
|
return;
|
|
4216
4246
|
}
|
|
4217
4247
|
if (key.upArrow) {
|
|
4218
|
-
|
|
4248
|
+
moveActive(-1);
|
|
4219
4249
|
return;
|
|
4220
4250
|
}
|
|
4221
4251
|
if (key.downArrow) {
|
|
4222
|
-
|
|
4252
|
+
moveActive(1);
|
|
4223
4253
|
return;
|
|
4224
4254
|
}
|
|
4225
4255
|
if (key.backspace || key.delete) {
|
|
@@ -4282,16 +4312,18 @@ function App({
|
|
|
4282
4312
|
dispatchCmd(argv);
|
|
4283
4313
|
void recordRuns(argv);
|
|
4284
4314
|
}
|
|
4285
|
-
const
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4315
|
+
const paletteRows = useMemo(
|
|
4316
|
+
() => buildPaletteRows({
|
|
4317
|
+
corpus: mode.kind === "palette" ? mode.corpus : "commands",
|
|
4318
|
+
query: paletteQuery,
|
|
4319
|
+
commands: deps.commands ?? [],
|
|
4320
|
+
matcher: deps.matcher ?? handRolledMatcher,
|
|
4321
|
+
recent,
|
|
4322
|
+
homeSections,
|
|
4323
|
+
outputLines: searchLines
|
|
4324
|
+
}),
|
|
4325
|
+
[mode, paletteQuery, deps.commands, deps.matcher, recent, homeSections, searchLines]
|
|
4326
|
+
);
|
|
4295
4327
|
if (mode.kind === "palette") {
|
|
4296
4328
|
return /* @__PURE__ */ jsxs7(Box5, { flexDirection: "column", children: [
|
|
4297
4329
|
/* @__PURE__ */ jsx9(Header, { tagline: `palette \xB7 ${mode.corpus}` }),
|