@robinpath/cli 1.78.0 → 1.80.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/dist/cli.mjs +228 -80
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -18598,7 +18598,7 @@ function getNativeModules() {
|
|
|
18598
18598
|
import { join as join3, basename as basename2 } from "node:path";
|
|
18599
18599
|
import { homedir as homedir2, platform as platform2 } from "node:os";
|
|
18600
18600
|
import { existsSync as existsSync2 } from "node:fs";
|
|
18601
|
-
var CLI_VERSION = true ? "1.
|
|
18601
|
+
var CLI_VERSION = true ? "1.80.0" : "1.80.0";
|
|
18602
18602
|
var FLAG_QUIET = false;
|
|
18603
18603
|
var FLAG_VERBOSE = false;
|
|
18604
18604
|
var FLAG_AUTO_ACCEPT = false;
|
|
@@ -21904,7 +21904,8 @@ async function fetchBrainStream(prompt, { onToken, conversationHistory, provider
|
|
|
21904
21904
|
});
|
|
21905
21905
|
if (!response.ok) {
|
|
21906
21906
|
logVerbose("Brain stream returned", response.status);
|
|
21907
|
-
|
|
21907
|
+
const errorHint = response.status === 401 ? "Invalid API key." : response.status === 429 ? "Rate limited. Wait a moment and try again." : response.status >= 500 ? "Brain server error. Try again." : `Brain returned HTTP ${response.status}.`;
|
|
21908
|
+
return { code: "", sources: [], context: {}, validation: null, usage: null, error: errorHint };
|
|
21908
21909
|
}
|
|
21909
21910
|
let fullText = "";
|
|
21910
21911
|
let metadata = null;
|
|
@@ -21964,8 +21965,19 @@ async function fetchBrainStream(prompt, { onToken, conversationHistory, provider
|
|
|
21964
21965
|
usage: doneData?.usage || null
|
|
21965
21966
|
};
|
|
21966
21967
|
} catch (err) {
|
|
21967
|
-
|
|
21968
|
-
|
|
21968
|
+
const msg = err.message || "";
|
|
21969
|
+
logVerbose("Brain stream unreachable:", msg);
|
|
21970
|
+
let errorHint;
|
|
21971
|
+
if (msg.includes("fetch failed") || msg.includes("ENOTFOUND") || msg.includes("ECONNREFUSED") || msg.includes("NetworkError") || msg.includes("getaddrinfo")) {
|
|
21972
|
+
errorHint = "No internet connection. Check your network and try again.";
|
|
21973
|
+
} else if (msg.includes("abort") || msg.includes("timeout") || msg.includes("TimeoutError")) {
|
|
21974
|
+
errorHint = "Request timed out. The server might be slow \u2014 try again.";
|
|
21975
|
+
} else if (msg.includes("CERT") || msg.includes("SSL") || msg.includes("certificate")) {
|
|
21976
|
+
errorHint = "SSL/certificate error. Check your network or proxy settings.";
|
|
21977
|
+
} else {
|
|
21978
|
+
errorHint = `Connection failed: ${msg.slice(0, 100)}`;
|
|
21979
|
+
}
|
|
21980
|
+
return { code: "", sources: [], context: {}, validation: null, usage: null, error: errorHint };
|
|
21969
21981
|
}
|
|
21970
21982
|
}
|
|
21971
21983
|
async function resolveBrainModules(prompt) {
|
|
@@ -23941,9 +23953,20 @@ ${readFileSync9(rpJson, "utf-8")}
|
|
|
23941
23953
|
if (pending.length > 0 && !insideMemory && !insideCmd) {
|
|
23942
23954
|
process.stdout.write(pending);
|
|
23943
23955
|
}
|
|
23944
|
-
if (!brainResult
|
|
23956
|
+
if (!brainResult) {
|
|
23957
|
+
spinner.stop();
|
|
23958
|
+
log(color.red("\n No internet connection. Check your network and try again."));
|
|
23959
|
+
break;
|
|
23960
|
+
}
|
|
23961
|
+
if (brainResult.error) {
|
|
23962
|
+
spinner.stop();
|
|
23963
|
+
log(color.red(`
|
|
23964
|
+
${brainResult.error}`));
|
|
23965
|
+
break;
|
|
23966
|
+
}
|
|
23967
|
+
if (!brainResult.code) {
|
|
23945
23968
|
spinner.stop();
|
|
23946
|
-
log(color.red("\n
|
|
23969
|
+
log(color.red("\n No response from AI. Try again."));
|
|
23947
23970
|
break;
|
|
23948
23971
|
}
|
|
23949
23972
|
if (brainResult.usage) {
|
|
@@ -24132,72 +24155,145 @@ ${resultSummary}`
|
|
|
24132
24155
|
}
|
|
24133
24156
|
|
|
24134
24157
|
// src/ink-repl.tsx
|
|
24135
|
-
import { useState, useEffect } from "react";
|
|
24158
|
+
import { useState, useCallback, useEffect, useMemo } from "react";
|
|
24136
24159
|
import { render, Box, Text, Static, useInput, useApp } from "ink";
|
|
24137
24160
|
import InkSpinner from "ink-spinner";
|
|
24138
24161
|
import { platform as platform7 } from "node:os";
|
|
24139
24162
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
24140
24163
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
24141
24164
|
var nextId = 0;
|
|
24142
|
-
|
|
24143
|
-
|
|
24144
|
-
|
|
24145
|
-
|
|
24146
|
-
|
|
24165
|
+
var COMMANDS = {
|
|
24166
|
+
"/model": "Switch AI model",
|
|
24167
|
+
"/auto": "Toggle auto-accept",
|
|
24168
|
+
"/clear": "Clear conversation",
|
|
24169
|
+
"/save": "Save session",
|
|
24170
|
+
"/sessions": "List sessions",
|
|
24171
|
+
"/memory": "Show memory",
|
|
24172
|
+
"/remember": "Save a fact",
|
|
24173
|
+
"/usage": "Token usage & cost",
|
|
24174
|
+
"/shell": "Switch shell",
|
|
24175
|
+
"/help": "Show commands"
|
|
24176
|
+
};
|
|
24177
|
+
function InputArea({ onSubmit, placeholder }) {
|
|
24178
|
+
const [value, setValue] = useState("");
|
|
24179
|
+
const [showHints, setShowHints] = useState(false);
|
|
24147
24180
|
const { exit } = useApp();
|
|
24148
|
-
|
|
24149
|
-
|
|
24150
|
-
|
|
24151
|
-
|
|
24152
|
-
|
|
24153
|
-
|
|
24154
|
-
}, []);
|
|
24155
|
-
useInput((character, key) => {
|
|
24156
|
-
if (loading) return;
|
|
24181
|
+
const matchingCommands = useMemo(() => {
|
|
24182
|
+
if (!value.startsWith("/")) return [];
|
|
24183
|
+
if (value === "/") return Object.entries(COMMANDS);
|
|
24184
|
+
return Object.entries(COMMANDS).filter(([cmd]) => cmd.startsWith(value));
|
|
24185
|
+
}, [value]);
|
|
24186
|
+
useInput((ch, key) => {
|
|
24157
24187
|
if (key.return) {
|
|
24158
|
-
if (
|
|
24159
|
-
|
|
24160
|
-
setInput((prev) => prev.slice(0, -1) + "\n");
|
|
24188
|
+
if (value.endsWith("\\")) {
|
|
24189
|
+
setValue((p) => p.slice(0, -1) + "\n");
|
|
24161
24190
|
return;
|
|
24162
24191
|
}
|
|
24163
|
-
const text =
|
|
24164
|
-
|
|
24165
|
-
|
|
24166
|
-
|
|
24167
|
-
|
|
24192
|
+
const text = value.trim();
|
|
24193
|
+
if (text) {
|
|
24194
|
+
onSubmit(text);
|
|
24195
|
+
setValue("");
|
|
24196
|
+
setShowHints(false);
|
|
24168
24197
|
}
|
|
24169
|
-
setMessages((prev) => [...prev, { id: ++nextId, text: `\u276F ${text}` }]);
|
|
24170
|
-
setLoading(true);
|
|
24171
|
-
setStreaming("");
|
|
24172
|
-
onMessage(text).then((response) => {
|
|
24173
|
-
if (response) {
|
|
24174
|
-
setMessages((prev) => [...prev, { id: ++nextId, text: response }]);
|
|
24175
|
-
}
|
|
24176
|
-
setLoading(false);
|
|
24177
|
-
setStreaming("");
|
|
24178
|
-
}).catch((err) => {
|
|
24179
|
-
setMessages((prev) => [...prev, { id: ++nextId, text: `Error: ${err.message}` }]);
|
|
24180
|
-
setLoading(false);
|
|
24181
|
-
setStreaming("");
|
|
24182
|
-
});
|
|
24183
24198
|
return;
|
|
24184
24199
|
}
|
|
24185
|
-
if (
|
|
24186
|
-
|
|
24200
|
+
if (ch === "\n") {
|
|
24201
|
+
setValue((p) => p + "\n");
|
|
24187
24202
|
return;
|
|
24188
24203
|
}
|
|
24189
24204
|
if (key.escape) {
|
|
24190
|
-
|
|
24205
|
+
setValue("");
|
|
24206
|
+
setShowHints(false);
|
|
24191
24207
|
return;
|
|
24192
24208
|
}
|
|
24193
|
-
if (
|
|
24194
|
-
|
|
24195
|
-
|
|
24209
|
+
if (ch === "") {
|
|
24210
|
+
if (!value) exit();
|
|
24211
|
+
else {
|
|
24212
|
+
setValue("");
|
|
24213
|
+
setShowHints(false);
|
|
24214
|
+
}
|
|
24215
|
+
return;
|
|
24216
|
+
}
|
|
24217
|
+
if (key.backspace || key.delete) {
|
|
24218
|
+
setValue((p) => p.slice(0, -1));
|
|
24219
|
+
return;
|
|
24196
24220
|
}
|
|
24221
|
+
if (key.tab) {
|
|
24222
|
+
if (matchingCommands.length === 1) {
|
|
24223
|
+
setValue(matchingCommands[0][0] + " ");
|
|
24224
|
+
setShowHints(false);
|
|
24225
|
+
}
|
|
24226
|
+
return;
|
|
24227
|
+
}
|
|
24228
|
+
if (ch === "") {
|
|
24229
|
+
setValue("");
|
|
24230
|
+
return;
|
|
24231
|
+
}
|
|
24232
|
+
if (ch === "") {
|
|
24233
|
+
setValue((p) => p.replace(/\S+\s*$/, ""));
|
|
24234
|
+
return;
|
|
24235
|
+
}
|
|
24236
|
+
if (ch && !key.ctrl && !key.meta) setValue((p) => p + ch);
|
|
24197
24237
|
});
|
|
24198
|
-
|
|
24238
|
+
useEffect(() => {
|
|
24239
|
+
setShowHints(value.startsWith("/") && matchingCommands.length > 0);
|
|
24240
|
+
}, [value, matchingCommands.length]);
|
|
24241
|
+
const lines = value.split("\n");
|
|
24242
|
+
const empty = value === "";
|
|
24243
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
24244
|
+
showHints && /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginX: 2, marginBottom: 1, children: matchingCommands.slice(0, 6).map(([cmd, desc]) => /* @__PURE__ */ jsxs(Text, { children: [
|
|
24245
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: cmd.padEnd(12) }),
|
|
24246
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: desc })
|
|
24247
|
+
] }, cmd)) }),
|
|
24248
|
+
/* @__PURE__ */ jsx(Box, { borderStyle: "round", borderColor: "cyan", flexDirection: "column", paddingX: 1, marginX: 1, children: empty ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: placeholder }) : lines.map((line, i) => /* @__PURE__ */ jsxs(Text, { children: [
|
|
24249
|
+
line,
|
|
24250
|
+
i === lines.length - 1 ? /* @__PURE__ */ jsx(Text, { color: "cyan", children: "\u2588" }) : null
|
|
24251
|
+
] }, i)) }),
|
|
24252
|
+
/* @__PURE__ */ jsx(Box, { marginX: 2, children: /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
24253
|
+
/* @__PURE__ */ jsx(Text, { color: "gray", children: "enter" }),
|
|
24254
|
+
" send ",
|
|
24255
|
+
/* @__PURE__ */ jsx(Text, { color: "gray", children: "\\" }),
|
|
24256
|
+
" newline ",
|
|
24257
|
+
/* @__PURE__ */ jsx(Text, { color: "gray", children: "esc" }),
|
|
24258
|
+
" clear ",
|
|
24259
|
+
/* @__PURE__ */ jsx(Text, { color: "gray", children: "/" }),
|
|
24260
|
+
" commands ",
|
|
24261
|
+
/* @__PURE__ */ jsx(Text, { color: "gray", children: "tab" }),
|
|
24262
|
+
" complete"
|
|
24263
|
+
] }) })
|
|
24264
|
+
] });
|
|
24265
|
+
}
|
|
24266
|
+
function ChatApp({ onMessage, statusText }) {
|
|
24267
|
+
const [messages, setMessages] = useState([]);
|
|
24268
|
+
const [streaming, setStreaming] = useState("");
|
|
24269
|
+
const [loading, setLoading] = useState(false);
|
|
24270
|
+
useEffect(() => {
|
|
24271
|
+
global.__rpUI = {
|
|
24272
|
+
setStreaming,
|
|
24273
|
+
setLoading,
|
|
24274
|
+
addMessage: (text, dim) => setMessages((p) => [...p, { id: ++nextId, text, dim }])
|
|
24275
|
+
};
|
|
24276
|
+
}, []);
|
|
24277
|
+
const handleSubmit = useCallback(async (text) => {
|
|
24278
|
+
if (text === "exit" || text === "quit") {
|
|
24279
|
+
global.__rpExit?.();
|
|
24280
|
+
return;
|
|
24281
|
+
}
|
|
24282
|
+
setMessages((p) => [...p, { id: ++nextId, text: `\u276F ${text}` }]);
|
|
24283
|
+
setLoading(true);
|
|
24284
|
+
setStreaming("");
|
|
24285
|
+
try {
|
|
24286
|
+
const response = await onMessage(text);
|
|
24287
|
+
if (response) setMessages((p) => [...p, { id: ++nextId, text: response }]);
|
|
24288
|
+
} catch (err) {
|
|
24289
|
+
setMessages((p) => [...p, { id: ++nextId, text: `Error: ${err.message}`, dim: true }]);
|
|
24290
|
+
}
|
|
24291
|
+
setLoading(false);
|
|
24292
|
+
setStreaming("");
|
|
24293
|
+
}, [onMessage]);
|
|
24294
|
+
const isFirst = messages.length === 0;
|
|
24199
24295
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", padding: 1, children: [
|
|
24200
|
-
/* @__PURE__ */ jsxs(Text, { children: [
|
|
24296
|
+
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
24201
24297
|
/* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: "\u25C6" }),
|
|
24202
24298
|
" ",
|
|
24203
24299
|
/* @__PURE__ */ jsx(Text, { bold: true, children: "RobinPath" }),
|
|
@@ -24206,21 +24302,22 @@ function ChatApp({ onMessage }) {
|
|
|
24206
24302
|
"v",
|
|
24207
24303
|
CLI_VERSION
|
|
24208
24304
|
] })
|
|
24209
|
-
] }),
|
|
24210
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true,
|
|
24211
|
-
/* @__PURE__ */ jsx(
|
|
24212
|
-
|
|
24213
|
-
|
|
24305
|
+
] }) }),
|
|
24306
|
+
/* @__PURE__ */ jsx(Static, { items: messages, children: (msg) => /* @__PURE__ */ jsx(Box, { paddingX: 1, marginBottom: msg.text.startsWith("\u276F") ? 0 : 1, children: msg.dim ? /* @__PURE__ */ jsx(Text, { dimColor: true, wrap: "wrap", children: msg.text }) : /* @__PURE__ */ jsx(Text, { wrap: "wrap", children: msg.text }) }, msg.id) }),
|
|
24307
|
+
loading ? /* @__PURE__ */ jsx(Box, { flexDirection: "column", paddingX: 1, children: streaming ? /* @__PURE__ */ jsxs(Text, { wrap: "wrap", children: [
|
|
24308
|
+
streaming,
|
|
24309
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: "\u258D" })
|
|
24310
|
+
] }) : /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
24214
24311
|
/* @__PURE__ */ jsx(InkSpinner, { type: "dots" }),
|
|
24215
24312
|
" Thinking"
|
|
24216
|
-
] }) :
|
|
24217
|
-
|
|
24218
|
-
|
|
24219
|
-
|
|
24220
|
-
|
|
24221
|
-
|
|
24222
|
-
|
|
24223
|
-
|
|
24313
|
+
] }) }) : /* @__PURE__ */ jsx(
|
|
24314
|
+
InputArea,
|
|
24315
|
+
{
|
|
24316
|
+
onSubmit: handleSubmit,
|
|
24317
|
+
placeholder: isFirst ? "Anything to automate with RobinPath?" : "Ask anything..."
|
|
24318
|
+
}
|
|
24319
|
+
),
|
|
24320
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, paddingX: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: statusText }) })
|
|
24224
24321
|
] });
|
|
24225
24322
|
}
|
|
24226
24323
|
async function startInkREPL(initialPrompt, resumeSessionId, opts = {}) {
|
|
@@ -24237,6 +24334,7 @@ async function startInkREPL(initialPrompt, resumeSessionId, opts = {}) {
|
|
|
24237
24334
|
};
|
|
24238
24335
|
const apiKey = config.apiKey || null;
|
|
24239
24336
|
const model = apiKey ? config.model || "anthropic/claude-sonnet-4.6" : "robinpath-default";
|
|
24337
|
+
const modelShort = (m) => m === "robinpath-default" ? "gemini-free" : m.includes("/") ? m.split("/").pop() : m;
|
|
24240
24338
|
const cliContext = {
|
|
24241
24339
|
platform: platform7(),
|
|
24242
24340
|
shell: getShellConfig().name,
|
|
@@ -24262,15 +24360,23 @@ async function startInkREPL(initialPrompt, resumeSessionId, opts = {}) {
|
|
|
24262
24360
|
if (session.usage) Object.assign(usage, session.usage);
|
|
24263
24361
|
}
|
|
24264
24362
|
}
|
|
24363
|
+
function getStatusText() {
|
|
24364
|
+
const m = modelShort(readAiConfig().model || model);
|
|
24365
|
+
const cost = usage.cost > 0 ? ` \xB7 $${usage.cost.toFixed(4)}` : "";
|
|
24366
|
+
const tokens = usage.totalTokens > 0 ? ` \xB7 ${usage.totalTokens.toLocaleString()} tok` : "";
|
|
24367
|
+
return `${m} \xB7 ${getShellConfig().name} \xB7 ${autoAccept ? "auto" : "confirm"}${tokens}${cost}`;
|
|
24368
|
+
}
|
|
24265
24369
|
async function handleMessage(text) {
|
|
24266
24370
|
const ui = global.__rpUI;
|
|
24267
|
-
if (text === "/" || text === "/help")
|
|
24371
|
+
if (text === "/" || text === "/help") {
|
|
24372
|
+
return Object.entries(COMMANDS).map(([cmd, desc]) => `${cmd.padEnd(12)} ${desc}`).join("\n");
|
|
24373
|
+
}
|
|
24268
24374
|
if (text === "/clear") {
|
|
24269
24375
|
conversationMessages.length = 0;
|
|
24270
|
-
return "
|
|
24376
|
+
return "Conversation cleared.";
|
|
24271
24377
|
}
|
|
24272
24378
|
if (text === "/usage") {
|
|
24273
|
-
const c = usage.cost > 0 ? `$${usage.cost.toFixed(4)}` : "$0 (free)";
|
|
24379
|
+
const c = usage.cost > 0 ? `$${usage.cost.toFixed(4)}` : "$0.00 (free)";
|
|
24274
24380
|
return `${usage.totalTokens.toLocaleString()} tokens \xB7 ${usage.requests} requests \xB7 ${c}`;
|
|
24275
24381
|
}
|
|
24276
24382
|
if (text === "/auto") {
|
|
@@ -24280,7 +24386,11 @@ async function startInkREPL(initialPrompt, resumeSessionId, opts = {}) {
|
|
|
24280
24386
|
if (text === "/model") {
|
|
24281
24387
|
const hasKey = !!readAiConfig().apiKey;
|
|
24282
24388
|
const models = hasKey ? AI_MODELS : AI_MODELS.filter((m) => !m.requiresKey);
|
|
24283
|
-
|
|
24389
|
+
const cur = readAiConfig().model || model;
|
|
24390
|
+
return models.map((m, i) => {
|
|
24391
|
+
const mark = m.id === cur ? " \u2713" : "";
|
|
24392
|
+
return `${String(i + 1).padStart(2)}. ${m.name.padEnd(22)} ${m.desc}${mark}`;
|
|
24393
|
+
}).join("\n") + "\n\nType /model <number> to switch.";
|
|
24284
24394
|
}
|
|
24285
24395
|
if (text.match(/^\/model \d+$/)) {
|
|
24286
24396
|
const hasKey = !!readAiConfig().apiKey;
|
|
@@ -24289,20 +24399,44 @@ async function startInkREPL(initialPrompt, resumeSessionId, opts = {}) {
|
|
|
24289
24399
|
if (idx >= 0 && idx < models.length) {
|
|
24290
24400
|
config.model = models[idx].id;
|
|
24291
24401
|
writeAiConfig(config);
|
|
24292
|
-
return `Model
|
|
24402
|
+
return `Model changed to ${models[idx].name}`;
|
|
24293
24403
|
}
|
|
24294
24404
|
return "Invalid number.";
|
|
24295
24405
|
}
|
|
24296
24406
|
if (text === "/memory") {
|
|
24297
24407
|
const m = loadMemory();
|
|
24298
|
-
return m.facts.length ? m.facts.map((f, i) => `${i + 1}. ${f}`).join("\n") : "No memories.";
|
|
24408
|
+
return m.facts.length ? m.facts.map((f, i) => `${i + 1}. ${f}`).join("\n") : "No memories saved.";
|
|
24409
|
+
}
|
|
24410
|
+
if (text.startsWith("/remember ")) {
|
|
24411
|
+
addMemoryFact(text.slice(10).trim());
|
|
24412
|
+
return "Remembered.";
|
|
24299
24413
|
}
|
|
24300
|
-
if (text.startsWith("/
|
|
24414
|
+
if (text.startsWith("/forget ")) {
|
|
24415
|
+
removeMemoryFact(parseInt(text.slice(8).trim(), 10) - 1);
|
|
24416
|
+
return "Forgotten.";
|
|
24417
|
+
}
|
|
24418
|
+
if (text === "/save" || text.startsWith("/save ")) {
|
|
24301
24419
|
if (text.length > 5) sessionName = text.slice(5).trim();
|
|
24302
24420
|
saveSession(sessionId, sessionName, conversationMessages, usage);
|
|
24303
|
-
return `
|
|
24421
|
+
return `Session saved: ${sessionName}`;
|
|
24422
|
+
}
|
|
24423
|
+
if (text === "/sessions") {
|
|
24424
|
+
const sessions = listSessions();
|
|
24425
|
+
if (sessions.length === 0) return "No saved sessions.";
|
|
24426
|
+
return sessions.map((s) => `${s.id} ${s.name} (${s.messages} msgs)`).join("\n");
|
|
24427
|
+
}
|
|
24428
|
+
if (text === "/shell") {
|
|
24429
|
+
return getAvailableShells().map((s) => {
|
|
24430
|
+
const mark = s.current ? " \u2713" : s.available ? "" : " (not found)";
|
|
24431
|
+
return `${s.name}${mark}`;
|
|
24432
|
+
}).join("\n") + "\n\nType /shell <name> to switch.";
|
|
24304
24433
|
}
|
|
24305
|
-
if (text.startsWith("/"))
|
|
24434
|
+
if (text.startsWith("/shell ")) {
|
|
24435
|
+
setShellOverride(text.slice(7).trim());
|
|
24436
|
+
cliContext.shell = getShellConfig().name;
|
|
24437
|
+
return `Shell: ${getShellConfig().name}`;
|
|
24438
|
+
}
|
|
24439
|
+
if (text.startsWith("/")) return `Unknown command: ${text}. Type / for help.`;
|
|
24306
24440
|
const { expanded } = expandFileRefs(text);
|
|
24307
24441
|
conversationMessages.push({ role: "user", content: expanded });
|
|
24308
24442
|
await autoCompact(conversationMessages);
|
|
@@ -24332,8 +24466,16 @@ async function startInkREPL(initialPrompt, resumeSessionId, opts = {}) {
|
|
|
24332
24466
|
cliContext
|
|
24333
24467
|
}
|
|
24334
24468
|
);
|
|
24335
|
-
if (!result
|
|
24336
|
-
finalResponse =
|
|
24469
|
+
if (!result) {
|
|
24470
|
+
finalResponse = "No internet connection. Check your network and try again.";
|
|
24471
|
+
break;
|
|
24472
|
+
}
|
|
24473
|
+
if (result.error) {
|
|
24474
|
+
finalResponse = result.error;
|
|
24475
|
+
break;
|
|
24476
|
+
}
|
|
24477
|
+
if (!result.code) {
|
|
24478
|
+
finalResponse = fullText || "No response. Try again.";
|
|
24337
24479
|
break;
|
|
24338
24480
|
}
|
|
24339
24481
|
if (result.usage) {
|
|
@@ -24355,15 +24497,15 @@ async function startInkREPL(initialPrompt, resumeSessionId, opts = {}) {
|
|
|
24355
24497
|
if (cleaned) ui?.addMessage(cleaned);
|
|
24356
24498
|
for (const cmd of commands) {
|
|
24357
24499
|
const preview = cmd.split("\n")[0].slice(0, 80);
|
|
24358
|
-
ui?.addMessage(`$ ${preview}${cmd.includes("\n") ? " ..." : ""}
|
|
24500
|
+
ui?.addMessage(`$ ${preview}${cmd.includes("\n") ? " ..." : ""}`, true);
|
|
24359
24501
|
const r = await executeShellCommand(cmd);
|
|
24360
24502
|
if (r.exitCode === 0 && r.stdout?.trim()) {
|
|
24361
|
-
ui?.addMessage(r.stdout.trim().split("\n").slice(0, 5).join("\n"));
|
|
24503
|
+
ui?.addMessage(r.stdout.trim().split("\n").slice(0, 5).join("\n"), true);
|
|
24362
24504
|
} else if (r.exitCode !== 0) {
|
|
24363
|
-
ui?.addMessage(`exit ${r.exitCode}: ${(r.stderr || "").slice(0, 100)}
|
|
24505
|
+
ui?.addMessage(`exit ${r.exitCode}: ${(r.stderr || "").slice(0, 100)}`, true);
|
|
24364
24506
|
}
|
|
24365
24507
|
}
|
|
24366
|
-
const summary = commands.map((cmd
|
|
24508
|
+
const summary = commands.map((cmd) => `$ ${cmd}
|
|
24367
24509
|
(executed)`).join("\n");
|
|
24368
24510
|
conversationMessages.push({ role: "user", content: `[Results]
|
|
24369
24511
|
${summary}` });
|
|
@@ -24373,7 +24515,13 @@ ${summary}` });
|
|
|
24373
24515
|
saveSession(sessionId, sessionName, conversationMessages, usage);
|
|
24374
24516
|
return finalResponse;
|
|
24375
24517
|
}
|
|
24376
|
-
const { waitUntilExit } = render(
|
|
24518
|
+
const { waitUntilExit } = render(
|
|
24519
|
+
/* @__PURE__ */ jsx(ChatApp, { onMessage: handleMessage, statusText: getStatusText() })
|
|
24520
|
+
);
|
|
24521
|
+
global.__rpExit = () => {
|
|
24522
|
+
if (conversationMessages.length > 1) saveSession(sessionId, sessionName, conversationMessages, usage);
|
|
24523
|
+
process.exit(0);
|
|
24524
|
+
};
|
|
24377
24525
|
if (initialPrompt) {
|
|
24378
24526
|
await new Promise((r) => setTimeout(r, 200));
|
|
24379
24527
|
const ui = global.__rpUI;
|