@robinpath/cli 1.75.0 → 1.77.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/README.md +111 -111
- package/dist/cli.mjs +347 -458
- package/modules/_helpers.js +33 -33
- package/modules/assert.js +270 -270
- package/modules/buffer.js +245 -245
- package/modules/child.js +176 -176
- package/modules/crypto.js +352 -352
- package/modules/dns.js +146 -146
- package/modules/events.js +174 -174
- package/modules/file.js +361 -361
- package/modules/http.js +268 -268
- package/modules/index.js +76 -76
- package/modules/net.js +189 -189
- package/modules/os.js +219 -219
- package/modules/path.js +162 -162
- package/modules/process.js +214 -214
- package/modules/stream.js +322 -322
- package/modules/string_decoder.js +106 -106
- package/modules/timer.js +167 -167
- package/modules/tls.js +264 -264
- package/modules/tty.js +169 -169
- package/modules/url.js +189 -189
- package/modules/util.js +275 -275
- package/modules/zlib.js +126 -126
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -18561,7 +18561,7 @@ var init_modules = __esm({
|
|
|
18561
18561
|
});
|
|
18562
18562
|
|
|
18563
18563
|
// src/index.ts
|
|
18564
|
-
import { readFileSync as
|
|
18564
|
+
import { readFileSync as readFileSync14, existsSync as existsSync15 } from "node:fs";
|
|
18565
18565
|
import { resolve as resolve12, extname as extname5, basename as basename8 } from "node:path";
|
|
18566
18566
|
|
|
18567
18567
|
// src/runtime.ts
|
|
@@ -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.77.0" : "1.77.0";
|
|
18602
18602
|
var FLAG_QUIET = false;
|
|
18603
18603
|
var FLAG_VERBOSE = false;
|
|
18604
18604
|
var FLAG_AUTO_ACCEPT = false;
|
|
@@ -24132,17 +24132,17 @@ ${resultSummary}`
|
|
|
24132
24132
|
}
|
|
24133
24133
|
|
|
24134
24134
|
// src/ink-repl.tsx
|
|
24135
|
-
import { useState } from "react";
|
|
24136
|
-
import { render, Box, Text, useInput, useApp } from "ink";
|
|
24137
|
-
import
|
|
24135
|
+
import { useState, useCallback, useEffect } from "react";
|
|
24136
|
+
import { render, Box, Text, Static, useInput, useApp } from "ink";
|
|
24137
|
+
import InkSpinner from "ink-spinner";
|
|
24138
|
+
import { platform as platform7 } from "node:os";
|
|
24138
24139
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
24139
|
-
import { readdirSync as readdirSync6, statSync as statSync6 } from "node:fs";
|
|
24140
|
-
import { join as join12 } from "node:path";
|
|
24141
24140
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
24142
|
-
|
|
24141
|
+
var nextId = 0;
|
|
24142
|
+
function InputBox({ onSubmit, active, placeholder }) {
|
|
24143
24143
|
const [value, setValue] = useState("");
|
|
24144
|
-
const { exit } = useApp();
|
|
24145
24144
|
useInput((input, key) => {
|
|
24145
|
+
if (!active) return;
|
|
24146
24146
|
if (key.return) {
|
|
24147
24147
|
if (value.endsWith("\\")) {
|
|
24148
24148
|
setValue((p) => p.slice(0, -1) + "\n");
|
|
@@ -24150,8 +24150,8 @@ function InputPrompt({ placeholder, onSubmit, onExit }) {
|
|
|
24150
24150
|
}
|
|
24151
24151
|
const text = value.trim();
|
|
24152
24152
|
if (text) {
|
|
24153
|
-
exit();
|
|
24154
24153
|
onSubmit(text);
|
|
24154
|
+
setValue("");
|
|
24155
24155
|
}
|
|
24156
24156
|
return;
|
|
24157
24157
|
}
|
|
@@ -24163,13 +24163,6 @@ function InputPrompt({ placeholder, onSubmit, onExit }) {
|
|
|
24163
24163
|
setValue("");
|
|
24164
24164
|
return;
|
|
24165
24165
|
}
|
|
24166
|
-
if (input === "") {
|
|
24167
|
-
if (!value) {
|
|
24168
|
-
exit();
|
|
24169
|
-
onExit();
|
|
24170
|
-
} else setValue("");
|
|
24171
|
-
return;
|
|
24172
|
-
}
|
|
24173
24166
|
if (key.backspace || key.delete) {
|
|
24174
24167
|
setValue((p) => p.slice(0, -1));
|
|
24175
24168
|
return;
|
|
@@ -24184,361 +24177,272 @@ function InputPrompt({ placeholder, onSubmit, onExit }) {
|
|
|
24184
24177
|
return;
|
|
24185
24178
|
}
|
|
24186
24179
|
if (input && !key.ctrl && !key.meta) setValue((p) => p + input);
|
|
24187
|
-
});
|
|
24180
|
+
}, { isActive: active });
|
|
24188
24181
|
const lines = value.split("\n");
|
|
24189
24182
|
const empty = value === "";
|
|
24190
|
-
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
24191
|
-
/* @__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: [
|
|
24183
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
24184
|
+
/* @__PURE__ */ jsx(Box, { borderStyle: "round", borderColor: active ? "cyan" : "gray", flexDirection: "column", paddingX: 1, marginX: 1, children: empty ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: placeholder }) : lines.map((line, i) => /* @__PURE__ */ jsxs(Text, { children: [
|
|
24192
24185
|
line,
|
|
24193
|
-
i === lines.length - 1 ? /* @__PURE__ */ jsx(Text, { color: "cyan", children: "\u2588" }) : null
|
|
24186
|
+
i === lines.length - 1 && active ? /* @__PURE__ */ jsx(Text, { color: "cyan", children: "\u2588" }) : null
|
|
24194
24187
|
] }, i)) }),
|
|
24195
24188
|
/* @__PURE__ */ jsx(Box, { marginX: 2, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "enter send \xB7 \\ newline \xB7 esc clear \xB7 / commands" }) })
|
|
24196
24189
|
] });
|
|
24197
24190
|
}
|
|
24198
|
-
function
|
|
24199
|
-
|
|
24200
|
-
|
|
24201
|
-
|
|
24202
|
-
|
|
24203
|
-
|
|
24204
|
-
|
|
24205
|
-
|
|
24206
|
-
|
|
24207
|
-
|
|
24208
|
-
|
|
24209
|
-
|
|
24210
|
-
|
|
24211
|
-
|
|
24212
|
-
|
|
24213
|
-
|
|
24214
|
-
|
|
24215
|
-
|
|
24216
|
-
|
|
24217
|
-
|
|
24218
|
-
|
|
24219
|
-
|
|
24220
|
-
|
|
24221
|
-
|
|
24222
|
-
|
|
24223
|
-
|
|
24224
|
-
|
|
24225
|
-
|
|
24226
|
-
|
|
24227
|
-
|
|
24191
|
+
function App({ engine }) {
|
|
24192
|
+
const [messages, setMessages] = useState([]);
|
|
24193
|
+
const [streaming, setStreaming] = useState("");
|
|
24194
|
+
const [loading, setLoading] = useState(false);
|
|
24195
|
+
const [loadingLabel, setLoadingLabel] = useState("Thinking");
|
|
24196
|
+
const [status, setStatus] = useState("");
|
|
24197
|
+
const { exit } = useApp();
|
|
24198
|
+
useEffect(() => {
|
|
24199
|
+
engine.ui = {
|
|
24200
|
+
addMessage: (role, text) => setMessages((p) => [...p, { id: ++nextId, role, text }]),
|
|
24201
|
+
setStreaming,
|
|
24202
|
+
setLoading,
|
|
24203
|
+
setLoadingLabel,
|
|
24204
|
+
setStatus,
|
|
24205
|
+
exit
|
|
24206
|
+
};
|
|
24207
|
+
}, []);
|
|
24208
|
+
const handleSubmit = useCallback(async (text) => {
|
|
24209
|
+
if (text === "exit" || text === "quit") {
|
|
24210
|
+
engine.exit();
|
|
24211
|
+
return;
|
|
24212
|
+
}
|
|
24213
|
+
await engine.handleInput(text);
|
|
24214
|
+
}, [engine]);
|
|
24215
|
+
const isFirst = messages.length === 0;
|
|
24216
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
24217
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, marginBottom: 1, marginX: 1, children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
24218
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: "\u25C6" }),
|
|
24219
|
+
" ",
|
|
24220
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "RobinPath" }),
|
|
24221
|
+
" ",
|
|
24222
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
24223
|
+
"v",
|
|
24224
|
+
CLI_VERSION
|
|
24225
|
+
] })
|
|
24226
|
+
] }) }),
|
|
24227
|
+
/* @__PURE__ */ jsx(Static, { items: messages, children: (msg) => /* @__PURE__ */ jsx(Box, { marginX: 2, marginBottom: msg.role === "assistant" ? 1 : 0, children: msg.role === "user" ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
24228
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: "\u276F " }),
|
|
24229
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: msg.text })
|
|
24230
|
+
] }) : msg.role === "info" ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: msg.text }) : /* @__PURE__ */ jsx(Text, { wrap: "wrap", children: msg.text }) }, msg.id) }),
|
|
24231
|
+
loading && streaming ? /* @__PURE__ */ jsx(Box, { marginX: 2, marginBottom: 1, children: /* @__PURE__ */ jsxs(Text, { wrap: "wrap", children: [
|
|
24232
|
+
streaming,
|
|
24233
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: "\u258D" })
|
|
24234
|
+
] }) }) : null,
|
|
24235
|
+
loading && !streaming ? /* @__PURE__ */ jsx(Box, { marginX: 2, marginBottom: 1, children: /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
24236
|
+
/* @__PURE__ */ jsx(InkSpinner, { type: "dots" }),
|
|
24237
|
+
" ",
|
|
24238
|
+
loadingLabel
|
|
24239
|
+
] }) }) : null,
|
|
24240
|
+
/* @__PURE__ */ jsx(
|
|
24241
|
+
InputBox,
|
|
24242
|
+
{
|
|
24243
|
+
onSubmit: handleSubmit,
|
|
24244
|
+
active: !loading,
|
|
24245
|
+
placeholder: isFirst ? "What do you want to automate?" : "Ask anything..."
|
|
24228
24246
|
}
|
|
24229
|
-
|
|
24230
|
-
|
|
24231
|
-
}
|
|
24232
|
-
function printBanner(modelShort, modeStr, cwdShort, shellName) {
|
|
24233
|
-
log("");
|
|
24234
|
-
log(` ${color.cyan("\u25C6")} ${color.bold("RobinPath")} ${color.dim("v" + CLI_VERSION)}`);
|
|
24235
|
-
log(color.dim(` ${modelShort} \xB7 ${shellName} \xB7 ${modeStr}`));
|
|
24236
|
-
log("");
|
|
24247
|
+
),
|
|
24248
|
+
status ? /* @__PURE__ */ jsx(Box, { marginX: 2, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: status }) }) : null
|
|
24249
|
+
] });
|
|
24237
24250
|
}
|
|
24238
|
-
|
|
24239
|
-
|
|
24240
|
-
|
|
24241
|
-
|
|
24242
|
-
|
|
24243
|
-
|
|
24251
|
+
var ReplEngine = class {
|
|
24252
|
+
config;
|
|
24253
|
+
autoAccept;
|
|
24254
|
+
devMode;
|
|
24255
|
+
apiKey;
|
|
24256
|
+
model;
|
|
24257
|
+
provider;
|
|
24258
|
+
sessionId;
|
|
24259
|
+
sessionName;
|
|
24260
|
+
usage;
|
|
24261
|
+
conversationMessages;
|
|
24262
|
+
cliContext;
|
|
24263
|
+
ui = null;
|
|
24264
|
+
constructor(resumeSessionId, opts) {
|
|
24265
|
+
this.config = readAiConfig();
|
|
24266
|
+
this.autoAccept = opts.autoAccept || false;
|
|
24267
|
+
this.devMode = opts.devMode || false;
|
|
24268
|
+
if (this.devMode) setFlags({ verbose: true });
|
|
24269
|
+
this.apiKey = this.config.apiKey || null;
|
|
24270
|
+
this.provider = this.resolveProvider(this.apiKey);
|
|
24271
|
+
this.model = this.apiKey ? this.config.model || "anthropic/claude-sonnet-4.6" : "robinpath-default";
|
|
24272
|
+
this.sessionId = resumeSessionId || randomUUID4().slice(0, 8);
|
|
24273
|
+
this.sessionName = `session-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}`;
|
|
24274
|
+
this.usage = createUsageTracker();
|
|
24275
|
+
this.conversationMessages = [];
|
|
24276
|
+
this.cliContext = {
|
|
24277
|
+
platform: platform7(),
|
|
24278
|
+
shell: getShellConfig().name,
|
|
24279
|
+
cwd: process.cwd(),
|
|
24280
|
+
cliVersion: CLI_VERSION,
|
|
24281
|
+
nativeModules: getNativeModules().map((m) => m.name),
|
|
24282
|
+
installedModules: Object.keys(readModulesManifest())
|
|
24283
|
+
};
|
|
24284
|
+
const mem = buildMemoryContext();
|
|
24285
|
+
if (mem.trim()) {
|
|
24286
|
+
this.conversationMessages.push({ role: "user", content: `[Context] ${mem.trim()}` });
|
|
24287
|
+
this.conversationMessages.push({ role: "assistant", content: "Preferences loaded." });
|
|
24288
|
+
}
|
|
24289
|
+
if (resumeSessionId) {
|
|
24290
|
+
const session = loadSession(resumeSessionId);
|
|
24291
|
+
if (session) {
|
|
24292
|
+
this.sessionName = session.name;
|
|
24293
|
+
for (const msg of session.messages) this.conversationMessages.push(msg);
|
|
24294
|
+
if (session.usage) {
|
|
24295
|
+
this.usage.promptTokens = session.usage.promptTokens || 0;
|
|
24296
|
+
this.usage.completionTokens = session.usage.completionTokens || 0;
|
|
24297
|
+
this.usage.totalTokens = session.usage.totalTokens || 0;
|
|
24298
|
+
this.usage.requests = session.usage.requests || 0;
|
|
24299
|
+
}
|
|
24300
|
+
}
|
|
24301
|
+
}
|
|
24302
|
+
}
|
|
24303
|
+
resolveProvider(key) {
|
|
24244
24304
|
if (!key) return "gemini";
|
|
24245
24305
|
if (key.startsWith("sk-or-")) return "openrouter";
|
|
24246
24306
|
if (key.startsWith("sk-ant-")) return "anthropic";
|
|
24247
24307
|
if (key.startsWith("sk-")) return "openai";
|
|
24248
|
-
return config.provider || "gemini";
|
|
24249
|
-
};
|
|
24250
|
-
const apiKey = config.apiKey || null;
|
|
24251
|
-
const provider = resolveProvider(apiKey);
|
|
24252
|
-
const model = apiKey ? config.model || "anthropic/claude-sonnet-4.6" : "robinpath-default";
|
|
24253
|
-
const modelShort = model === "robinpath-default" ? "gemini-2.0-flash (free)" : model.includes("/") ? model.split("/").pop() : model;
|
|
24254
|
-
const cliContext = {
|
|
24255
|
-
platform: platform7(),
|
|
24256
|
-
shell: getShellConfig().name,
|
|
24257
|
-
cwd: process.cwd(),
|
|
24258
|
-
cliVersion: CLI_VERSION,
|
|
24259
|
-
nativeModules: getNativeModules().map((m) => m.name),
|
|
24260
|
-
installedModules: Object.keys(readModulesManifest())
|
|
24261
|
-
};
|
|
24262
|
-
let sessionId = resumeSessionId || randomUUID4().slice(0, 8);
|
|
24263
|
-
let sessionName = `session-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}`;
|
|
24264
|
-
const usage = createUsageTracker();
|
|
24265
|
-
const conversationMessages = [];
|
|
24266
|
-
const history = [];
|
|
24267
|
-
const memContext = buildMemoryContext();
|
|
24268
|
-
if (memContext.trim()) {
|
|
24269
|
-
conversationMessages.push({ role: "user", content: `[Context] ${memContext.trim()}` });
|
|
24270
|
-
conversationMessages.push({ role: "assistant", content: "Got it, I have your preferences loaded." });
|
|
24308
|
+
return this.config.provider || "gemini";
|
|
24271
24309
|
}
|
|
24272
|
-
|
|
24273
|
-
const
|
|
24274
|
-
|
|
24275
|
-
|
|
24276
|
-
|
|
24277
|
-
if (session.usage) {
|
|
24278
|
-
usage.promptTokens = session.usage.promptTokens || 0;
|
|
24279
|
-
usage.completionTokens = session.usage.completionTokens || 0;
|
|
24280
|
-
usage.totalTokens = session.usage.totalTokens || 0;
|
|
24281
|
-
usage.requests = session.usage.requests || 0;
|
|
24282
|
-
}
|
|
24283
|
-
log(color.green(` Resumed: ${sessionName} (${session.messages.length} msgs)`));
|
|
24284
|
-
}
|
|
24310
|
+
updateStatus() {
|
|
24311
|
+
const model = this.model.includes("/") ? this.model.split("/").pop() : this.model;
|
|
24312
|
+
const cost = this.usage.cost > 0 ? ` \xB7 $${this.usage.cost.toFixed(4)}` : "";
|
|
24313
|
+
const tokens = this.usage.totalTokens > 0 ? ` \xB7 ${this.usage.totalTokens.toLocaleString()} tokens` : "";
|
|
24314
|
+
this.ui?.setStatus(`${model} \xB7 ${getShellConfig().name} \xB7 ${this.autoAccept ? "auto" : "confirm"}${tokens}${cost}`);
|
|
24285
24315
|
}
|
|
24286
|
-
|
|
24287
|
-
|
|
24288
|
-
|
|
24289
|
-
try {
|
|
24290
|
-
const entries = readdirSync6(process.cwd()).filter((e) => !e.startsWith("."));
|
|
24291
|
-
let rpCount = 0, dirCount = 0;
|
|
24292
|
-
for (const e of entries.slice(0, 100)) {
|
|
24293
|
-
try {
|
|
24294
|
-
const s = statSync6(join12(process.cwd(), e));
|
|
24295
|
-
if (s.isDirectory() && !["node_modules", "__pycache__", "dist", "build"].includes(e)) dirCount++;
|
|
24296
|
-
else if (e.endsWith(".rp") || e.endsWith(".robin")) rpCount++;
|
|
24297
|
-
} catch {
|
|
24298
|
-
}
|
|
24316
|
+
exit() {
|
|
24317
|
+
if (this.conversationMessages.length > 1) {
|
|
24318
|
+
saveSession(this.sessionId, this.sessionName, this.conversationMessages, this.usage);
|
|
24299
24319
|
}
|
|
24300
|
-
|
|
24301
|
-
} catch {
|
|
24320
|
+
this.ui?.exit();
|
|
24302
24321
|
}
|
|
24303
|
-
|
|
24304
|
-
|
|
24305
|
-
|
|
24306
|
-
|
|
24307
|
-
|
|
24308
|
-
initialPrompt = null;
|
|
24309
|
-
log(color.cyan(" \u276F ") + trimmed);
|
|
24310
|
-
} else {
|
|
24311
|
-
const input = await collectInkInput(
|
|
24312
|
-
isFirst ? "What do you want to automate?" : "Ask anything..."
|
|
24313
|
-
);
|
|
24314
|
-
isFirst = false;
|
|
24315
|
-
if (input === null) {
|
|
24316
|
-
exitWithSave();
|
|
24317
|
-
break;
|
|
24318
|
-
}
|
|
24319
|
-
trimmed = input.trim();
|
|
24320
|
-
if (!trimmed) continue;
|
|
24321
|
-
log(color.cyan(" \u276F ") + color.bold(trimmed));
|
|
24322
|
-
}
|
|
24323
|
-
if (trimmed === "/") {
|
|
24324
|
-
log("");
|
|
24325
|
-
for (const [cmd, desc] of Object.entries(SLASH_CMDS)) {
|
|
24326
|
-
log(` ${color.cyan(cmd.padEnd(14))} ${color.dim(desc)}`);
|
|
24327
|
-
}
|
|
24328
|
-
log("");
|
|
24329
|
-
continue;
|
|
24322
|
+
async handleInput(text) {
|
|
24323
|
+
if (text === "/" || text === "/help") {
|
|
24324
|
+
const cmds = ["/model", "/shell", "/auto", "/clear", "/save", "/sessions", "/memory", "/usage", "exit"];
|
|
24325
|
+
this.ui?.addMessage("info", cmds.join(" "));
|
|
24326
|
+
return;
|
|
24330
24327
|
}
|
|
24331
|
-
if (
|
|
24332
|
-
|
|
24333
|
-
|
|
24328
|
+
if (text === "/clear") {
|
|
24329
|
+
this.conversationMessages.length = 0;
|
|
24330
|
+
this.ui?.addMessage("info", "Cleared.");
|
|
24331
|
+
return;
|
|
24334
24332
|
}
|
|
24335
|
-
if (
|
|
24336
|
-
|
|
24337
|
-
|
|
24338
|
-
|
|
24339
|
-
}
|
|
24340
|
-
log("");
|
|
24341
|
-
continue;
|
|
24333
|
+
if (text === "/usage") {
|
|
24334
|
+
const c = this.usage.cost > 0 ? `$${this.usage.cost.toFixed(4)}` : "$0 (free)";
|
|
24335
|
+
this.ui?.addMessage("info", `${this.usage.totalTokens.toLocaleString()} tokens \xB7 ${this.usage.requests} requests \xB7 ${c}`);
|
|
24336
|
+
return;
|
|
24342
24337
|
}
|
|
24343
|
-
if (
|
|
24344
|
-
|
|
24345
|
-
|
|
24346
|
-
|
|
24338
|
+
if (text === "/auto") {
|
|
24339
|
+
this.autoAccept = !this.autoAccept;
|
|
24340
|
+
this.ui?.addMessage("info", `Auto-accept: ${this.autoAccept ? "ON" : "OFF"}`);
|
|
24341
|
+
this.updateStatus();
|
|
24342
|
+
return;
|
|
24347
24343
|
}
|
|
24348
|
-
if (
|
|
24349
|
-
const
|
|
24350
|
-
|
|
24351
|
-
|
|
24344
|
+
if (text === "/model") {
|
|
24345
|
+
const hasKey = !!readAiConfig().apiKey;
|
|
24346
|
+
const models = hasKey ? AI_MODELS : AI_MODELS.filter((m) => !m.requiresKey);
|
|
24347
|
+
this.ui?.addMessage("info", models.map((m, i) => `${i + 1}. ${m.name} \u2014 ${m.desc}`).join("\n"));
|
|
24348
|
+
return;
|
|
24352
24349
|
}
|
|
24353
|
-
if (
|
|
24350
|
+
if (text.match(/^\/model \d+$/)) {
|
|
24354
24351
|
const hasKey = !!readAiConfig().apiKey;
|
|
24355
24352
|
const models = hasKey ? AI_MODELS : AI_MODELS.filter((m) => !m.requiresKey);
|
|
24356
|
-
const
|
|
24357
|
-
|
|
24358
|
-
|
|
24359
|
-
|
|
24360
|
-
|
|
24361
|
-
|
|
24362
|
-
|
|
24363
|
-
lastGroup = m.group;
|
|
24364
|
-
}
|
|
24365
|
-
const mark = m.id === cur ? color.green(" \u2713") : "";
|
|
24366
|
-
log(` ${color.cyan(String(i + 1))}. ${m.name} ${color.dim("\u2014 " + m.desc)}${mark}`);
|
|
24367
|
-
}
|
|
24368
|
-
log("");
|
|
24369
|
-
const answer = await collectInkInput("Enter number...");
|
|
24370
|
-
if (answer) {
|
|
24371
|
-
const idx = parseInt(answer, 10) - 1;
|
|
24372
|
-
if (idx >= 0 && idx < models.length) {
|
|
24373
|
-
config.model = models[idx].id;
|
|
24374
|
-
writeAiConfig(config);
|
|
24375
|
-
log(color.green(` Model: ${models[idx].id}`));
|
|
24376
|
-
}
|
|
24353
|
+
const idx = parseInt(text.split(" ")[1], 10) - 1;
|
|
24354
|
+
if (idx >= 0 && idx < models.length) {
|
|
24355
|
+
this.config.model = models[idx].id;
|
|
24356
|
+
this.model = models[idx].id;
|
|
24357
|
+
writeAiConfig(this.config);
|
|
24358
|
+
this.ui?.addMessage("info", `Model: ${models[idx].id}`);
|
|
24359
|
+
this.updateStatus();
|
|
24377
24360
|
}
|
|
24378
|
-
|
|
24379
|
-
}
|
|
24380
|
-
if (trimmed === "/auto" || trimmed.startsWith("/auto ")) {
|
|
24381
|
-
const arg = trimmed.slice(5).trim().toLowerCase();
|
|
24382
|
-
if (arg === "on") autoAccept = true;
|
|
24383
|
-
else if (arg === "off") autoAccept = false;
|
|
24384
|
-
else autoAccept = !autoAccept;
|
|
24385
|
-
log(` Auto-accept: ${autoAccept ? color.green("ON") : color.yellow("OFF")}`);
|
|
24386
|
-
continue;
|
|
24361
|
+
return;
|
|
24387
24362
|
}
|
|
24388
|
-
if (
|
|
24363
|
+
if (text === "/memory") {
|
|
24389
24364
|
const mem = loadMemory();
|
|
24390
|
-
|
|
24391
|
-
|
|
24392
|
-
continue;
|
|
24393
|
-
}
|
|
24394
|
-
if (trimmed.startsWith("/remember ")) {
|
|
24395
|
-
addMemoryFact(trimmed.slice(10).trim());
|
|
24396
|
-
log(color.green(" Remembered."));
|
|
24397
|
-
continue;
|
|
24398
|
-
}
|
|
24399
|
-
if (trimmed.startsWith("/forget ")) {
|
|
24400
|
-
removeMemoryFact(parseInt(trimmed.slice(8).trim(), 10) - 1);
|
|
24401
|
-
log(color.green(" Forgot."));
|
|
24402
|
-
continue;
|
|
24403
|
-
}
|
|
24404
|
-
if (trimmed === "/save" || trimmed.startsWith("/save ")) {
|
|
24405
|
-
if (trimmed.length > 5) sessionName = trimmed.slice(5).trim();
|
|
24406
|
-
saveSession(sessionId, sessionName, conversationMessages, usage);
|
|
24407
|
-
log(color.green(` Saved: ${sessionName}`));
|
|
24408
|
-
continue;
|
|
24409
|
-
}
|
|
24410
|
-
if (trimmed === "/sessions") {
|
|
24411
|
-
const sessions = listSessions();
|
|
24412
|
-
if (sessions.length === 0) log(color.dim(" No sessions."));
|
|
24413
|
-
else sessions.forEach((s) => log(` ${color.cyan(s.id)} ${s.name} ${color.dim(`${s.messages} msgs`)}`));
|
|
24414
|
-
continue;
|
|
24415
|
-
}
|
|
24416
|
-
if (trimmed === "/shell") {
|
|
24417
|
-
const shells = getAvailableShells();
|
|
24418
|
-
shells.forEach((s) => {
|
|
24419
|
-
const mark = s.current ? color.green(" \u2713") : s.available ? "" : color.dim(" (not found)");
|
|
24420
|
-
log(` ${s.available ? color.cyan(s.name) : color.dim(s.name)}${mark}`);
|
|
24421
|
-
});
|
|
24422
|
-
continue;
|
|
24365
|
+
this.ui?.addMessage("info", mem.facts.length ? mem.facts.map((f, i) => `${i + 1}. ${f}`).join("\n") : "No memories.");
|
|
24366
|
+
return;
|
|
24423
24367
|
}
|
|
24424
|
-
if (
|
|
24425
|
-
|
|
24426
|
-
|
|
24427
|
-
|
|
24428
|
-
|
|
24368
|
+
if (text.startsWith("/save")) {
|
|
24369
|
+
if (text.length > 5) this.sessionName = text.slice(5).trim();
|
|
24370
|
+
saveSession(this.sessionId, this.sessionName, this.conversationMessages, this.usage);
|
|
24371
|
+
this.ui?.addMessage("info", `Saved: ${this.sessionName}`);
|
|
24372
|
+
return;
|
|
24429
24373
|
}
|
|
24430
|
-
if (
|
|
24431
|
-
|
|
24432
|
-
|
|
24374
|
+
if (text.startsWith("/")) {
|
|
24375
|
+
this.ui?.addMessage("info", `Unknown: ${text}. Type / for help.`);
|
|
24376
|
+
return;
|
|
24433
24377
|
}
|
|
24434
|
-
|
|
24435
|
-
|
|
24436
|
-
|
|
24437
|
-
|
|
24438
|
-
const activeKey = readAiConfig().apiKey || apiKey;
|
|
24439
|
-
const activeProvider = resolveProvider(activeKey);
|
|
24440
|
-
let spinner = createSpinner("Thinking");
|
|
24378
|
+
this.ui?.addMessage("user", text);
|
|
24379
|
+
this.ui?.setLoading(true);
|
|
24380
|
+
this.ui?.setStreaming("");
|
|
24381
|
+
this.ui?.setLoadingLabel("Thinking");
|
|
24441
24382
|
try {
|
|
24383
|
+
const { expanded } = expandFileRefs(text);
|
|
24384
|
+
this.conversationMessages.push({ role: "user", content: expanded });
|
|
24385
|
+
await autoCompact(this.conversationMessages);
|
|
24386
|
+
const activeModel = readAiConfig().model || this.model;
|
|
24387
|
+
const activeKey = readAiConfig().apiKey || this.apiKey;
|
|
24388
|
+
const activeProvider = this.resolveProvider(activeKey);
|
|
24389
|
+
let fullResponse = "";
|
|
24442
24390
|
for (let loop = 0; loop < 15; loop++) {
|
|
24443
|
-
|
|
24444
|
-
|
|
24445
|
-
let insideCmd = false;
|
|
24391
|
+
this.ui?.setLoadingLabel(loop === 0 ? "Thinking" : "Processing");
|
|
24392
|
+
fullResponse = "";
|
|
24446
24393
|
const result = await fetchBrainStream(
|
|
24447
|
-
loop === 0 ? expanded : conversationMessages[conversationMessages.length - 1].content,
|
|
24394
|
+
loop === 0 ? expanded : this.conversationMessages[this.conversationMessages.length - 1].content,
|
|
24448
24395
|
{
|
|
24449
24396
|
onToken: (delta) => {
|
|
24450
|
-
spinner.stop();
|
|
24451
24397
|
if (delta === "\x1B[RETRY]") {
|
|
24452
|
-
|
|
24453
|
-
|
|
24454
|
-
insideCmd = false;
|
|
24455
|
-
spinner = createSpinner("Retrying");
|
|
24398
|
+
fullResponse = "";
|
|
24399
|
+
this.ui?.setStreaming("");
|
|
24456
24400
|
return;
|
|
24457
24401
|
}
|
|
24458
|
-
|
|
24459
|
-
|
|
24460
|
-
|
|
24461
|
-
const ci2 = pending.indexOf("</memory>");
|
|
24462
|
-
if (ci2 === -1) break;
|
|
24463
|
-
const fact = pending.slice(0, ci2).trim();
|
|
24464
|
-
if (fact.length > 3 && fact.length < 300) addMemoryFact(fact);
|
|
24465
|
-
pending = pending.slice(ci2 + 9);
|
|
24466
|
-
insideMemory = false;
|
|
24467
|
-
continue;
|
|
24468
|
-
}
|
|
24469
|
-
if (insideCmd) {
|
|
24470
|
-
const ci2 = pending.indexOf("</cmd>");
|
|
24471
|
-
if (ci2 === -1) break;
|
|
24472
|
-
pending = pending.slice(ci2 + 6);
|
|
24473
|
-
insideCmd = false;
|
|
24474
|
-
continue;
|
|
24475
|
-
}
|
|
24476
|
-
const mi = pending.indexOf("<memory>");
|
|
24477
|
-
const ci = pending.indexOf("<cmd>");
|
|
24478
|
-
if (mi === -1 && ci === -1) {
|
|
24479
|
-
const lt2 = pending.lastIndexOf("<");
|
|
24480
|
-
if (lt2 !== -1 && lt2 > pending.length - 9) {
|
|
24481
|
-
if (lt2 > 0) {
|
|
24482
|
-
process.stdout.write(pending.slice(0, lt2).replace(/\n{3,}/g, "\n\n"));
|
|
24483
|
-
pending = pending.slice(lt2);
|
|
24484
|
-
}
|
|
24485
|
-
} else {
|
|
24486
|
-
process.stdout.write(pending.replace(/\n{3,}/g, "\n\n"));
|
|
24487
|
-
pending = "";
|
|
24488
|
-
}
|
|
24489
|
-
break;
|
|
24490
|
-
}
|
|
24491
|
-
const first = mi === -1 ? ci : ci === -1 ? mi : Math.min(mi, ci);
|
|
24492
|
-
if (first > 0) process.stdout.write(pending.slice(0, first).replace(/\n{3,}/g, "\n\n"));
|
|
24493
|
-
if (first === mi) {
|
|
24494
|
-
pending = pending.slice(first + 8);
|
|
24495
|
-
insideMemory = true;
|
|
24496
|
-
} else {
|
|
24497
|
-
pending = pending.slice(first + 5);
|
|
24498
|
-
insideCmd = true;
|
|
24499
|
-
}
|
|
24500
|
-
}
|
|
24402
|
+
fullResponse += delta;
|
|
24403
|
+
const clean = fullResponse.replace(/<memory>[\s\S]*?<\/memory>/g, "").replace(/<cmd>[\s\S]*?<\/cmd>/g, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
24404
|
+
this.ui?.setStreaming(clean);
|
|
24501
24405
|
},
|
|
24502
|
-
conversationHistory: conversationMessages.slice(0, -1),
|
|
24406
|
+
conversationHistory: this.conversationMessages.slice(0, -1),
|
|
24503
24407
|
provider: activeProvider,
|
|
24504
24408
|
model: activeModel,
|
|
24505
24409
|
apiKey: activeKey,
|
|
24506
|
-
cliContext
|
|
24410
|
+
cliContext: this.cliContext
|
|
24507
24411
|
}
|
|
24508
24412
|
);
|
|
24509
|
-
if (pending && !insideMemory && !insideCmd) process.stdout.write(pending);
|
|
24510
24413
|
if (!result || !result.code) {
|
|
24511
|
-
|
|
24512
|
-
log(color.red("\n No response."));
|
|
24414
|
+
this.ui?.addMessage("assistant", fullResponse || "No response. Check connection or API key.");
|
|
24513
24415
|
break;
|
|
24514
24416
|
}
|
|
24515
24417
|
if (result.usage) {
|
|
24516
24418
|
const pt2 = result.usage.prompt_tokens || 0;
|
|
24517
24419
|
const ct2 = result.usage.completion_tokens || 0;
|
|
24518
|
-
usage.promptTokens += pt2;
|
|
24519
|
-
usage.completionTokens += ct2;
|
|
24520
|
-
usage.totalTokens += pt2 + ct2;
|
|
24521
|
-
usage.requests++;
|
|
24522
|
-
usage.cost += estimateCost(activeModel, pt2, ct2);
|
|
24420
|
+
this.usage.promptTokens += pt2;
|
|
24421
|
+
this.usage.completionTokens += ct2;
|
|
24422
|
+
this.usage.totalTokens += pt2 + ct2;
|
|
24423
|
+
this.usage.requests++;
|
|
24424
|
+
this.usage.cost += estimateCost(activeModel, pt2, ct2);
|
|
24425
|
+
this.updateStatus();
|
|
24523
24426
|
}
|
|
24524
|
-
const commands = extractCommands(result.code);
|
|
24525
24427
|
const { cleaned } = extractMemoryTags(stripCommandTags(result.code));
|
|
24526
|
-
|
|
24527
|
-
if (cleaned)
|
|
24528
|
-
|
|
24428
|
+
const commands = extractCommands(result.code);
|
|
24429
|
+
if (cleaned) {
|
|
24430
|
+
this.conversationMessages.push({ role: "assistant", content: cleaned });
|
|
24431
|
+
}
|
|
24432
|
+
if (commands.length === 0) {
|
|
24433
|
+
if (cleaned) this.ui?.addMessage("assistant", cleaned);
|
|
24434
|
+
break;
|
|
24435
|
+
}
|
|
24436
|
+
if (cleaned) this.ui?.addMessage("assistant", cleaned);
|
|
24529
24437
|
const cmdResults = [];
|
|
24530
24438
|
for (const cmd of commands) {
|
|
24531
|
-
|
|
24532
|
-
if (decision === "no") {
|
|
24533
|
-
cmdResults.push({ command: cmd, stdout: "", stderr: "(skipped)", exitCode: -1 });
|
|
24534
|
-
continue;
|
|
24535
|
-
}
|
|
24536
|
-
if (decision === "auto") {
|
|
24537
|
-
autoAccept = true;
|
|
24538
|
-
log(color.green(" Auto-accept ON"));
|
|
24539
|
-
}
|
|
24439
|
+
this.ui?.addMessage("info", `$ ${cmd.split("\n")[0]}${cmd.includes("\n") ? ` (+${cmd.split("\n").length - 1} lines)` : ""}`);
|
|
24540
24440
|
const r = await executeShellCommand(cmd);
|
|
24541
|
-
if (r.exitCode
|
|
24441
|
+
if (r.exitCode === 0 && r.stdout?.trim()) {
|
|
24442
|
+
this.ui?.addMessage("info", r.stdout.trim().split("\n").slice(0, 5).join("\n"));
|
|
24443
|
+
} else if (r.exitCode !== 0) {
|
|
24444
|
+
this.ui?.addMessage("info", `exit ${r.exitCode}: ${(r.stderr || "").slice(0, 100)}`);
|
|
24445
|
+
}
|
|
24542
24446
|
cmdResults.push({ command: cmd, stdout: r.stdout || "", stderr: r.stderr || "", exitCode: r.exitCode });
|
|
24543
24447
|
}
|
|
24544
24448
|
const summary = cmdResults.map((r) => {
|
|
@@ -24552,59 +24456,44 @@ async function startInkREPL(initialPrompt, resumeSessionId, opts = {}) {
|
|
|
24552
24456
|
}
|
|
24553
24457
|
return o;
|
|
24554
24458
|
}).join("\n\n");
|
|
24555
|
-
conversationMessages.push({ role: "user", content: `[Command results]
|
|
24459
|
+
this.conversationMessages.push({ role: "user", content: `[Command results]
|
|
24556
24460
|
${summary}` });
|
|
24557
|
-
|
|
24461
|
+
this.ui?.setStreaming("");
|
|
24558
24462
|
}
|
|
24559
24463
|
} catch (err) {
|
|
24560
|
-
|
|
24561
|
-
|
|
24464
|
+
this.ui?.addMessage("info", `Error: ${err.message}`);
|
|
24465
|
+
} finally {
|
|
24466
|
+
this.ui?.setLoading(false);
|
|
24467
|
+
this.ui?.setStreaming("");
|
|
24468
|
+
saveSession(this.sessionId, this.sessionName, this.conversationMessages, this.usage);
|
|
24562
24469
|
}
|
|
24563
|
-
log("");
|
|
24564
|
-
if (usage.cost > 0) log(color.dim(` $${usage.cost.toFixed(4)} \xB7 ${usage.totalTokens.toLocaleString()} tokens`));
|
|
24565
24470
|
}
|
|
24566
|
-
function exitWithSave() {
|
|
24567
|
-
if (conversationMessages.length > 1) {
|
|
24568
|
-
saveSession(sessionId, sessionName, conversationMessages, usage);
|
|
24569
|
-
log(color.dim(` Session saved: ${sessionId}`));
|
|
24570
|
-
}
|
|
24571
|
-
log(color.dim(" Goodbye!"));
|
|
24572
|
-
process.exit(0);
|
|
24573
|
-
}
|
|
24574
|
-
process.on("SIGINT", () => {
|
|
24575
|
-
log("");
|
|
24576
|
-
exitWithSave();
|
|
24577
|
-
});
|
|
24578
|
-
}
|
|
24579
|
-
var SLASH_CMDS = {
|
|
24580
|
-
"/help": "Show commands",
|
|
24581
|
-
"/model": "Switch AI model",
|
|
24582
|
-
"/shell": "Switch shell",
|
|
24583
|
-
"/auto": "Toggle auto-accept",
|
|
24584
|
-
"/clear": "Clear conversation",
|
|
24585
|
-
"/save": "Save session",
|
|
24586
|
-
"/sessions": "List sessions",
|
|
24587
|
-
"/memory": "Show memory",
|
|
24588
|
-
"/remember": "Save a fact",
|
|
24589
|
-
"/forget": "Remove a memory",
|
|
24590
|
-
"/usage": "Token usage & cost",
|
|
24591
|
-
"exit": "Quit"
|
|
24592
24471
|
};
|
|
24472
|
+
async function startInkREPL(initialPrompt, resumeSessionId, opts = {}) {
|
|
24473
|
+
const engine = new ReplEngine(resumeSessionId, opts);
|
|
24474
|
+
const { waitUntilExit } = render(/* @__PURE__ */ jsx(App, { engine }));
|
|
24475
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
24476
|
+
engine.updateStatus();
|
|
24477
|
+
if (initialPrompt) {
|
|
24478
|
+
await engine.handleInput(initialPrompt);
|
|
24479
|
+
}
|
|
24480
|
+
await waitUntilExit();
|
|
24481
|
+
}
|
|
24593
24482
|
|
|
24594
24483
|
// src/commands-modules.ts
|
|
24595
24484
|
import { createInterface as createInterface3 } from "node:readline";
|
|
24596
24485
|
import {
|
|
24597
|
-
readFileSync as
|
|
24598
|
-
existsSync as
|
|
24486
|
+
readFileSync as readFileSync10,
|
|
24487
|
+
existsSync as existsSync11,
|
|
24599
24488
|
mkdirSync as mkdirSync6,
|
|
24600
24489
|
copyFileSync as copyFileSync2,
|
|
24601
24490
|
rmSync as rmSync2,
|
|
24602
24491
|
writeFileSync as writeFileSync6,
|
|
24603
|
-
readdirSync as
|
|
24604
|
-
statSync as
|
|
24492
|
+
readdirSync as readdirSync6,
|
|
24493
|
+
statSync as statSync6,
|
|
24605
24494
|
unlinkSync as unlinkSync5
|
|
24606
24495
|
} from "node:fs";
|
|
24607
|
-
import { resolve as resolve8, join as
|
|
24496
|
+
import { resolve as resolve8, join as join12, dirname as dirname4, basename as basename4 } from "node:path";
|
|
24608
24497
|
import { execSync as execSync2 } from "node:child_process";
|
|
24609
24498
|
import { homedir as homedir9, platform as platform8, tmpdir as tmpdir3 } from "node:os";
|
|
24610
24499
|
import { createHash as createHash3 } from "node:crypto";
|
|
@@ -24695,17 +24584,17 @@ async function handleAdd(args) {
|
|
|
24695
24584
|
process.exit(1);
|
|
24696
24585
|
}
|
|
24697
24586
|
const integrity = "sha256-" + createHash3("sha256").update(tarballBuffer).digest("hex");
|
|
24698
|
-
if (!
|
|
24587
|
+
if (!existsSync11(CACHE_DIR)) {
|
|
24699
24588
|
mkdirSync6(CACHE_DIR, { recursive: true });
|
|
24700
24589
|
}
|
|
24701
|
-
const cacheFile =
|
|
24590
|
+
const cacheFile = join12(CACHE_DIR, `${scope}-${name}-${resolvedVersion}.tar.gz`);
|
|
24702
24591
|
writeFileSync6(cacheFile, tarballBuffer);
|
|
24703
24592
|
const modDir = getModulePath(fullName);
|
|
24704
|
-
if (
|
|
24593
|
+
if (existsSync11(modDir)) {
|
|
24705
24594
|
rmSync2(modDir, { recursive: true, force: true });
|
|
24706
24595
|
}
|
|
24707
24596
|
mkdirSync6(modDir, { recursive: true });
|
|
24708
|
-
const tmpFile =
|
|
24597
|
+
const tmpFile = join12(tmpdir3(), `robinpath-add-${Date.now()}.tar.gz`);
|
|
24709
24598
|
writeFileSync6(tmpFile, tarballBuffer);
|
|
24710
24599
|
try {
|
|
24711
24600
|
execSync2(`tar xzf "${toTarPath(tmpFile)}" --strip-components=1 -C "${toTarPath(modDir)}"`, { stdio: "pipe" });
|
|
@@ -24722,15 +24611,15 @@ async function handleAdd(args) {
|
|
|
24722
24611
|
unlinkSync5(tmpFile);
|
|
24723
24612
|
} catch {
|
|
24724
24613
|
}
|
|
24725
|
-
const distDir =
|
|
24726
|
-
const srcDir =
|
|
24727
|
-
if (!
|
|
24614
|
+
const distDir = join12(modDir, "dist");
|
|
24615
|
+
const srcDir = join12(modDir, "src");
|
|
24616
|
+
if (!existsSync11(distDir) && existsSync11(srcDir) && existsSync11(join12(srcDir, "index.ts"))) {
|
|
24728
24617
|
log(color.dim(" Compiling module..."));
|
|
24729
24618
|
mkdirSync6(distDir, { recursive: true });
|
|
24730
|
-
const tsFiles =
|
|
24619
|
+
const tsFiles = readdirSync6(srcDir).filter((f) => f.endsWith(".ts"));
|
|
24731
24620
|
for (const file of tsFiles) {
|
|
24732
|
-
const srcFile =
|
|
24733
|
-
const outFile =
|
|
24621
|
+
const srcFile = join12(srcDir, file);
|
|
24622
|
+
const outFile = join12(distDir, file.replace(".ts", ".js"));
|
|
24734
24623
|
try {
|
|
24735
24624
|
const stripScript = `
|
|
24736
24625
|
const fs = require('fs');
|
|
@@ -24746,17 +24635,17 @@ async function handleAdd(args) {
|
|
|
24746
24635
|
}
|
|
24747
24636
|
}
|
|
24748
24637
|
let installedVersion = resolvedVersion;
|
|
24749
|
-
const pkgJsonPath =
|
|
24750
|
-
if (
|
|
24638
|
+
const pkgJsonPath = join12(modDir, "package.json");
|
|
24639
|
+
if (existsSync11(pkgJsonPath)) {
|
|
24751
24640
|
try {
|
|
24752
|
-
const pkg = JSON.parse(
|
|
24641
|
+
const pkg = JSON.parse(readFileSync10(pkgJsonPath, "utf-8"));
|
|
24753
24642
|
installedVersion = pkg.version || installedVersion;
|
|
24754
24643
|
} catch {
|
|
24755
24644
|
}
|
|
24756
24645
|
}
|
|
24757
|
-
if (
|
|
24646
|
+
if (existsSync11(pkgJsonPath)) {
|
|
24758
24647
|
try {
|
|
24759
|
-
const pkg = JSON.parse(
|
|
24648
|
+
const pkg = JSON.parse(readFileSync10(pkgJsonPath, "utf-8"));
|
|
24760
24649
|
const depends = pkg.robinpath?.depends || [];
|
|
24761
24650
|
for (const dep of depends) {
|
|
24762
24651
|
if (!manifest[dep]) {
|
|
@@ -24775,9 +24664,9 @@ async function handleAdd(args) {
|
|
|
24775
24664
|
};
|
|
24776
24665
|
writeModulesManifest(updatedManifest);
|
|
24777
24666
|
const projectFile = resolve8("robinpath.json");
|
|
24778
|
-
if (
|
|
24667
|
+
if (existsSync11(projectFile)) {
|
|
24779
24668
|
try {
|
|
24780
|
-
const config = JSON.parse(
|
|
24669
|
+
const config = JSON.parse(readFileSync10(projectFile, "utf-8"));
|
|
24781
24670
|
if (!config.modules) config.modules = {};
|
|
24782
24671
|
config.modules[fullName] = `^${installedVersion}`;
|
|
24783
24672
|
writeFileSync6(projectFile, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
@@ -24805,12 +24694,12 @@ async function handleRemove(args) {
|
|
|
24805
24694
|
process.exit(1);
|
|
24806
24695
|
}
|
|
24807
24696
|
const modDir = getModulePath(fullName);
|
|
24808
|
-
if (
|
|
24697
|
+
if (existsSync11(modDir)) {
|
|
24809
24698
|
rmSync2(modDir, { recursive: true, force: true });
|
|
24810
24699
|
}
|
|
24811
24700
|
const scopeDir = dirname4(modDir);
|
|
24812
24701
|
try {
|
|
24813
|
-
const remaining =
|
|
24702
|
+
const remaining = readdirSync6(scopeDir);
|
|
24814
24703
|
if (remaining.length === 0) {
|
|
24815
24704
|
rmSync2(scopeDir, { recursive: true, force: true });
|
|
24816
24705
|
}
|
|
@@ -24819,9 +24708,9 @@ async function handleRemove(args) {
|
|
|
24819
24708
|
delete manifest[fullName];
|
|
24820
24709
|
writeModulesManifest(manifest);
|
|
24821
24710
|
const projectFile = resolve8("robinpath.json");
|
|
24822
|
-
if (
|
|
24711
|
+
if (existsSync11(projectFile)) {
|
|
24823
24712
|
try {
|
|
24824
|
-
const config = JSON.parse(
|
|
24713
|
+
const config = JSON.parse(readFileSync10(projectFile, "utf-8"));
|
|
24825
24714
|
if (config.modules && config.modules[fullName]) {
|
|
24826
24715
|
delete config.modules[fullName];
|
|
24827
24716
|
writeFileSync6(projectFile, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
@@ -24994,14 +24883,14 @@ async function handleModulesInit() {
|
|
|
24994
24883
|
const targetDir = resolve8(moduleName);
|
|
24995
24884
|
log("");
|
|
24996
24885
|
log(`Creating ${color.cyan(fullName)}...`);
|
|
24997
|
-
if (
|
|
24886
|
+
if (existsSync11(targetDir)) {
|
|
24998
24887
|
console.error(color.red("Error:") + ` Directory already exists: ${moduleName}/`);
|
|
24999
24888
|
process.exit(1);
|
|
25000
24889
|
}
|
|
25001
|
-
mkdirSync6(
|
|
25002
|
-
mkdirSync6(
|
|
24890
|
+
mkdirSync6(join12(targetDir, "src"), { recursive: true });
|
|
24891
|
+
mkdirSync6(join12(targetDir, "tests"), { recursive: true });
|
|
25003
24892
|
writeFileSync6(
|
|
25004
|
-
|
|
24893
|
+
join12(targetDir, "package.json"),
|
|
25005
24894
|
JSON.stringify(
|
|
25006
24895
|
{
|
|
25007
24896
|
name: fullName,
|
|
@@ -25025,7 +24914,7 @@ async function handleModulesInit() {
|
|
|
25025
24914
|
"utf-8"
|
|
25026
24915
|
);
|
|
25027
24916
|
writeFileSync6(
|
|
25028
|
-
|
|
24917
|
+
join12(targetDir, "src", "index.ts"),
|
|
25029
24918
|
`import type { ModuleAdapter } from "@wiredwp/robinpath";
|
|
25030
24919
|
import {
|
|
25031
24920
|
${pascalName}Functions,
|
|
@@ -25047,7 +24936,7 @@ export { ${pascalName}Module };
|
|
|
25047
24936
|
"utf-8"
|
|
25048
24937
|
);
|
|
25049
24938
|
writeFileSync6(
|
|
25050
|
-
|
|
24939
|
+
join12(targetDir, "src", `${moduleName}.ts`),
|
|
25051
24940
|
`import type {
|
|
25052
24941
|
BuiltinHandler,
|
|
25053
24942
|
FunctionMetadata,
|
|
@@ -25118,7 +25007,7 @@ export const ${pascalName}ModuleMetadata: ModuleMetadata = {
|
|
|
25118
25007
|
"utf-8"
|
|
25119
25008
|
);
|
|
25120
25009
|
writeFileSync6(
|
|
25121
|
-
|
|
25010
|
+
join12(targetDir, "tsconfig.json"),
|
|
25122
25011
|
JSON.stringify(
|
|
25123
25012
|
{
|
|
25124
25013
|
compilerOptions: {
|
|
@@ -25142,7 +25031,7 @@ export const ${pascalName}ModuleMetadata: ModuleMetadata = {
|
|
|
25142
25031
|
"utf-8"
|
|
25143
25032
|
);
|
|
25144
25033
|
writeFileSync6(
|
|
25145
|
-
|
|
25034
|
+
join12(targetDir, "tests", `${moduleName}.test.rp`),
|
|
25146
25035
|
`# ${displayName} module tests
|
|
25147
25036
|
# Run: robinpath test tests/
|
|
25148
25037
|
|
|
@@ -25161,7 +25050,7 @@ enddo
|
|
|
25161
25050
|
"utf-8"
|
|
25162
25051
|
);
|
|
25163
25052
|
writeFileSync6(
|
|
25164
|
-
|
|
25053
|
+
join12(targetDir, "README.md"),
|
|
25165
25054
|
`# ${fullName}
|
|
25166
25055
|
|
|
25167
25056
|
${description}
|
|
@@ -25205,7 +25094,7 @@ ${license}
|
|
|
25205
25094
|
"utf-8"
|
|
25206
25095
|
);
|
|
25207
25096
|
writeFileSync6(
|
|
25208
|
-
|
|
25097
|
+
join12(targetDir, ".gitignore"),
|
|
25209
25098
|
`node_modules/
|
|
25210
25099
|
dist/
|
|
25211
25100
|
*.tgz
|
|
@@ -25235,14 +25124,14 @@ dist/
|
|
|
25235
25124
|
async function handlePack(args) {
|
|
25236
25125
|
const targetArg = args.find((a) => !a.startsWith("-")) || ".";
|
|
25237
25126
|
const targetDir = resolve8(targetArg);
|
|
25238
|
-
const pkgPath =
|
|
25239
|
-
if (!
|
|
25127
|
+
const pkgPath = join12(targetDir, "package.json");
|
|
25128
|
+
if (!existsSync11(pkgPath)) {
|
|
25240
25129
|
console.error(color.red("Error:") + ` No package.json found in ${targetDir}`);
|
|
25241
25130
|
process.exit(2);
|
|
25242
25131
|
}
|
|
25243
25132
|
let pkg;
|
|
25244
25133
|
try {
|
|
25245
|
-
pkg = JSON.parse(
|
|
25134
|
+
pkg = JSON.parse(readFileSync10(pkgPath, "utf-8"));
|
|
25246
25135
|
} catch (err) {
|
|
25247
25136
|
console.error(color.red("Error:") + ` Invalid package.json: ${err.message}`);
|
|
25248
25137
|
process.exit(2);
|
|
@@ -25263,12 +25152,12 @@ async function handlePack(args) {
|
|
|
25263
25152
|
{ stdio: "pipe" }
|
|
25264
25153
|
);
|
|
25265
25154
|
} catch (err) {
|
|
25266
|
-
if (!
|
|
25155
|
+
if (!existsSync11(outputPath)) {
|
|
25267
25156
|
console.error(color.red("Error:") + ` Failed to create tarball: ${err.message}`);
|
|
25268
25157
|
process.exit(1);
|
|
25269
25158
|
}
|
|
25270
25159
|
}
|
|
25271
|
-
const size =
|
|
25160
|
+
const size = statSync6(outputPath).size;
|
|
25272
25161
|
log(color.green("Created") + ` ${outputFile} (${(size / 1024).toFixed(1)}KB)`);
|
|
25273
25162
|
}
|
|
25274
25163
|
function formatCompactNumber(n) {
|
|
@@ -25417,9 +25306,9 @@ async function handleInfo(args) {
|
|
|
25417
25306
|
path: getModulePath(packageName)
|
|
25418
25307
|
};
|
|
25419
25308
|
try {
|
|
25420
|
-
const pkgPath =
|
|
25421
|
-
if (
|
|
25422
|
-
const pkg = JSON.parse(
|
|
25309
|
+
const pkgPath = join12(getModulePath(packageName), "package.json");
|
|
25310
|
+
if (existsSync11(pkgPath)) {
|
|
25311
|
+
const pkg = JSON.parse(readFileSync10(pkgPath, "utf-8"));
|
|
25423
25312
|
if (pkg.description) entry.description = pkg.description;
|
|
25424
25313
|
if (pkg.keywords) entry.keywords = pkg.keywords;
|
|
25425
25314
|
}
|
|
@@ -25443,9 +25332,9 @@ async function handleInfo(args) {
|
|
|
25443
25332
|
modules_manifest: MODULES_MANIFEST,
|
|
25444
25333
|
cache: CACHE_DIR,
|
|
25445
25334
|
auth: getAuthPath(),
|
|
25446
|
-
history:
|
|
25447
|
-
env:
|
|
25448
|
-
docs:
|
|
25335
|
+
history: join12(homedir9(), ".robinpath", "history"),
|
|
25336
|
+
env: join12(homedir9(), ".robinpath", "env"),
|
|
25337
|
+
docs: join12(getRobinPathHome(), "DOCUMENTATION.md")
|
|
25449
25338
|
},
|
|
25450
25339
|
native_modules: modulesInfo,
|
|
25451
25340
|
installed_modules: installedModulesInfo,
|
|
@@ -25834,14 +25723,14 @@ async function handleInfo(args) {
|
|
|
25834
25723
|
}
|
|
25835
25724
|
|
|
25836
25725
|
// src/commands-project.ts
|
|
25837
|
-
import { readFileSync as
|
|
25838
|
-
import { resolve as resolve9, join as
|
|
25726
|
+
import { readFileSync as readFileSync11, existsSync as existsSync12, mkdirSync as mkdirSync7, writeFileSync as writeFileSync7, readdirSync as readdirSync7, statSync as statSync7, rmSync as rmSync3, chmodSync as chmodSync3 } from "node:fs";
|
|
25727
|
+
import { resolve as resolve9, join as join13, basename as basename5 } from "node:path";
|
|
25839
25728
|
import { createInterface as createInterface4 } from "node:readline";
|
|
25840
25729
|
import { platform as platform9 } from "node:os";
|
|
25841
25730
|
var PLATFORM_URL3 = process.env.ROBINPATH_PLATFORM_URL || "https://api.robinpath.com";
|
|
25842
25731
|
async function handleInit(args) {
|
|
25843
25732
|
const projectFile = resolve9("robinpath.json");
|
|
25844
|
-
if (
|
|
25733
|
+
if (existsSync12(projectFile) && !args.includes("--force")) {
|
|
25845
25734
|
console.error(color.red("Error:") + " robinpath.json already exists. Use --force to overwrite.");
|
|
25846
25735
|
process.exit(1);
|
|
25847
25736
|
}
|
|
@@ -25872,7 +25761,7 @@ async function handleInit(args) {
|
|
|
25872
25761
|
};
|
|
25873
25762
|
writeFileSync7(projectFile, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
25874
25763
|
const mainPath = resolve9(mainFile);
|
|
25875
|
-
if (!
|
|
25764
|
+
if (!existsSync12(mainPath)) {
|
|
25876
25765
|
writeFileSync7(
|
|
25877
25766
|
mainPath,
|
|
25878
25767
|
`# ${projectName}
|
|
@@ -25883,7 +25772,7 @@ log "Hello from RobinPath!"
|
|
|
25883
25772
|
"utf-8"
|
|
25884
25773
|
);
|
|
25885
25774
|
}
|
|
25886
|
-
if (!
|
|
25775
|
+
if (!existsSync12(resolve9(".env"))) {
|
|
25887
25776
|
writeFileSync7(
|
|
25888
25777
|
resolve9(".env"),
|
|
25889
25778
|
`# Add your secrets here
|
|
@@ -25893,7 +25782,7 @@ log "Hello from RobinPath!"
|
|
|
25893
25782
|
"utf-8"
|
|
25894
25783
|
);
|
|
25895
25784
|
}
|
|
25896
|
-
if (!
|
|
25785
|
+
if (!existsSync12(resolve9(".gitignore"))) {
|
|
25897
25786
|
writeFileSync7(
|
|
25898
25787
|
resolve9(".gitignore"),
|
|
25899
25788
|
`.env
|
|
@@ -25906,7 +25795,7 @@ node_modules/
|
|
|
25906
25795
|
log("");
|
|
25907
25796
|
log(color.green("Created project:"));
|
|
25908
25797
|
log(` robinpath.json`);
|
|
25909
|
-
if (!
|
|
25798
|
+
if (!existsSync12(mainPath)) log(` ${mainFile}`);
|
|
25910
25799
|
log(` .env`);
|
|
25911
25800
|
log(` .gitignore`);
|
|
25912
25801
|
log("");
|
|
@@ -25915,13 +25804,13 @@ node_modules/
|
|
|
25915
25804
|
}
|
|
25916
25805
|
async function handleProjectInstall() {
|
|
25917
25806
|
const projectFile = resolve9("robinpath.json");
|
|
25918
|
-
if (!
|
|
25807
|
+
if (!existsSync12(projectFile)) {
|
|
25919
25808
|
handleInstall();
|
|
25920
25809
|
return;
|
|
25921
25810
|
}
|
|
25922
25811
|
let config;
|
|
25923
25812
|
try {
|
|
25924
|
-
config = JSON.parse(
|
|
25813
|
+
config = JSON.parse(readFileSync11(projectFile, "utf-8"));
|
|
25925
25814
|
} catch (err) {
|
|
25926
25815
|
console.error(color.red("Error:") + ` Invalid robinpath.json: ${err.message}`);
|
|
25927
25816
|
process.exit(2);
|
|
@@ -25992,7 +25881,7 @@ async function handleDoctor() {
|
|
|
25992
25881
|
const installDir = getInstallDir();
|
|
25993
25882
|
const isWindows = platform9() === "win32";
|
|
25994
25883
|
const binaryName = isWindows ? "robinpath.exe" : "robinpath";
|
|
25995
|
-
if (
|
|
25884
|
+
if (existsSync12(join13(installDir, binaryName))) {
|
|
25996
25885
|
log(color.green(" \u2713") + ` Installed: ${installDir}`);
|
|
25997
25886
|
} else {
|
|
25998
25887
|
log(color.yellow(" !") + ` Not installed to PATH. Run ${color.cyan("robinpath install")}`);
|
|
@@ -26019,21 +25908,21 @@ async function handleDoctor() {
|
|
|
26019
25908
|
log(color.green(" \u2713") + ` ${moduleCount} module${moduleCount !== 1 ? "s" : ""} installed`);
|
|
26020
25909
|
for (const [name, info] of Object.entries(manifest)) {
|
|
26021
25910
|
const modDir = getModulePath(name);
|
|
26022
|
-
const pkgPath =
|
|
26023
|
-
if (!
|
|
25911
|
+
const pkgPath = join13(modDir, "package.json");
|
|
25912
|
+
if (!existsSync12(modDir)) {
|
|
26024
25913
|
log(color.red(" \u2717") + ` ${name}: directory missing`);
|
|
26025
25914
|
issues++;
|
|
26026
|
-
} else if (!
|
|
25915
|
+
} else if (!existsSync12(pkgPath)) {
|
|
26027
25916
|
log(color.red(" \u2717") + ` ${name}: package.json missing`);
|
|
26028
25917
|
issues++;
|
|
26029
25918
|
} else {
|
|
26030
25919
|
let entryPoint = "dist/index.js";
|
|
26031
25920
|
try {
|
|
26032
|
-
const pkg = JSON.parse(
|
|
25921
|
+
const pkg = JSON.parse(readFileSync11(pkgPath, "utf-8"));
|
|
26033
25922
|
if (pkg.main) entryPoint = pkg.main;
|
|
26034
25923
|
} catch {
|
|
26035
25924
|
}
|
|
26036
|
-
if (!
|
|
25925
|
+
if (!existsSync12(join13(modDir, entryPoint))) {
|
|
26037
25926
|
log(color.red(" \u2717") + ` ${name}: entry point ${entryPoint} missing`);
|
|
26038
25927
|
issues++;
|
|
26039
25928
|
}
|
|
@@ -26043,9 +25932,9 @@ async function handleDoctor() {
|
|
|
26043
25932
|
log(color.dim(" -") + ` No modules installed`);
|
|
26044
25933
|
}
|
|
26045
25934
|
const projectFile = resolve9("robinpath.json");
|
|
26046
|
-
if (
|
|
25935
|
+
if (existsSync12(projectFile)) {
|
|
26047
25936
|
try {
|
|
26048
|
-
const config = JSON.parse(
|
|
25937
|
+
const config = JSON.parse(readFileSync11(projectFile, "utf-8"));
|
|
26049
25938
|
log(color.green(" \u2713") + ` Project: ${config.name || "unnamed"} v${config.version || "?"}`);
|
|
26050
25939
|
const projectModules = Object.keys(config.modules || {});
|
|
26051
25940
|
for (const mod of projectModules) {
|
|
@@ -26059,12 +25948,12 @@ async function handleDoctor() {
|
|
|
26059
25948
|
issues++;
|
|
26060
25949
|
}
|
|
26061
25950
|
}
|
|
26062
|
-
if (
|
|
25951
|
+
if (existsSync12(CACHE_DIR)) {
|
|
26063
25952
|
try {
|
|
26064
|
-
const cacheFiles =
|
|
25953
|
+
const cacheFiles = readdirSync7(CACHE_DIR);
|
|
26065
25954
|
const cacheSize = cacheFiles.reduce((total, f) => {
|
|
26066
25955
|
try {
|
|
26067
|
-
return total +
|
|
25956
|
+
return total + statSync7(join13(CACHE_DIR, f)).size;
|
|
26068
25957
|
} catch {
|
|
26069
25958
|
return total;
|
|
26070
25959
|
}
|
|
@@ -26082,12 +25971,12 @@ async function handleDoctor() {
|
|
|
26082
25971
|
log("");
|
|
26083
25972
|
}
|
|
26084
25973
|
async function handleEnv(args) {
|
|
26085
|
-
const envPath =
|
|
25974
|
+
const envPath = join13(getRobinPathHome(), "env");
|
|
26086
25975
|
const sub = args[0];
|
|
26087
25976
|
function readEnvFile() {
|
|
26088
25977
|
try {
|
|
26089
|
-
if (!
|
|
26090
|
-
const lines =
|
|
25978
|
+
if (!existsSync12(envPath)) return {};
|
|
25979
|
+
const lines = readFileSync11(envPath, "utf-8").split("\n");
|
|
26091
25980
|
const env = {};
|
|
26092
25981
|
for (const line of lines) {
|
|
26093
25982
|
const trimmed = line.trim();
|
|
@@ -26104,7 +25993,7 @@ async function handleEnv(args) {
|
|
|
26104
25993
|
}
|
|
26105
25994
|
function writeEnvFile(env) {
|
|
26106
25995
|
const dir = getRobinPathHome();
|
|
26107
|
-
if (!
|
|
25996
|
+
if (!existsSync12(dir)) mkdirSync7(dir, { recursive: true });
|
|
26108
25997
|
const content = Object.entries(env).map(([k2, v]) => `${k2}=${v}`).join("\n") + "\n";
|
|
26109
25998
|
writeFileSync7(envPath, content, "utf-8");
|
|
26110
25999
|
if (platform9() !== "win32") {
|
|
@@ -26168,12 +26057,12 @@ async function handleEnv(args) {
|
|
|
26168
26057
|
async function handleCache(args) {
|
|
26169
26058
|
const sub = args[0];
|
|
26170
26059
|
if (sub === "list") {
|
|
26171
|
-
if (!
|
|
26060
|
+
if (!existsSync12(CACHE_DIR)) {
|
|
26172
26061
|
log("Cache is empty.");
|
|
26173
26062
|
return;
|
|
26174
26063
|
}
|
|
26175
26064
|
try {
|
|
26176
|
-
const files =
|
|
26065
|
+
const files = readdirSync7(CACHE_DIR);
|
|
26177
26066
|
if (files.length === 0) {
|
|
26178
26067
|
log("Cache is empty.");
|
|
26179
26068
|
return;
|
|
@@ -26183,7 +26072,7 @@ async function handleCache(args) {
|
|
|
26183
26072
|
log(color.dim(" " + "\u2500".repeat(50)));
|
|
26184
26073
|
let totalSize = 0;
|
|
26185
26074
|
for (const file of files) {
|
|
26186
|
-
const size =
|
|
26075
|
+
const size = statSync7(join13(CACHE_DIR, file)).size;
|
|
26187
26076
|
totalSize += size;
|
|
26188
26077
|
log(` ${file.padEnd(45)} ${color.dim((size / 1024).toFixed(1) + "KB")}`);
|
|
26189
26078
|
}
|
|
@@ -26199,15 +26088,15 @@ async function handleCache(args) {
|
|
|
26199
26088
|
process.exit(1);
|
|
26200
26089
|
}
|
|
26201
26090
|
} else if (sub === "clean") {
|
|
26202
|
-
if (!
|
|
26091
|
+
if (!existsSync12(CACHE_DIR)) {
|
|
26203
26092
|
log("Cache is already empty.");
|
|
26204
26093
|
return;
|
|
26205
26094
|
}
|
|
26206
26095
|
try {
|
|
26207
|
-
const files =
|
|
26096
|
+
const files = readdirSync7(CACHE_DIR);
|
|
26208
26097
|
let totalSize = 0;
|
|
26209
26098
|
for (const file of files) {
|
|
26210
|
-
totalSize +=
|
|
26099
|
+
totalSize += statSync7(join13(CACHE_DIR, file)).size;
|
|
26211
26100
|
}
|
|
26212
26101
|
rmSync3(CACHE_DIR, { recursive: true, force: true });
|
|
26213
26102
|
log(
|
|
@@ -26322,8 +26211,8 @@ async function handleDeprecate(args) {
|
|
|
26322
26211
|
}
|
|
26323
26212
|
|
|
26324
26213
|
// src/commands-snippets.ts
|
|
26325
|
-
import { readFileSync as
|
|
26326
|
-
import { resolve as resolve10, basename as basename6, extname as extname4, join as
|
|
26214
|
+
import { readFileSync as readFileSync12, existsSync as existsSync13, mkdirSync as mkdirSync8, writeFileSync as writeFileSync8 } from "node:fs";
|
|
26215
|
+
import { resolve as resolve10, basename as basename6, extname as extname4, join as join14 } from "node:path";
|
|
26327
26216
|
import { homedir as homedir10, platform as platform10 } from "node:os";
|
|
26328
26217
|
import { createInterface as createInterface5 } from "node:readline";
|
|
26329
26218
|
var PLATFORM_URL4 = process.env.ROBINPATH_PLATFORM_URL || "https://api.robinpath.com";
|
|
@@ -26559,11 +26448,11 @@ async function snippetCreate(args) {
|
|
|
26559
26448
|
defaultName = "untitled";
|
|
26560
26449
|
} else {
|
|
26561
26450
|
const filePath = resolve10(fileArg);
|
|
26562
|
-
if (!
|
|
26451
|
+
if (!existsSync13(filePath)) {
|
|
26563
26452
|
console.error(color.red("Error:") + ` File not found: ${fileArg}`);
|
|
26564
26453
|
process.exit(1);
|
|
26565
26454
|
}
|
|
26566
|
-
code =
|
|
26455
|
+
code = readFileSync12(filePath, "utf-8");
|
|
26567
26456
|
defaultName = basename6(filePath, extname4(filePath));
|
|
26568
26457
|
}
|
|
26569
26458
|
if (!code || !code.trim()) {
|
|
@@ -26585,8 +26474,8 @@ async function snippetCreate(args) {
|
|
|
26585
26474
|
if (flags.version) payload.version = flags.version;
|
|
26586
26475
|
if (flags.readme) {
|
|
26587
26476
|
const readmePath = resolve10(flags.readme);
|
|
26588
|
-
if (
|
|
26589
|
-
payload.readme =
|
|
26477
|
+
if (existsSync13(readmePath)) {
|
|
26478
|
+
payload.readme = readFileSync12(readmePath, "utf-8");
|
|
26590
26479
|
}
|
|
26591
26480
|
}
|
|
26592
26481
|
try {
|
|
@@ -26669,12 +26558,12 @@ async function snippetInit(args) {
|
|
|
26669
26558
|
code = codeLines.join("\n");
|
|
26670
26559
|
} else {
|
|
26671
26560
|
const filePath = await ask("File path", "");
|
|
26672
|
-
if (!filePath || !
|
|
26561
|
+
if (!filePath || !existsSync13(resolve10(filePath))) {
|
|
26673
26562
|
console.error(color.red("Error:") + " File not found.");
|
|
26674
26563
|
rl.close();
|
|
26675
26564
|
process.exit(1);
|
|
26676
26565
|
}
|
|
26677
|
-
code =
|
|
26566
|
+
code = readFileSync12(resolve10(filePath), "utf-8");
|
|
26678
26567
|
}
|
|
26679
26568
|
rl.close();
|
|
26680
26569
|
if (!code.trim()) {
|
|
@@ -26831,16 +26720,16 @@ async function snippetUpdate(args) {
|
|
|
26831
26720
|
payload.tags = flags.tags.split(",").map((t) => t.trim()).filter(Boolean);
|
|
26832
26721
|
if (flags.code) {
|
|
26833
26722
|
const codePath = resolve10(flags.code);
|
|
26834
|
-
if (!
|
|
26723
|
+
if (!existsSync13(codePath)) {
|
|
26835
26724
|
console.error(color.red("Error:") + ` Code file not found: ${flags.code}`);
|
|
26836
26725
|
process.exit(1);
|
|
26837
26726
|
}
|
|
26838
|
-
payload.code =
|
|
26727
|
+
payload.code = readFileSync12(codePath, "utf-8");
|
|
26839
26728
|
}
|
|
26840
26729
|
if (flags.readme) {
|
|
26841
26730
|
const readmePath = resolve10(flags.readme);
|
|
26842
|
-
if (
|
|
26843
|
-
payload.readme =
|
|
26731
|
+
if (existsSync13(readmePath)) {
|
|
26732
|
+
payload.readme = readFileSync12(readmePath, "utf-8");
|
|
26844
26733
|
}
|
|
26845
26734
|
}
|
|
26846
26735
|
if (Object.keys(payload).length === 0) {
|
|
@@ -27216,16 +27105,16 @@ async function snippetCopy(args) {
|
|
|
27216
27105
|
process.exit(1);
|
|
27217
27106
|
}
|
|
27218
27107
|
}
|
|
27219
|
-
var SNIPPET_CACHE_DIR =
|
|
27108
|
+
var SNIPPET_CACHE_DIR = join14(homedir10(), ".robinpath", "cache", "snippets");
|
|
27220
27109
|
var SNIPPET_CACHE_TTL = 5 * 60 * 1e3;
|
|
27221
27110
|
function getSnippetCachePath(id) {
|
|
27222
|
-
return
|
|
27111
|
+
return join14(SNIPPET_CACHE_DIR, `${id}.json`);
|
|
27223
27112
|
}
|
|
27224
27113
|
function readSnippetCache(id) {
|
|
27225
27114
|
try {
|
|
27226
27115
|
const cachePath = getSnippetCachePath(id);
|
|
27227
|
-
if (!
|
|
27228
|
-
const raw = JSON.parse(
|
|
27116
|
+
if (!existsSync13(cachePath)) return null;
|
|
27117
|
+
const raw = JSON.parse(readFileSync12(cachePath, "utf-8"));
|
|
27229
27118
|
if (Date.now() - (raw._cachedAt || 0) > SNIPPET_CACHE_TTL) return null;
|
|
27230
27119
|
return raw;
|
|
27231
27120
|
} catch {
|
|
@@ -27234,7 +27123,7 @@ function readSnippetCache(id) {
|
|
|
27234
27123
|
}
|
|
27235
27124
|
function writeSnippetCache(id, data) {
|
|
27236
27125
|
try {
|
|
27237
|
-
if (!
|
|
27126
|
+
if (!existsSync13(SNIPPET_CACHE_DIR)) {
|
|
27238
27127
|
mkdirSync8(SNIPPET_CACHE_DIR, { recursive: true });
|
|
27239
27128
|
}
|
|
27240
27129
|
writeFileSync8(getSnippetCachePath(id), JSON.stringify({ ...data, _cachedAt: Date.now() }), "utf-8");
|
|
@@ -27348,11 +27237,11 @@ async function snippetPush(args) {
|
|
|
27348
27237
|
}
|
|
27349
27238
|
id = await resolveSnippetId(id);
|
|
27350
27239
|
const filePath = resolve10(fileArg);
|
|
27351
|
-
if (!
|
|
27240
|
+
if (!existsSync13(filePath)) {
|
|
27352
27241
|
console.error(color.red("Error:") + ` File not found: ${fileArg}`);
|
|
27353
27242
|
process.exit(1);
|
|
27354
27243
|
}
|
|
27355
|
-
const code =
|
|
27244
|
+
const code = readFileSync12(filePath, "utf-8");
|
|
27356
27245
|
if (!code.trim()) {
|
|
27357
27246
|
console.error(color.red("Error:") + " File is empty.");
|
|
27358
27247
|
process.exit(1);
|
|
@@ -27436,11 +27325,11 @@ async function snippetDiff(args) {
|
|
|
27436
27325
|
}
|
|
27437
27326
|
id = await resolveSnippetId(id);
|
|
27438
27327
|
const filePath = resolve10(fileArg);
|
|
27439
|
-
if (!
|
|
27328
|
+
if (!existsSync13(filePath)) {
|
|
27440
27329
|
console.error(color.red("Error:") + ` File not found: ${fileArg}`);
|
|
27441
27330
|
process.exit(1);
|
|
27442
27331
|
}
|
|
27443
|
-
const localCode =
|
|
27332
|
+
const localCode = readFileSync12(filePath, "utf-8");
|
|
27444
27333
|
try {
|
|
27445
27334
|
const res = await fetchSnippet(id);
|
|
27446
27335
|
if (!res.ok) {
|
|
@@ -27560,13 +27449,13 @@ async function snippetImport(args) {
|
|
|
27560
27449
|
process.exit(2);
|
|
27561
27450
|
}
|
|
27562
27451
|
const filePath = resolve10(fileArg);
|
|
27563
|
-
if (!
|
|
27452
|
+
if (!existsSync13(filePath)) {
|
|
27564
27453
|
console.error(color.red("Error:") + ` File not found: ${fileArg}`);
|
|
27565
27454
|
process.exit(1);
|
|
27566
27455
|
}
|
|
27567
27456
|
let importData;
|
|
27568
27457
|
try {
|
|
27569
|
-
importData = JSON.parse(
|
|
27458
|
+
importData = JSON.parse(readFileSync12(filePath, "utf-8"));
|
|
27570
27459
|
} catch {
|
|
27571
27460
|
console.error(color.red("Error:") + " Invalid JSON file.");
|
|
27572
27461
|
process.exit(1);
|
|
@@ -27633,8 +27522,8 @@ async function snippetImport(args) {
|
|
|
27633
27522
|
|
|
27634
27523
|
// src/commands-cloud.ts
|
|
27635
27524
|
import { createServer as createServer4 } from "node:http";
|
|
27636
|
-
import { readFileSync as
|
|
27637
|
-
import { resolve as resolve11, join as
|
|
27525
|
+
import { readFileSync as readFileSync13, writeFileSync as writeFileSync9, unlinkSync as unlinkSync6, existsSync as existsSync14 } from "node:fs";
|
|
27526
|
+
import { resolve as resolve11, join as join15, dirname as dirname5, basename as basename7 } from "node:path";
|
|
27638
27527
|
import { execSync as execSync3 } from "node:child_process";
|
|
27639
27528
|
import { tmpdir as tmpdir4, hostname as hostname3 } from "node:os";
|
|
27640
27529
|
var CLOUD_URL2 = process.env.ROBINPATH_CLOUD_URL || "https://dev.robinpath.com";
|
|
@@ -27770,14 +27659,14 @@ async function handlePublish(args) {
|
|
|
27770
27659
|
const isDryRun = args.includes("--dry-run");
|
|
27771
27660
|
const targetArg = args.find((a) => !a.startsWith("-") && !a.startsWith("--org")) || ".";
|
|
27772
27661
|
const targetDir = resolve11(targetArg);
|
|
27773
|
-
const pkgPath =
|
|
27774
|
-
if (!
|
|
27662
|
+
const pkgPath = join15(targetDir, "package.json");
|
|
27663
|
+
if (!existsSync14(pkgPath)) {
|
|
27775
27664
|
console.error(color.red("Error:") + ` No package.json found in ${targetDir}`);
|
|
27776
27665
|
process.exit(2);
|
|
27777
27666
|
}
|
|
27778
27667
|
let pkg;
|
|
27779
27668
|
try {
|
|
27780
|
-
pkg = JSON.parse(
|
|
27669
|
+
pkg = JSON.parse(readFileSync13(pkgPath, "utf-8"));
|
|
27781
27670
|
} catch (err) {
|
|
27782
27671
|
console.error(color.red("Error:") + ` Invalid package.json: ${err.message}`);
|
|
27783
27672
|
process.exit(2);
|
|
@@ -27821,7 +27710,7 @@ async function handlePublish(args) {
|
|
|
27821
27710
|
scope = emailPrefix;
|
|
27822
27711
|
name = pkg.name;
|
|
27823
27712
|
}
|
|
27824
|
-
const tmpFile =
|
|
27713
|
+
const tmpFile = join15(tmpdir4(), `robinpath-publish-${Date.now()}.tar.gz`);
|
|
27825
27714
|
const parentDir = dirname5(targetDir);
|
|
27826
27715
|
const dirName = basename7(targetDir);
|
|
27827
27716
|
log(`Packing @${scope}/${name}@${pkg.version} (${visibility})...`);
|
|
@@ -27838,7 +27727,7 @@ async function handlePublish(args) {
|
|
|
27838
27727
|
console.error(color.red("Error:") + ` Failed to create tarball: ${err.message}`);
|
|
27839
27728
|
process.exit(1);
|
|
27840
27729
|
}
|
|
27841
|
-
const tarball =
|
|
27730
|
+
const tarball = readFileSync13(tmpFile);
|
|
27842
27731
|
const maxSize = 50 * 1024 * 1024;
|
|
27843
27732
|
if (tarball.length > maxSize) {
|
|
27844
27733
|
unlinkSync6(tmpFile);
|
|
@@ -28150,7 +28039,7 @@ async function main() {
|
|
|
28150
28039
|
return;
|
|
28151
28040
|
}
|
|
28152
28041
|
if (command === "install") {
|
|
28153
|
-
|
|
28042
|
+
existsSync15(resolve12("robinpath.json")) ? await handleProjectInstall() : handleInstall();
|
|
28154
28043
|
return;
|
|
28155
28044
|
}
|
|
28156
28045
|
if (command === "uninstall") {
|
|
@@ -28269,7 +28158,7 @@ async function main() {
|
|
|
28269
28158
|
}
|
|
28270
28159
|
process.exit(2);
|
|
28271
28160
|
}
|
|
28272
|
-
const script =
|
|
28161
|
+
const script = readFileSync14(filePath, "utf-8");
|
|
28273
28162
|
const hasWatch = args.includes("--watch");
|
|
28274
28163
|
const hasShortWatch = args.includes("-w") && command !== "fmt";
|
|
28275
28164
|
if (hasWatch || hasShortWatch) {
|