@robinpath/cli 3.0.2 → 3.2.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 +85 -18
- 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 ? "3.0
|
|
18601
|
+
var CLI_VERSION = true ? "3.2.0" : "3.2.0";
|
|
18602
18602
|
var FLAG_QUIET = false;
|
|
18603
18603
|
var FLAG_VERBOSE = false;
|
|
18604
18604
|
var FLAG_AUTO_ACCEPT = false;
|
|
@@ -20076,9 +20076,7 @@ async function loadInstalledModules(rp2) {
|
|
|
20076
20076
|
}
|
|
20077
20077
|
if (FLAG_VERBOSE) logVerbose(`Loaded module: ${packageName}@${info.version}`);
|
|
20078
20078
|
} catch (err) {
|
|
20079
|
-
|
|
20080
|
-
color.yellow("Warning:") + ` Failed to load module ${packageName}: ${err.message}`
|
|
20081
|
-
);
|
|
20079
|
+
logVerbose(`Failed to load module ${packageName}: ${err.message}`);
|
|
20082
20080
|
}
|
|
20083
20081
|
}
|
|
20084
20082
|
}
|
|
@@ -24141,6 +24139,7 @@ import { render, Box as Box2, Text as Text2, useInput, useApp } from "ink";
|
|
|
24141
24139
|
import InkSpinner from "ink-spinner";
|
|
24142
24140
|
|
|
24143
24141
|
// src/ui/Markdown.tsx
|
|
24142
|
+
import React from "react";
|
|
24144
24143
|
import { Box, Text } from "ink";
|
|
24145
24144
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
24146
24145
|
function parseBlocks(text) {
|
|
@@ -24187,11 +24186,42 @@ function renderInlineMarkdown(line) {
|
|
|
24187
24186
|
}
|
|
24188
24187
|
return parts;
|
|
24189
24188
|
}
|
|
24189
|
+
function renderTable(tableLines) {
|
|
24190
|
+
const rows = tableLines.filter((l) => !l.match(/^\s*\|[-:\s|]+\|\s*$/)).map((l) => l.split("|").slice(1, -1).map((cell) => cell.trim()));
|
|
24191
|
+
if (rows.length === 0) return null;
|
|
24192
|
+
const colCount = rows[0].length;
|
|
24193
|
+
const widths = Array(colCount).fill(0);
|
|
24194
|
+
for (const row of rows) {
|
|
24195
|
+
for (let c = 0; c < Math.min(row.length, colCount); c++) {
|
|
24196
|
+
widths[c] = Math.max(widths[c], row[c].length);
|
|
24197
|
+
}
|
|
24198
|
+
}
|
|
24199
|
+
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginY: 1, children: rows.map((row, ri) => /* @__PURE__ */ jsxs(Text, { bold: ri === 0, dimColor: ri === 0, children: [
|
|
24200
|
+
" ",
|
|
24201
|
+
row.map((cell, ci) => cell.padEnd(widths[ci] || 0) + " ").join("")
|
|
24202
|
+
] }, ri)) });
|
|
24203
|
+
}
|
|
24190
24204
|
function TextBlock({ content }) {
|
|
24191
24205
|
const lines = content.split("\n");
|
|
24192
|
-
|
|
24206
|
+
const rendered = [];
|
|
24207
|
+
let i = 0;
|
|
24208
|
+
while (i < lines.length) {
|
|
24209
|
+
if (lines[i].trim().startsWith("|") && lines[i].trim().endsWith("|")) {
|
|
24210
|
+
const tableStart = i;
|
|
24211
|
+
while (i < lines.length && lines[i].trim().startsWith("|")) i++;
|
|
24212
|
+
if (i - tableStart >= 2) {
|
|
24213
|
+
rendered.push(/* @__PURE__ */ jsx(React.Fragment, { children: renderTable(lines.slice(tableStart, i)) }, tableStart));
|
|
24214
|
+
continue;
|
|
24215
|
+
}
|
|
24216
|
+
i = tableStart;
|
|
24217
|
+
}
|
|
24218
|
+
rendered.push(/* @__PURE__ */ jsx(React.Fragment, { children: renderTextLine(lines[i], i) }, i));
|
|
24219
|
+
i++;
|
|
24220
|
+
}
|
|
24221
|
+
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: rendered });
|
|
24222
|
+
function renderTextLine(line, idx) {
|
|
24193
24223
|
const trimmed = line.trimStart();
|
|
24194
|
-
if (!trimmed) return /* @__PURE__ */ jsx(Text, { children: " " },
|
|
24224
|
+
if (!trimmed) return /* @__PURE__ */ jsx(Text, { children: " " }, idx);
|
|
24195
24225
|
if (trimmed.startsWith("## ")) {
|
|
24196
24226
|
return /* @__PURE__ */ jsx(Text, { bold: true, children: trimmed.slice(3) }, i);
|
|
24197
24227
|
}
|
|
@@ -24215,8 +24245,8 @@ function TextBlock({ content }) {
|
|
|
24215
24245
|
renderInlineMarkdown(trimmed.slice(numMatch[0].length))
|
|
24216
24246
|
] }, i);
|
|
24217
24247
|
}
|
|
24218
|
-
return /* @__PURE__ */ jsx(Text, { wrap: "wrap", children: renderInlineMarkdown(line) },
|
|
24219
|
-
}
|
|
24248
|
+
return /* @__PURE__ */ jsx(Text, { wrap: "wrap", children: renderInlineMarkdown(line) }, idx);
|
|
24249
|
+
}
|
|
24220
24250
|
}
|
|
24221
24251
|
function CodeBlock({ content, lang }) {
|
|
24222
24252
|
const allLines = content.split("\n");
|
|
@@ -24277,12 +24307,14 @@ var COMMANDS = {
|
|
|
24277
24307
|
"/forget": "Remove a memory",
|
|
24278
24308
|
"/usage": "Token usage & cost",
|
|
24279
24309
|
"/shell": "Switch shell",
|
|
24310
|
+
"/init": "Create ROBINPATH.md",
|
|
24280
24311
|
"/help": "All commands"
|
|
24281
24312
|
};
|
|
24282
24313
|
function InputArea({ onSubmit, placeholder, statusText, history }) {
|
|
24283
24314
|
const [value, setValue] = useState("");
|
|
24284
24315
|
const [historyIdx, setHistoryIdx] = useState(-1);
|
|
24285
24316
|
const [savedInput, setSavedInput] = useState("");
|
|
24317
|
+
const [tabIdx, setTabIdx] = useState(-1);
|
|
24286
24318
|
const { exit } = useApp();
|
|
24287
24319
|
const matchingCommands = useMemo(() => {
|
|
24288
24320
|
if (!value.startsWith("/")) return [];
|
|
@@ -24344,10 +24376,12 @@ function InputArea({ onSubmit, placeholder, statusText, history }) {
|
|
|
24344
24376
|
return;
|
|
24345
24377
|
}
|
|
24346
24378
|
if (showFiles.length > 0) {
|
|
24379
|
+
const nextIdx = (tabIdx + 1) % showFiles.length;
|
|
24380
|
+
setTabIdx(nextIdx);
|
|
24347
24381
|
const atMatch = value.match(/@(\S*)$/);
|
|
24348
24382
|
if (atMatch) {
|
|
24349
24383
|
const before = value.slice(0, value.length - atMatch[0].length);
|
|
24350
|
-
setValue(before + "@" + showFiles[
|
|
24384
|
+
setValue(before + "@" + showFiles[nextIdx].name);
|
|
24351
24385
|
}
|
|
24352
24386
|
}
|
|
24353
24387
|
return;
|
|
@@ -24381,6 +24415,7 @@ function InputArea({ onSubmit, placeholder, statusText, history }) {
|
|
|
24381
24415
|
if (ch && !key.ctrl && !key.meta) {
|
|
24382
24416
|
setValue((p) => p + ch);
|
|
24383
24417
|
setHistoryIdx(-1);
|
|
24418
|
+
setTabIdx(-1);
|
|
24384
24419
|
}
|
|
24385
24420
|
});
|
|
24386
24421
|
const lines = value.split("\n");
|
|
@@ -24422,9 +24457,9 @@ function InputArea({ onSubmit, placeholder, statusText, history }) {
|
|
|
24422
24457
|
] }, i)) }),
|
|
24423
24458
|
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "\u2500".repeat(Math.max(process.stdout.columns || 80, 40)) })
|
|
24424
24459
|
] }),
|
|
24425
|
-
showFiles.length > 0 && /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", paddingX: 2, marginTop: 1, children: showFiles.map((f) => /* @__PURE__ */ jsxs2(Text2, { children: [
|
|
24426
|
-
/* @__PURE__ */ jsx2(Text2, { color: "cyan", children: "+ " }),
|
|
24427
|
-
/* @__PURE__ */ jsx2(Text2, { bold:
|
|
24460
|
+
showFiles.length > 0 && /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", paddingX: 2, marginTop: 1, children: showFiles.map((f, i) => /* @__PURE__ */ jsxs2(Text2, { children: [
|
|
24461
|
+
/* @__PURE__ */ jsx2(Text2, { color: i === tabIdx ? "cyan" : "gray", children: i === tabIdx ? "\u276F " : "+ " }),
|
|
24462
|
+
/* @__PURE__ */ jsx2(Text2, { bold: i === tabIdx, color: i === tabIdx ? "cyan" : void 0, children: f.name }),
|
|
24428
24463
|
f.isDir ? /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "/" }) : null
|
|
24429
24464
|
] }, f.name)) }),
|
|
24430
24465
|
/* @__PURE__ */ jsxs2(Box2, { paddingX: 2, justifyContent: "space-between", children: [
|
|
@@ -24576,6 +24611,7 @@ function ChatApp({ engine }) {
|
|
|
24576
24611
|
const elapsed = Date.now() - startTime;
|
|
24577
24612
|
const timeStr = elapsed < 1e3 ? `${elapsed}ms` : elapsed < 6e4 ? `${(elapsed / 1e3).toFixed(1)}s` : `${Math.floor(elapsed / 6e4)}m ${Math.round(elapsed % 6e4 / 1e3)}s`;
|
|
24578
24613
|
setResponseTime(timeStr);
|
|
24614
|
+
if (elapsed > 1e4) process.stdout.write("\x07");
|
|
24579
24615
|
engine.updateStatus();
|
|
24580
24616
|
}
|
|
24581
24617
|
}, [engine]);
|
|
@@ -24618,6 +24654,11 @@ function ChatApp({ engine }) {
|
|
|
24618
24654
|
] })
|
|
24619
24655
|
] }),
|
|
24620
24656
|
/* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", width: "50%", children: [
|
|
24657
|
+
/* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
24658
|
+
"Run ",
|
|
24659
|
+
/* @__PURE__ */ jsx2(Text2, { color: "cyan", children: "/init" }),
|
|
24660
|
+
" to create ROBINPATH.md"
|
|
24661
|
+
] }),
|
|
24621
24662
|
/* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
24622
24663
|
"Type ",
|
|
24623
24664
|
/* @__PURE__ */ jsx2(Text2, { color: "cyan", children: "/" }),
|
|
@@ -24625,13 +24666,8 @@ function ChatApp({ engine }) {
|
|
|
24625
24666
|
] }),
|
|
24626
24667
|
/* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
24627
24668
|
"Use ",
|
|
24628
|
-
/* @__PURE__ */ jsx2(Text2, { color: "cyan", children: "
|
|
24669
|
+
/* @__PURE__ */ jsx2(Text2, { color: "cyan", children: "@" }),
|
|
24629
24670
|
" to include files"
|
|
24630
|
-
] }),
|
|
24631
|
-
/* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
24632
|
-
"Use ",
|
|
24633
|
-
/* @__PURE__ */ jsx2(Text2, { color: "cyan", children: "\\" }),
|
|
24634
|
-
" for multiline"
|
|
24635
24671
|
] })
|
|
24636
24672
|
] })
|
|
24637
24673
|
] }) : null,
|
|
@@ -24709,6 +24745,20 @@ var ReplEngine = class {
|
|
|
24709
24745
|
nativeModules: getNativeModules().map((m) => m.name),
|
|
24710
24746
|
installedModules: Object.keys(readModulesManifest())
|
|
24711
24747
|
};
|
|
24748
|
+
const projectFiles = ["ROBINPATH.md", "robinpath.md", ".robinpath.md"];
|
|
24749
|
+
for (const pf of projectFiles) {
|
|
24750
|
+
try {
|
|
24751
|
+
const projectPath = join12(process.cwd(), pf);
|
|
24752
|
+
if (existsSync11(projectPath)) {
|
|
24753
|
+
const content = readFileSync10(projectPath, "utf-8").slice(0, 1e4);
|
|
24754
|
+
this.conversationMessages.push({ role: "user", content: `[Project Instructions \u2014 ${pf}]
|
|
24755
|
+
${content}` });
|
|
24756
|
+
this.conversationMessages.push({ role: "assistant", content: "Project instructions loaded." });
|
|
24757
|
+
break;
|
|
24758
|
+
}
|
|
24759
|
+
} catch {
|
|
24760
|
+
}
|
|
24761
|
+
}
|
|
24712
24762
|
const mem = buildMemoryContext();
|
|
24713
24763
|
if (mem.trim()) {
|
|
24714
24764
|
this.conversationMessages.push({ role: "user", content: `[Context] ${mem.trim()}` });
|
|
@@ -24757,6 +24807,23 @@ var ReplEngine = class {
|
|
|
24757
24807
|
this.ui?.clearMessages();
|
|
24758
24808
|
return "";
|
|
24759
24809
|
}
|
|
24810
|
+
if (text === "/init") {
|
|
24811
|
+
const mdPath = join12(process.cwd(), "ROBINPATH.md");
|
|
24812
|
+
if (existsSync11(mdPath)) return "ROBINPATH.md already exists. Edit it to update project instructions.";
|
|
24813
|
+
writeFileSync6(mdPath, `# Project Instructions
|
|
24814
|
+
|
|
24815
|
+
## About
|
|
24816
|
+
Describe your project here.
|
|
24817
|
+
|
|
24818
|
+
## Rules
|
|
24819
|
+
- Use RobinPath scripting language for automation
|
|
24820
|
+
- Follow the project structure
|
|
24821
|
+
|
|
24822
|
+
## Context
|
|
24823
|
+
Any context the AI should know about this project.
|
|
24824
|
+
`);
|
|
24825
|
+
return "\u2713 Created ROBINPATH.md \u2014 edit it to customize AI behavior for this project.";
|
|
24826
|
+
}
|
|
24760
24827
|
if (text === "/compact") {
|
|
24761
24828
|
if (this.conversationMessages.length > 12) {
|
|
24762
24829
|
this.conversationMessages.splice(1, this.conversationMessages.length - 11);
|