reasonix 0.23.1 → 0.24.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/dashboard/dist/app.js +1723 -574
- package/dashboard/dist/app.js.map +1 -1
- package/dist/cli/.-3G6VX5S7.js +327 -0
- package/dist/cli/.-6YRPB2C7.js +329 -0
- package/dist/cli/.-6YRPB2C7.js.map +1 -0
- package/dist/cli/.-EYSVINK3.js +317 -0
- package/dist/cli/.-EYSVINK3.js.map +1 -0
- package/dist/cli/banner-demo-QKOPDSTL.js +77 -0
- package/dist/cli/banner-demo-QKOPDSTL.js.map +1 -0
- package/dist/cli/card-demo-5TVXJISK.js +944 -0
- package/dist/cli/card-demo-5TVXJISK.js.map +1 -0
- package/dist/cli/chunk-2H7UOFLK.js +11 -0
- package/dist/cli/chunk-2H7UOFLK.js.map +1 -0
- package/dist/cli/chunk-BGTXZKNY.js +197 -0
- package/dist/cli/chunk-BGTXZKNY.js.map +1 -0
- package/dist/cli/chunk-JHXQDL7B.js +2056 -0
- package/dist/cli/chunk-JHXQDL7B.js.map +1 -0
- package/dist/cli/flicker-demo-MOB6GAW4.js +165 -0
- package/dist/cli/flicker-demo-MOB6GAW4.js.map +1 -0
- package/dist/cli/index.js +3654 -2035
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/preview-4FOEEE5G.js +224 -0
- package/dist/cli/preview-4FOEEE5G.js.map +1 -0
- package/dist/cli/{prompt-YUL7CYKY.js → prompt-VZQ2CPID.js} +2 -1
- package/dist/cli/prompt-VZQ2CPID.js.map +1 -0
- package/dist/cli/renderer-demo-2BIGEV2T.js +95 -0
- package/dist/cli/renderer-demo-2BIGEV2T.js.map +1 -0
- package/dist/cli/select-demo-OA5N34BJ.js +107 -0
- package/dist/cli/select-demo-OA5N34BJ.js.map +1 -0
- package/dist/cli/stress-demo-I7XRPQMM.js +211 -0
- package/dist/cli/stress-demo-I7XRPQMM.js.map +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +22 -9
- package/dist/index.js.map +1 -1
- package/package.json +6 -4
- /package/dist/cli/{prompt-YUL7CYKY.js.map → .-3G6VX5S7.js.map} +0 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
CharPool,
|
|
4
|
+
HyperlinkPool,
|
|
5
|
+
StylePool,
|
|
6
|
+
ink_compat_exports,
|
|
7
|
+
mount,
|
|
8
|
+
useKeystroke
|
|
9
|
+
} from "./chunk-JHXQDL7B.js";
|
|
10
|
+
import "./chunk-2H7UOFLK.js";
|
|
11
|
+
|
|
12
|
+
// src/cli/commands/preview.tsx
|
|
13
|
+
import React, { useEffect, useRef, useState } from "react";
|
|
14
|
+
var BRAND = "#79c0ff";
|
|
15
|
+
var FAINT = "#6e7681";
|
|
16
|
+
var ACCENT = "#d2a8ff";
|
|
17
|
+
var OK = "#7ee787";
|
|
18
|
+
var ERR = "#ff8b81";
|
|
19
|
+
var META = "#8b949e";
|
|
20
|
+
var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
21
|
+
var SPINNER_TICK_MS = 80;
|
|
22
|
+
var TOKEN_TICK_MS = 33;
|
|
23
|
+
var CHARS_PER_TICK = 3;
|
|
24
|
+
function buildResponse(userText) {
|
|
25
|
+
return `you said: ${userText}. Streamed cell-by-cell \u2014 only the new chars get patched.`;
|
|
26
|
+
}
|
|
27
|
+
var SLASH_COMMANDS = [
|
|
28
|
+
{ name: "/help", summary: "list available commands" },
|
|
29
|
+
{ name: "/clear", summary: "clear the history" },
|
|
30
|
+
{ name: "/exit", summary: "leave the preview" }
|
|
31
|
+
];
|
|
32
|
+
function Header() {
|
|
33
|
+
return /* @__PURE__ */ React.createElement(ink_compat_exports.Box, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React.createElement(ink_compat_exports.Text, { color: BRAND, bold: true }, "\u25C8 Reasonix"), /* @__PURE__ */ React.createElement(ink_compat_exports.Text, { color: FAINT }, "preview \xB7 cell-diff renderer"));
|
|
34
|
+
}
|
|
35
|
+
function HistoryRow({ entry }) {
|
|
36
|
+
const { tone, glyph } = decorate(entry.role);
|
|
37
|
+
return /* @__PURE__ */ React.createElement(ink_compat_exports.Box, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React.createElement(ink_compat_exports.Text, { color: tone }, glyph), /* @__PURE__ */ React.createElement(ink_compat_exports.Text, { color: entry.role === "info" ? META : void 0 }, entry.text));
|
|
38
|
+
}
|
|
39
|
+
function decorate(role) {
|
|
40
|
+
switch (role) {
|
|
41
|
+
case "user":
|
|
42
|
+
return { tone: ACCENT, glyph: "\u203A" };
|
|
43
|
+
case "echo":
|
|
44
|
+
return { tone: OK, glyph: "\u2039" };
|
|
45
|
+
case "info":
|
|
46
|
+
return { tone: META, glyph: "\xB7" };
|
|
47
|
+
case "error":
|
|
48
|
+
return { tone: ERR, glyph: "\u2716" };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function PromptLine({ value, placeholder }) {
|
|
52
|
+
const showPlaceholder = value.length === 0;
|
|
53
|
+
return /* @__PURE__ */ React.createElement(ink_compat_exports.Box, { flexDirection: "row", gap: 1, marginTop: 1 }, /* @__PURE__ */ React.createElement(ink_compat_exports.Text, { color: BRAND, bold: true }, "\u203A"), showPlaceholder ? /* @__PURE__ */ React.createElement(ink_compat_exports.Text, { dimColor: true }, placeholder) : /* @__PURE__ */ React.createElement(ink_compat_exports.Text, null, value), /* @__PURE__ */ React.createElement(ink_compat_exports.Text, { color: FAINT }, "\u258F"));
|
|
54
|
+
}
|
|
55
|
+
function HintBar({ streaming }) {
|
|
56
|
+
return /* @__PURE__ */ React.createElement(ink_compat_exports.Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(ink_compat_exports.Text, { dimColor: true }, streaming ? "thinking \u2014 input paused" : "Enter submit \xB7 / for commands \xB7 Esc exit"));
|
|
57
|
+
}
|
|
58
|
+
function StreamingRow({ userText, response, frame, done }) {
|
|
59
|
+
const glyph = done ? "\u2039" : SPINNER_FRAMES[frame % SPINNER_FRAMES.length] ?? "\xB7";
|
|
60
|
+
return /* @__PURE__ */ React.createElement(ink_compat_exports.Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(ink_compat_exports.Box, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React.createElement(ink_compat_exports.Text, { color: ACCENT }, "\u203A"), /* @__PURE__ */ React.createElement(ink_compat_exports.Text, null, userText)), /* @__PURE__ */ React.createElement(ink_compat_exports.Box, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React.createElement(ink_compat_exports.Text, { color: done ? OK : BRAND }, glyph), /* @__PURE__ */ React.createElement(ink_compat_exports.Text, null, response.length > 0 ? response : "thinking\u2026")));
|
|
61
|
+
}
|
|
62
|
+
function trySlash(text, onExit, onClear) {
|
|
63
|
+
if (!text.startsWith("/")) return null;
|
|
64
|
+
const [name] = text.split(/\s+/, 1);
|
|
65
|
+
const cmd = name ?? text;
|
|
66
|
+
if (cmd === "/exit") {
|
|
67
|
+
onExit();
|
|
68
|
+
return [{ role: "info", text: "exiting\u2026" }];
|
|
69
|
+
}
|
|
70
|
+
if (cmd === "/clear") {
|
|
71
|
+
onClear();
|
|
72
|
+
return "cleared";
|
|
73
|
+
}
|
|
74
|
+
if (cmd === "/help") {
|
|
75
|
+
return [
|
|
76
|
+
{ role: "info", text: "available commands:" },
|
|
77
|
+
...SLASH_COMMANDS.map((c) => ({ role: "info", text: ` ${c.name} \u2014 ${c.summary}` }))
|
|
78
|
+
];
|
|
79
|
+
}
|
|
80
|
+
return [{ role: "error", text: `unknown command: ${cmd}` }];
|
|
81
|
+
}
|
|
82
|
+
function PreviewShell({ onExit }) {
|
|
83
|
+
const [history, setHistory] = useState([]);
|
|
84
|
+
const [draft, setDraft] = useState("");
|
|
85
|
+
const [inflight, setInflight] = useState(null);
|
|
86
|
+
const draftRef = useRef("");
|
|
87
|
+
const nextIdRef = useRef(0);
|
|
88
|
+
const inflightRef = useRef(null);
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
inflightRef.current = inflight;
|
|
91
|
+
}, [inflight]);
|
|
92
|
+
const streaming = inflight !== null;
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
if (!streaming) return;
|
|
95
|
+
const spin = setInterval(() => {
|
|
96
|
+
const cur = inflightRef.current;
|
|
97
|
+
if (!cur) return;
|
|
98
|
+
setInflight({ ...cur, frame: cur.frame + 1 });
|
|
99
|
+
}, SPINNER_TICK_MS);
|
|
100
|
+
const reveal = setInterval(() => {
|
|
101
|
+
const cur = inflightRef.current;
|
|
102
|
+
if (!cur) return;
|
|
103
|
+
if (cur.revealed >= cur.fullResponse.length) {
|
|
104
|
+
clearInterval(reveal);
|
|
105
|
+
setTimeout(() => {
|
|
106
|
+
const fin = inflightRef.current;
|
|
107
|
+
if (!fin) return;
|
|
108
|
+
const id = nextIdRef.current;
|
|
109
|
+
nextIdRef.current = id + 2;
|
|
110
|
+
setHistory((prev) => [
|
|
111
|
+
...prev,
|
|
112
|
+
{ id, role: "user", text: fin.userText },
|
|
113
|
+
{ id: id + 1, role: "echo", text: fin.fullResponse }
|
|
114
|
+
]);
|
|
115
|
+
setInflight(null);
|
|
116
|
+
}, 200);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const next = Math.min(cur.fullResponse.length, cur.revealed + CHARS_PER_TICK);
|
|
120
|
+
setInflight({ ...cur, revealed: next });
|
|
121
|
+
}, TOKEN_TICK_MS);
|
|
122
|
+
return () => {
|
|
123
|
+
clearInterval(spin);
|
|
124
|
+
clearInterval(reveal);
|
|
125
|
+
};
|
|
126
|
+
}, [streaming]);
|
|
127
|
+
useKeystroke((k) => {
|
|
128
|
+
if (k.escape) {
|
|
129
|
+
onExit();
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (inflightRef.current) return;
|
|
133
|
+
if (k.return) {
|
|
134
|
+
const text = draftRef.current.trim();
|
|
135
|
+
if (text.length === 0) return;
|
|
136
|
+
const slashResult = trySlash(text, onExit, () => {
|
|
137
|
+
nextIdRef.current = 0;
|
|
138
|
+
setHistory([]);
|
|
139
|
+
});
|
|
140
|
+
if (slashResult === "cleared") {
|
|
141
|
+
draftRef.current = "";
|
|
142
|
+
setDraft("");
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
if (slashResult) {
|
|
146
|
+
const id = nextIdRef.current;
|
|
147
|
+
nextIdRef.current = id + 1 + slashResult.length;
|
|
148
|
+
setHistory((prev) => [
|
|
149
|
+
...prev,
|
|
150
|
+
{ id, role: "user", text },
|
|
151
|
+
...slashResult.map((r, i) => ({ id: id + 1 + i, role: r.role, text: r.text }))
|
|
152
|
+
]);
|
|
153
|
+
draftRef.current = "";
|
|
154
|
+
setDraft("");
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
setInflight({ userText: text, fullResponse: buildResponse(text), revealed: 0, frame: 0 });
|
|
158
|
+
draftRef.current = "";
|
|
159
|
+
setDraft("");
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (k.backspace) {
|
|
163
|
+
const next = draftRef.current.slice(0, -1);
|
|
164
|
+
draftRef.current = next;
|
|
165
|
+
setDraft(next);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
if (k.ctrl || k.meta) return;
|
|
169
|
+
if (k.input && k.input.length > 0) {
|
|
170
|
+
const next = draftRef.current + k.input;
|
|
171
|
+
draftRef.current = next;
|
|
172
|
+
setDraft(next);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
return /* @__PURE__ */ React.createElement(ink_compat_exports.Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, null), /* @__PURE__ */ React.createElement(ink_compat_exports.Box, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React.createElement(ink_compat_exports.Static, { items: history }, (entry) => /* @__PURE__ */ React.createElement(HistoryRow, { key: entry.id, entry }))), inflight ? /* @__PURE__ */ React.createElement(ink_compat_exports.Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(
|
|
176
|
+
StreamingRow,
|
|
177
|
+
{
|
|
178
|
+
userText: inflight.userText,
|
|
179
|
+
response: inflight.fullResponse.slice(0, inflight.revealed),
|
|
180
|
+
frame: inflight.frame,
|
|
181
|
+
done: inflight.revealed >= inflight.fullResponse.length
|
|
182
|
+
}
|
|
183
|
+
)) : /* @__PURE__ */ React.createElement(PromptLine, { value: draft, placeholder: "say something\u2026" }), /* @__PURE__ */ React.createElement(HintBar, { streaming: inflight !== null }));
|
|
184
|
+
}
|
|
185
|
+
async function runPreview(opts = {}) {
|
|
186
|
+
const stdout = opts.stdout ?? process.stdout;
|
|
187
|
+
const stdin = opts.stdin ?? process.stdin;
|
|
188
|
+
if (!stdin.isTTY || !stdout.isTTY) {
|
|
189
|
+
console.error("preview requires an interactive TTY.");
|
|
190
|
+
process.exit(1);
|
|
191
|
+
}
|
|
192
|
+
const pools = {
|
|
193
|
+
char: new CharPool(),
|
|
194
|
+
style: new StylePool(),
|
|
195
|
+
hyperlink: new HyperlinkPool()
|
|
196
|
+
};
|
|
197
|
+
let resolveExit = () => {
|
|
198
|
+
};
|
|
199
|
+
const exited = new Promise((resolve) => {
|
|
200
|
+
resolveExit = resolve;
|
|
201
|
+
});
|
|
202
|
+
const handle = mount(/* @__PURE__ */ React.createElement(PreviewShell, { onExit: () => resolveExit() }), {
|
|
203
|
+
viewportWidth: stdout.columns ?? 80,
|
|
204
|
+
viewportHeight: stdout.rows ?? 24,
|
|
205
|
+
pools,
|
|
206
|
+
write: (bytes) => stdout.write(bytes),
|
|
207
|
+
stdin,
|
|
208
|
+
onExit: () => resolveExit()
|
|
209
|
+
});
|
|
210
|
+
const onResize = () => handle.resize(stdout.columns ?? 80, stdout.rows ?? 24);
|
|
211
|
+
stdout.on("resize", onResize);
|
|
212
|
+
try {
|
|
213
|
+
await exited;
|
|
214
|
+
} finally {
|
|
215
|
+
stdout.off("resize", onResize);
|
|
216
|
+
handle.destroy();
|
|
217
|
+
stdin.pause();
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
export {
|
|
221
|
+
PreviewShell,
|
|
222
|
+
runPreview
|
|
223
|
+
};
|
|
224
|
+
//# sourceMappingURL=preview-4FOEEE5G.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/preview.tsx"],"sourcesContent":["// biome-ignore lint/style/useImportType: tsconfig jsx=react needs React in value scope for JSX compilation\nimport React, { useEffect, useRef, useState } from \"react\";\nimport {\n CharPool,\n type Handle,\n HyperlinkPool,\n StylePool,\n inkCompat,\n mount,\n useKeystroke,\n} from \"../../renderer/index.js\";\n\nconst BRAND = \"#79c0ff\";\nconst FAINT = \"#6e7681\";\nconst ACCENT = \"#d2a8ff\";\nconst OK = \"#7ee787\";\nconst ERR = \"#ff8b81\";\nconst META = \"#8b949e\";\n\ninterface HistoryEntry {\n readonly id: number;\n readonly role: \"user\" | \"echo\" | \"info\" | \"error\";\n readonly text: string;\n}\n\nconst SPINNER_FRAMES = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"] as const;\nconst SPINNER_TICK_MS = 80;\nconst TOKEN_TICK_MS = 33;\nconst CHARS_PER_TICK = 3;\n\nfunction buildResponse(userText: string): string {\n return `you said: ${userText}. Streamed cell-by-cell — only the new chars get patched.`;\n}\n\ninterface SlashCommand {\n readonly name: string;\n readonly summary: string;\n}\n\nconst SLASH_COMMANDS: ReadonlyArray<SlashCommand> = [\n { name: \"/help\", summary: \"list available commands\" },\n { name: \"/clear\", summary: \"clear the history\" },\n { name: \"/exit\", summary: \"leave the preview\" },\n];\n\nfunction Header(): React.ReactElement {\n return (\n <inkCompat.Box flexDirection=\"row\" gap={1}>\n <inkCompat.Text color={BRAND} bold>\n ◈ Reasonix\n </inkCompat.Text>\n <inkCompat.Text color={FAINT}>preview · cell-diff renderer</inkCompat.Text>\n </inkCompat.Box>\n );\n}\n\nfunction HistoryRow({ entry }: { entry: HistoryEntry }): React.ReactElement {\n const { tone, glyph } = decorate(entry.role);\n return (\n <inkCompat.Box flexDirection=\"row\" gap={1}>\n <inkCompat.Text color={tone}>{glyph}</inkCompat.Text>\n <inkCompat.Text color={entry.role === \"info\" ? META : undefined}>{entry.text}</inkCompat.Text>\n </inkCompat.Box>\n );\n}\n\nfunction decorate(role: HistoryEntry[\"role\"]): { tone: string; glyph: string } {\n switch (role) {\n case \"user\":\n return { tone: ACCENT, glyph: \"›\" };\n case \"echo\":\n return { tone: OK, glyph: \"‹\" };\n case \"info\":\n return { tone: META, glyph: \"·\" };\n case \"error\":\n return { tone: ERR, glyph: \"✖\" };\n }\n}\n\ninterface PromptLineProps {\n readonly value: string;\n readonly placeholder: string;\n}\n\nfunction PromptLine({ value, placeholder }: PromptLineProps): React.ReactElement {\n const showPlaceholder = value.length === 0;\n return (\n <inkCompat.Box flexDirection=\"row\" gap={1} marginTop={1}>\n <inkCompat.Text color={BRAND} bold>\n ›\n </inkCompat.Text>\n {showPlaceholder ? (\n <inkCompat.Text dimColor>{placeholder}</inkCompat.Text>\n ) : (\n <inkCompat.Text>{value}</inkCompat.Text>\n )}\n <inkCompat.Text color={FAINT}>▏</inkCompat.Text>\n </inkCompat.Box>\n );\n}\n\nfunction HintBar({ streaming }: { streaming: boolean }): React.ReactElement {\n return (\n <inkCompat.Box marginTop={1}>\n <inkCompat.Text dimColor>\n {streaming ? \"thinking — input paused\" : \"Enter submit · / for commands · Esc exit\"}\n </inkCompat.Text>\n </inkCompat.Box>\n );\n}\n\ninterface StreamingProps {\n readonly userText: string;\n readonly response: string;\n readonly frame: number;\n readonly done: boolean;\n}\n\nfunction StreamingRow({ userText, response, frame, done }: StreamingProps): React.ReactElement {\n const glyph = done ? \"‹\" : (SPINNER_FRAMES[frame % SPINNER_FRAMES.length] ?? \"·\");\n return (\n <inkCompat.Box flexDirection=\"column\">\n <inkCompat.Box flexDirection=\"row\" gap={1}>\n <inkCompat.Text color={ACCENT}>›</inkCompat.Text>\n <inkCompat.Text>{userText}</inkCompat.Text>\n </inkCompat.Box>\n <inkCompat.Box flexDirection=\"row\" gap={1}>\n <inkCompat.Text color={done ? OK : BRAND}>{glyph}</inkCompat.Text>\n <inkCompat.Text>{response.length > 0 ? response : \"thinking…\"}</inkCompat.Text>\n </inkCompat.Box>\n </inkCompat.Box>\n );\n}\n\ninterface ShellProps {\n onExit: () => void;\n}\n\ninterface Reply {\n readonly role: \"echo\" | \"info\" | \"error\";\n readonly text: string;\n}\n\nfunction trySlash(\n text: string,\n onExit: () => void,\n onClear: () => void,\n): ReadonlyArray<Reply> | \"cleared\" | null {\n if (!text.startsWith(\"/\")) return null;\n const [name] = text.split(/\\s+/, 1);\n const cmd = name ?? text;\n if (cmd === \"/exit\") {\n onExit();\n return [{ role: \"info\", text: \"exiting…\" }];\n }\n if (cmd === \"/clear\") {\n onClear();\n return \"cleared\";\n }\n if (cmd === \"/help\") {\n return [\n { role: \"info\", text: \"available commands:\" },\n ...SLASH_COMMANDS.map((c) => ({ role: \"info\" as const, text: ` ${c.name} — ${c.summary}` })),\n ];\n }\n return [{ role: \"error\", text: `unknown command: ${cmd}` }];\n}\n\ninterface InflightState {\n readonly userText: string;\n readonly fullResponse: string;\n readonly revealed: number;\n readonly frame: number;\n}\n\nexport function PreviewShell({ onExit }: ShellProps): React.ReactElement {\n const [history, setHistory] = useState<ReadonlyArray<HistoryEntry>>([]);\n const [draft, setDraft] = useState(\"\");\n const [inflight, setInflight] = useState<InflightState | null>(null);\n const draftRef = useRef(\"\");\n const nextIdRef = useRef(0);\n const inflightRef = useRef<InflightState | null>(null);\n\n useEffect(() => {\n inflightRef.current = inflight;\n }, [inflight]);\n\n const streaming = inflight !== null;\n useEffect(() => {\n if (!streaming) return;\n const spin = setInterval(() => {\n const cur = inflightRef.current;\n if (!cur) return;\n setInflight({ ...cur, frame: cur.frame + 1 });\n }, SPINNER_TICK_MS);\n const reveal = setInterval(() => {\n const cur = inflightRef.current;\n if (!cur) return;\n if (cur.revealed >= cur.fullResponse.length) {\n clearInterval(reveal);\n setTimeout(() => {\n const fin = inflightRef.current;\n if (!fin) return;\n const id = nextIdRef.current;\n nextIdRef.current = id + 2;\n setHistory((prev) => [\n ...prev,\n { id, role: \"user\", text: fin.userText },\n { id: id + 1, role: \"echo\", text: fin.fullResponse },\n ]);\n setInflight(null);\n }, 200);\n return;\n }\n const next = Math.min(cur.fullResponse.length, cur.revealed + CHARS_PER_TICK);\n setInflight({ ...cur, revealed: next });\n }, TOKEN_TICK_MS);\n return () => {\n clearInterval(spin);\n clearInterval(reveal);\n };\n }, [streaming]);\n\n useKeystroke((k) => {\n if (k.escape) {\n onExit();\n return;\n }\n if (inflightRef.current) return;\n if (k.return) {\n const text = draftRef.current.trim();\n if (text.length === 0) return;\n const slashResult = trySlash(text, onExit, () => {\n nextIdRef.current = 0;\n setHistory([]);\n });\n if (slashResult === \"cleared\") {\n draftRef.current = \"\";\n setDraft(\"\");\n return;\n }\n if (slashResult) {\n const id = nextIdRef.current;\n nextIdRef.current = id + 1 + slashResult.length;\n setHistory((prev) => [\n ...prev,\n { id, role: \"user\", text },\n ...slashResult.map((r, i) => ({ id: id + 1 + i, role: r.role, text: r.text })),\n ]);\n draftRef.current = \"\";\n setDraft(\"\");\n return;\n }\n setInflight({ userText: text, fullResponse: buildResponse(text), revealed: 0, frame: 0 });\n draftRef.current = \"\";\n setDraft(\"\");\n return;\n }\n if (k.backspace) {\n const next = draftRef.current.slice(0, -1);\n draftRef.current = next;\n setDraft(next);\n return;\n }\n if (k.ctrl || k.meta) return;\n if (k.input && k.input.length > 0) {\n const next = draftRef.current + k.input;\n draftRef.current = next;\n setDraft(next);\n }\n });\n\n return (\n <inkCompat.Box flexDirection=\"column\">\n <Header />\n <inkCompat.Box flexDirection=\"column\" marginTop={1}>\n <inkCompat.Static items={history}>\n {(entry) => <HistoryRow key={entry.id} entry={entry} />}\n </inkCompat.Static>\n </inkCompat.Box>\n {inflight ? (\n <inkCompat.Box marginTop={1}>\n <StreamingRow\n userText={inflight.userText}\n response={inflight.fullResponse.slice(0, inflight.revealed)}\n frame={inflight.frame}\n done={inflight.revealed >= inflight.fullResponse.length}\n />\n </inkCompat.Box>\n ) : (\n <PromptLine value={draft} placeholder=\"say something…\" />\n )}\n <HintBar streaming={inflight !== null} />\n </inkCompat.Box>\n );\n}\n\nexport interface PreviewOptions {\n readonly stdout?: NodeJS.WriteStream;\n readonly stdin?: NodeJS.ReadStream;\n}\n\nexport async function runPreview(opts: PreviewOptions = {}): Promise<void> {\n const stdout = opts.stdout ?? process.stdout;\n const stdin = opts.stdin ?? process.stdin;\n\n if (!stdin.isTTY || !stdout.isTTY) {\n console.error(\"preview requires an interactive TTY.\");\n process.exit(1);\n }\n\n const pools = {\n char: new CharPool(),\n style: new StylePool(),\n hyperlink: new HyperlinkPool(),\n };\n\n let resolveExit: () => void = () => {};\n const exited = new Promise<void>((resolve) => {\n resolveExit = resolve;\n });\n\n const handle: Handle = mount(<PreviewShell onExit={() => resolveExit()} />, {\n viewportWidth: stdout.columns ?? 80,\n viewportHeight: stdout.rows ?? 24,\n pools,\n write: (bytes) => stdout.write(bytes),\n stdin,\n onExit: () => resolveExit(),\n });\n\n const onResize = () => handle.resize(stdout.columns ?? 80, stdout.rows ?? 24);\n stdout.on(\"resize\", onResize);\n\n try {\n await exited;\n } finally {\n stdout.off(\"resize\", onResize);\n handle.destroy();\n stdin.pause();\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -3,8 +3,9 @@ import {
|
|
|
3
3
|
CODE_SYSTEM_PROMPT,
|
|
4
4
|
codeSystemPrompt
|
|
5
5
|
} from "./chunk-R2L5YEEF.js";
|
|
6
|
+
import "./chunk-2H7UOFLK.js";
|
|
6
7
|
export {
|
|
7
8
|
CODE_SYSTEM_PROMPT,
|
|
8
9
|
codeSystemPrompt
|
|
9
10
|
};
|
|
10
|
-
//# sourceMappingURL=prompt-
|
|
11
|
+
//# sourceMappingURL=prompt-VZQ2CPID.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
Box,
|
|
4
|
+
CharPool,
|
|
5
|
+
HyperlinkPool,
|
|
6
|
+
StylePool,
|
|
7
|
+
Text,
|
|
8
|
+
mount,
|
|
9
|
+
useKeystroke
|
|
10
|
+
} from "./chunk-JHXQDL7B.js";
|
|
11
|
+
import "./chunk-2H7UOFLK.js";
|
|
12
|
+
|
|
13
|
+
// src/cli/commands/renderer-demo.tsx
|
|
14
|
+
import React, { useState } from "react";
|
|
15
|
+
var ACCENT = { apply: "\x1B[36m", revert: "\x1B[39m" };
|
|
16
|
+
var DIM = { apply: "\x1B[2m", revert: "\x1B[22m" };
|
|
17
|
+
var FAINT_BORDER = [{ apply: "\x1B[90m", revert: "\x1B[39m" }];
|
|
18
|
+
function describeKey(k) {
|
|
19
|
+
if (k.escape) return "ESC";
|
|
20
|
+
if (k.return) return "Return";
|
|
21
|
+
if (k.tab) return "Tab";
|
|
22
|
+
if (k.backspace) return "Backspace";
|
|
23
|
+
if (k.delete) return "Delete";
|
|
24
|
+
if (k.upArrow) return `${modPrefix(k)}\u2191`;
|
|
25
|
+
if (k.downArrow) return `${modPrefix(k)}\u2193`;
|
|
26
|
+
if (k.leftArrow) return `${modPrefix(k)}\u2190`;
|
|
27
|
+
if (k.rightArrow) return `${modPrefix(k)}\u2192`;
|
|
28
|
+
if (k.home) return "Home";
|
|
29
|
+
if (k.end) return "End";
|
|
30
|
+
if (k.pageUp) return "PageUp";
|
|
31
|
+
if (k.pageDown) return "PageDown";
|
|
32
|
+
if (k.ctrl && k.input) return `Ctrl+${k.input.toUpperCase()}`;
|
|
33
|
+
if (k.meta && k.input) return `Alt+${k.input}`;
|
|
34
|
+
return k.input || "?";
|
|
35
|
+
}
|
|
36
|
+
function modPrefix(k) {
|
|
37
|
+
let p = "";
|
|
38
|
+
if (k.ctrl) p += "Ctrl+";
|
|
39
|
+
if (k.meta) p += "Alt+";
|
|
40
|
+
if (k.shift) p += "Shift+";
|
|
41
|
+
return p;
|
|
42
|
+
}
|
|
43
|
+
function Demo({ onExit }) {
|
|
44
|
+
const [count, setCount] = useState(0);
|
|
45
|
+
const [last, setLast] = useState("(none yet)");
|
|
46
|
+
useKeystroke((k) => {
|
|
47
|
+
if (k.escape) {
|
|
48
|
+
onExit();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
setCount((n) => n + 1);
|
|
52
|
+
setLast(describeKey(k));
|
|
53
|
+
});
|
|
54
|
+
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: FAINT_BORDER, padding: 1 }, /* @__PURE__ */ React.createElement(Text, { style: [ACCENT] }, "Reasonix cell-diff renderer \xB7 demo"), /* @__PURE__ */ React.createElement(Text, { style: [DIM] }, "Press any key. ESC to exit."), /* @__PURE__ */ React.createElement(Box, { paddingTop: 1, flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, null, "Count : "), /* @__PURE__ */ React.createElement(Text, null, String(count))), /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, null, "Last : "), /* @__PURE__ */ React.createElement(Text, null, last)));
|
|
55
|
+
}
|
|
56
|
+
async function runRendererDemo(opts = {}) {
|
|
57
|
+
const stdout = opts.stdout ?? process.stdout;
|
|
58
|
+
const stdin = opts.stdin ?? process.stdin;
|
|
59
|
+
if (!stdin.isTTY || !stdout.isTTY) {
|
|
60
|
+
console.error("renderer-demo requires an interactive TTY.");
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
const pools = {
|
|
64
|
+
char: new CharPool(),
|
|
65
|
+
style: new StylePool(),
|
|
66
|
+
hyperlink: new HyperlinkPool()
|
|
67
|
+
};
|
|
68
|
+
let resolveExit = () => {
|
|
69
|
+
};
|
|
70
|
+
const exited = new Promise((resolve) => {
|
|
71
|
+
resolveExit = resolve;
|
|
72
|
+
});
|
|
73
|
+
const handle = mount(/* @__PURE__ */ React.createElement(Demo, { onExit: () => resolveExit() }), {
|
|
74
|
+
viewportWidth: stdout.columns ?? 80,
|
|
75
|
+
viewportHeight: stdout.rows ?? 24,
|
|
76
|
+
pools,
|
|
77
|
+
write: (bytes) => stdout.write(bytes),
|
|
78
|
+
stdin
|
|
79
|
+
});
|
|
80
|
+
const onResize = () => {
|
|
81
|
+
handle.resize(stdout.columns ?? 80, stdout.rows ?? 24);
|
|
82
|
+
};
|
|
83
|
+
stdout.on("resize", onResize);
|
|
84
|
+
try {
|
|
85
|
+
await exited;
|
|
86
|
+
} finally {
|
|
87
|
+
stdout.off("resize", onResize);
|
|
88
|
+
handle.destroy();
|
|
89
|
+
stdin.pause();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
export {
|
|
93
|
+
runRendererDemo
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=renderer-demo-2BIGEV2T.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/renderer-demo.tsx"],"sourcesContent":["// biome-ignore lint/style/useImportType: tsconfig jsx=react needs React in value scope for JSX compilation\nimport React, { useState } from \"react\";\nimport {\n Box,\n CharPool,\n HyperlinkPool,\n type Keystroke,\n StylePool,\n Text,\n mount,\n useKeystroke,\n} from \"../../renderer/index.js\";\n\nconst ACCENT = { apply: \"\\x1b[36m\", revert: \"\\x1b[39m\" };\nconst DIM = { apply: \"\\x1b[2m\", revert: \"\\x1b[22m\" };\nconst FAINT_BORDER = [{ apply: \"\\x1b[90m\", revert: \"\\x1b[39m\" }];\n\nfunction describeKey(k: Keystroke): string {\n if (k.escape) return \"ESC\";\n if (k.return) return \"Return\";\n if (k.tab) return \"Tab\";\n if (k.backspace) return \"Backspace\";\n if (k.delete) return \"Delete\";\n if (k.upArrow) return `${modPrefix(k)}↑`;\n if (k.downArrow) return `${modPrefix(k)}↓`;\n if (k.leftArrow) return `${modPrefix(k)}←`;\n if (k.rightArrow) return `${modPrefix(k)}→`;\n if (k.home) return \"Home\";\n if (k.end) return \"End\";\n if (k.pageUp) return \"PageUp\";\n if (k.pageDown) return \"PageDown\";\n if (k.ctrl && k.input) return `Ctrl+${k.input.toUpperCase()}`;\n if (k.meta && k.input) return `Alt+${k.input}`;\n return k.input || \"?\";\n}\n\nfunction modPrefix(k: Keystroke): string {\n let p = \"\";\n if (k.ctrl) p += \"Ctrl+\";\n if (k.meta) p += \"Alt+\";\n if (k.shift) p += \"Shift+\";\n return p;\n}\n\nfunction Demo({ onExit }: { onExit: () => void }) {\n const [count, setCount] = useState(0);\n const [last, setLast] = useState<string>(\"(none yet)\");\n\n useKeystroke((k) => {\n if (k.escape) {\n onExit();\n return;\n }\n setCount((n) => n + 1);\n setLast(describeKey(k));\n });\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={FAINT_BORDER} padding={1}>\n <Text style={[ACCENT]}>Reasonix cell-diff renderer · demo</Text>\n <Text style={[DIM]}>Press any key. ESC to exit.</Text>\n <Box paddingTop={1} flexDirection=\"row\">\n <Text>{\"Count : \"}</Text>\n <Text>{String(count)}</Text>\n </Box>\n <Box flexDirection=\"row\">\n <Text>{\"Last : \"}</Text>\n <Text>{last}</Text>\n </Box>\n </Box>\n );\n}\n\nexport interface RendererDemoOptions {\n /** Optional override for stdout (used by tests). */\n stdout?: NodeJS.WriteStream;\n /** Optional override for stdin (used by tests). */\n stdin?: NodeJS.ReadStream;\n}\n\nexport async function runRendererDemo(opts: RendererDemoOptions = {}): Promise<void> {\n const stdout = opts.stdout ?? process.stdout;\n const stdin = opts.stdin ?? process.stdin;\n\n if (!stdin.isTTY || !stdout.isTTY) {\n console.error(\"renderer-demo requires an interactive TTY.\");\n process.exit(1);\n }\n\n const pools = {\n char: new CharPool(),\n style: new StylePool(),\n hyperlink: new HyperlinkPool(),\n };\n\n let resolveExit: () => void = () => {};\n const exited = new Promise<void>((resolve) => {\n resolveExit = resolve;\n });\n\n const handle = mount(<Demo onExit={() => resolveExit()} />, {\n viewportWidth: stdout.columns ?? 80,\n viewportHeight: stdout.rows ?? 24,\n pools,\n write: (bytes) => stdout.write(bytes),\n stdin,\n });\n\n const onResize = () => {\n handle.resize(stdout.columns ?? 80, stdout.rows ?? 24);\n };\n stdout.on(\"resize\", onResize);\n\n try {\n await exited;\n } finally {\n stdout.off(\"resize\", onResize);\n handle.destroy();\n stdin.pause();\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
CharPool,
|
|
4
|
+
HyperlinkPool,
|
|
5
|
+
StylePool,
|
|
6
|
+
ink_compat_exports,
|
|
7
|
+
mount,
|
|
8
|
+
useKeystroke
|
|
9
|
+
} from "./chunk-JHXQDL7B.js";
|
|
10
|
+
import "./chunk-2H7UOFLK.js";
|
|
11
|
+
|
|
12
|
+
// src/cli/commands/select-demo.tsx
|
|
13
|
+
import React, { useState } from "react";
|
|
14
|
+
var ITEMS = [
|
|
15
|
+
{ value: "deepseek-v3", label: "DeepSeek V3", hint: "default \xB7 cheap \xB7 fast" },
|
|
16
|
+
{ value: "deepseek-r1", label: "DeepSeek R1", hint: "reasoning model" },
|
|
17
|
+
{ value: "deepseek-coder", label: "DeepSeek Coder", hint: "code-focused", disabled: true },
|
|
18
|
+
{ value: "kimi-k2", label: "Kimi K2", hint: "alternate provider" }
|
|
19
|
+
];
|
|
20
|
+
function findEnabled(items, from, step) {
|
|
21
|
+
if (items.length === 0) return 0;
|
|
22
|
+
let i = from;
|
|
23
|
+
for (let tries = 0; tries < items.length; tries++) {
|
|
24
|
+
i = (i + step + items.length) % items.length;
|
|
25
|
+
if (!items[i]?.disabled) return i;
|
|
26
|
+
}
|
|
27
|
+
return from;
|
|
28
|
+
}
|
|
29
|
+
function SelectRow({ item, active, marker }) {
|
|
30
|
+
const color = item.disabled ? "gray" : active ? "cyan" : void 0;
|
|
31
|
+
return /* @__PURE__ */ React.createElement(ink_compat_exports.Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(ink_compat_exports.Text, { color, bold: active, dimColor: item.disabled }, `${marker} ${item.label}`), item.hint ? /* @__PURE__ */ React.createElement(ink_compat_exports.Box, { paddingLeft: marker.length + 1 }, /* @__PURE__ */ React.createElement(ink_compat_exports.Text, { dimColor: true }, item.hint)) : null);
|
|
32
|
+
}
|
|
33
|
+
function SingleSelect({ onSubmit, onCancel }) {
|
|
34
|
+
const [index, setIndex] = useState(
|
|
35
|
+
() => Math.max(
|
|
36
|
+
0,
|
|
37
|
+
ITEMS.findIndex((i) => !i.disabled)
|
|
38
|
+
)
|
|
39
|
+
);
|
|
40
|
+
useKeystroke((k) => {
|
|
41
|
+
if (k.upArrow) setIndex((i) => findEnabled(ITEMS, i, -1));
|
|
42
|
+
else if (k.downArrow) setIndex((i) => findEnabled(ITEMS, i, 1));
|
|
43
|
+
else if (k.return) {
|
|
44
|
+
const item = ITEMS[index];
|
|
45
|
+
if (item && !item.disabled) onSubmit(item.value);
|
|
46
|
+
} else if (k.escape) onCancel();
|
|
47
|
+
});
|
|
48
|
+
return /* @__PURE__ */ React.createElement(ink_compat_exports.Box, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React.createElement(ink_compat_exports.Text, { color: "cyan", bold: true }, "Pick a model"), /* @__PURE__ */ React.createElement(ink_compat_exports.Box, { flexDirection: "column", marginTop: 1 }, ITEMS.map((item, i) => /* @__PURE__ */ React.createElement(
|
|
49
|
+
SelectRow,
|
|
50
|
+
{
|
|
51
|
+
key: item.value,
|
|
52
|
+
item,
|
|
53
|
+
active: i === index,
|
|
54
|
+
marker: i === index ? "\u25B8" : " "
|
|
55
|
+
}
|
|
56
|
+
))), /* @__PURE__ */ React.createElement(ink_compat_exports.Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(ink_compat_exports.Text, { dimColor: true }, "\u2191/\u2193 navigate \xB7 Enter confirm \xB7 Esc cancel")));
|
|
57
|
+
}
|
|
58
|
+
async function runSelectDemo(opts = {}) {
|
|
59
|
+
const stdout = opts.stdout ?? process.stdout;
|
|
60
|
+
const stdin = opts.stdin ?? process.stdin;
|
|
61
|
+
if (!stdin.isTTY || !stdout.isTTY) {
|
|
62
|
+
console.error("select-demo requires an interactive TTY.");
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
const pools = {
|
|
66
|
+
char: new CharPool(),
|
|
67
|
+
style: new StylePool(),
|
|
68
|
+
hyperlink: new HyperlinkPool()
|
|
69
|
+
};
|
|
70
|
+
let resolveExit = () => {
|
|
71
|
+
};
|
|
72
|
+
const exited = new Promise((resolve) => {
|
|
73
|
+
resolveExit = resolve;
|
|
74
|
+
});
|
|
75
|
+
const handle = mount(
|
|
76
|
+
/* @__PURE__ */ React.createElement(
|
|
77
|
+
SingleSelect,
|
|
78
|
+
{
|
|
79
|
+
onSubmit: (v) => resolveExit(`picked: ${v}`),
|
|
80
|
+
onCancel: () => resolveExit("(cancelled)")
|
|
81
|
+
}
|
|
82
|
+
),
|
|
83
|
+
{
|
|
84
|
+
viewportWidth: stdout.columns ?? 80,
|
|
85
|
+
viewportHeight: stdout.rows ?? 24,
|
|
86
|
+
pools,
|
|
87
|
+
write: (bytes) => stdout.write(bytes),
|
|
88
|
+
stdin
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
const onResize = () => handle.resize(stdout.columns ?? 80, stdout.rows ?? 24);
|
|
92
|
+
stdout.on("resize", onResize);
|
|
93
|
+
let result = "";
|
|
94
|
+
try {
|
|
95
|
+
result = await exited;
|
|
96
|
+
} finally {
|
|
97
|
+
stdout.off("resize", onResize);
|
|
98
|
+
handle.destroy();
|
|
99
|
+
stdin.pause();
|
|
100
|
+
}
|
|
101
|
+
stdout.write(`${result}
|
|
102
|
+
`);
|
|
103
|
+
}
|
|
104
|
+
export {
|
|
105
|
+
runSelectDemo
|
|
106
|
+
};
|
|
107
|
+
//# sourceMappingURL=select-demo-OA5N34BJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/select-demo.tsx"],"sourcesContent":["// biome-ignore lint/style/useImportType: tsconfig jsx=react needs React in value scope for JSX compilation\nimport React, { useState } from \"react\";\nimport {\n CharPool,\n type Handle,\n HyperlinkPool,\n StylePool,\n inkCompat,\n mount,\n useKeystroke,\n} from \"../../renderer/index.js\";\n\ninterface Item {\n readonly value: string;\n readonly label: string;\n readonly hint?: string;\n readonly disabled?: boolean;\n}\n\nconst ITEMS: ReadonlyArray<Item> = [\n { value: \"deepseek-v3\", label: \"DeepSeek V3\", hint: \"default · cheap · fast\" },\n { value: \"deepseek-r1\", label: \"DeepSeek R1\", hint: \"reasoning model\" },\n { value: \"deepseek-coder\", label: \"DeepSeek Coder\", hint: \"code-focused\", disabled: true },\n { value: \"kimi-k2\", label: \"Kimi K2\", hint: \"alternate provider\" },\n];\n\nfunction findEnabled(items: ReadonlyArray<Item>, from: number, step: -1 | 1): number {\n if (items.length === 0) return 0;\n let i = from;\n for (let tries = 0; tries < items.length; tries++) {\n i = (i + step + items.length) % items.length;\n if (!items[i]?.disabled) return i;\n }\n return from;\n}\n\nfunction SelectRow({ item, active, marker }: { item: Item; active: boolean; marker: string }) {\n const color = item.disabled ? \"gray\" : active ? \"cyan\" : undefined;\n return (\n <inkCompat.Box flexDirection=\"column\">\n <inkCompat.Text color={color} bold={active} dimColor={item.disabled}>\n {`${marker} ${item.label}`}\n </inkCompat.Text>\n {item.hint ? (\n <inkCompat.Box paddingLeft={marker.length + 1}>\n <inkCompat.Text dimColor>{item.hint}</inkCompat.Text>\n </inkCompat.Box>\n ) : null}\n </inkCompat.Box>\n );\n}\n\ninterface SelectProps {\n onSubmit: (value: string) => void;\n onCancel: () => void;\n}\n\nfunction SingleSelect({ onSubmit, onCancel }: SelectProps): React.ReactElement {\n const [index, setIndex] = useState(() =>\n Math.max(\n 0,\n ITEMS.findIndex((i) => !i.disabled),\n ),\n );\n\n useKeystroke((k) => {\n if (k.upArrow) setIndex((i) => findEnabled(ITEMS, i, -1));\n else if (k.downArrow) setIndex((i) => findEnabled(ITEMS, i, +1));\n else if (k.return) {\n const item = ITEMS[index];\n if (item && !item.disabled) onSubmit(item.value);\n } else if (k.escape) onCancel();\n });\n\n return (\n <inkCompat.Box flexDirection=\"column\" marginY={1}>\n <inkCompat.Text color=\"cyan\" bold>\n Pick a model\n </inkCompat.Text>\n <inkCompat.Box flexDirection=\"column\" marginTop={1}>\n {ITEMS.map((item, i) => (\n <SelectRow\n key={item.value}\n item={item}\n active={i === index}\n marker={i === index ? \"▸\" : \" \"}\n />\n ))}\n </inkCompat.Box>\n <inkCompat.Box marginTop={1}>\n <inkCompat.Text dimColor>↑/↓ navigate · Enter confirm · Esc cancel</inkCompat.Text>\n </inkCompat.Box>\n </inkCompat.Box>\n );\n}\n\nexport interface SelectDemoOptions {\n readonly stdout?: NodeJS.WriteStream;\n readonly stdin?: NodeJS.ReadStream;\n}\n\nexport async function runSelectDemo(opts: SelectDemoOptions = {}): Promise<void> {\n const stdout = opts.stdout ?? process.stdout;\n const stdin = opts.stdin ?? process.stdin;\n\n if (!stdin.isTTY || !stdout.isTTY) {\n console.error(\"select-demo requires an interactive TTY.\");\n process.exit(1);\n }\n\n const pools = {\n char: new CharPool(),\n style: new StylePool(),\n hyperlink: new HyperlinkPool(),\n };\n\n let resolveExit: (msg: string) => void = () => {};\n const exited = new Promise<string>((resolve) => {\n resolveExit = resolve;\n });\n\n const handle: Handle = mount(\n <SingleSelect\n onSubmit={(v) => resolveExit(`picked: ${v}`)}\n onCancel={() => resolveExit(\"(cancelled)\")}\n />,\n {\n viewportWidth: stdout.columns ?? 80,\n viewportHeight: stdout.rows ?? 24,\n pools,\n write: (bytes) => stdout.write(bytes),\n stdin,\n },\n );\n\n const onResize = () => handle.resize(stdout.columns ?? 80, stdout.rows ?? 24);\n stdout.on(\"resize\", onResize);\n\n let result = \"\";\n try {\n result = await exited;\n } finally {\n stdout.off(\"resize\", onResize);\n handle.destroy();\n stdin.pause();\n }\n stdout.write(`${result}\\n`);\n}\n"],"mappings":"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","names":[]}
|