@robinpath/cli 3.2.1 → 3.4.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 +165 -79
- 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.
|
|
18601
|
+
var CLI_VERSION = true ? "3.4.0" : "3.4.0";
|
|
18602
18602
|
var FLAG_QUIET = false;
|
|
18603
18603
|
var FLAG_VERBOSE = false;
|
|
18604
18604
|
var FLAG_AUTO_ACCEPT = false;
|
|
@@ -23016,82 +23016,6 @@ function listReferenceableFiles(cwd, prefix) {
|
|
|
23016
23016
|
}
|
|
23017
23017
|
|
|
23018
23018
|
// src/repl.ts
|
|
23019
|
-
async function welcomeWizard() {
|
|
23020
|
-
log("");
|
|
23021
|
-
log(color.bold(" Welcome to RobinPath AI!"));
|
|
23022
|
-
log(color.dim(" Your AI-powered scripting assistant"));
|
|
23023
|
-
log("");
|
|
23024
|
-
log(color.dim(" An OpenRouter API key is required."));
|
|
23025
|
-
log(color.dim(" Get one at: https://openrouter.ai/keys"));
|
|
23026
|
-
log("");
|
|
23027
|
-
const key = await new Promise((resolve13) => {
|
|
23028
|
-
if (process.stdin.isTTY) {
|
|
23029
|
-
process.stdout.write(color.cyan(" Paste your API key: "));
|
|
23030
|
-
process.stdin.setRawMode(true);
|
|
23031
|
-
process.stdin.resume();
|
|
23032
|
-
let input = "";
|
|
23033
|
-
const onData = (ch) => {
|
|
23034
|
-
const c = ch.toString();
|
|
23035
|
-
if (c === "\n" || c === "\r") {
|
|
23036
|
-
process.stdin.removeListener("data", onData);
|
|
23037
|
-
try {
|
|
23038
|
-
process.stdin.setRawMode(false);
|
|
23039
|
-
} catch {
|
|
23040
|
-
}
|
|
23041
|
-
process.stdin.pause();
|
|
23042
|
-
process.stdout.write("\n");
|
|
23043
|
-
resolve13(input);
|
|
23044
|
-
} else if (c === "") {
|
|
23045
|
-
process.stdin.removeListener("data", onData);
|
|
23046
|
-
try {
|
|
23047
|
-
process.stdin.setRawMode(false);
|
|
23048
|
-
} catch {
|
|
23049
|
-
}
|
|
23050
|
-
process.stdin.pause();
|
|
23051
|
-
resolve13("");
|
|
23052
|
-
} else if (c === "\x7F" || c === "\b") {
|
|
23053
|
-
if (input.length > 0) {
|
|
23054
|
-
input = input.slice(0, -1);
|
|
23055
|
-
process.stdout.write("\b \b");
|
|
23056
|
-
}
|
|
23057
|
-
} else if (c.charCodeAt(0) >= 32) {
|
|
23058
|
-
input += c;
|
|
23059
|
-
process.stdout.write("*");
|
|
23060
|
-
}
|
|
23061
|
-
};
|
|
23062
|
-
process.stdin.on("data", onData);
|
|
23063
|
-
} else {
|
|
23064
|
-
const rl2 = createInterface2({ input: process.stdin, output: process.stdout });
|
|
23065
|
-
rl2.question(" Paste your API key: ", (answer) => {
|
|
23066
|
-
rl2.close();
|
|
23067
|
-
resolve13(answer.trim());
|
|
23068
|
-
});
|
|
23069
|
-
}
|
|
23070
|
-
});
|
|
23071
|
-
if (!key || !key.trim()) {
|
|
23072
|
-
log(color.red(" An OpenRouter API key is required to use RobinPath AI."));
|
|
23073
|
-
log(color.dim(` Set one with: ${color.cyan("robinpath ai config set-key <api-key>")}`));
|
|
23074
|
-
return;
|
|
23075
|
-
}
|
|
23076
|
-
const k2 = key.trim();
|
|
23077
|
-
const config = { apiKey: k2 };
|
|
23078
|
-
if (k2.startsWith("sk-or-")) config.provider = "openrouter";
|
|
23079
|
-
else if (k2.startsWith("sk-ant-")) config.provider = "anthropic";
|
|
23080
|
-
else if (k2.startsWith("sk-")) config.provider = "openai";
|
|
23081
|
-
else config.provider = "openrouter";
|
|
23082
|
-
config.model = "anthropic/claude-sonnet-4.6";
|
|
23083
|
-
writeAiConfig(config);
|
|
23084
|
-
log(color.green(" \u2713 API key saved"));
|
|
23085
|
-
log(` Provider: ${color.cyan(config.provider)} (auto-detected)`);
|
|
23086
|
-
log("");
|
|
23087
|
-
const picked2 = await selectModelInteractive(config.model);
|
|
23088
|
-
if (picked2) {
|
|
23089
|
-
config.model = picked2;
|
|
23090
|
-
writeAiConfig(config);
|
|
23091
|
-
}
|
|
23092
|
-
log(color.green(` \u2713 Model: ${color.cyan(config.model)}`));
|
|
23093
|
-
log("");
|
|
23094
|
-
}
|
|
23095
23019
|
async function handleAiConfig(args) {
|
|
23096
23020
|
const sub = args[0];
|
|
23097
23021
|
if (sub === "set-key") {
|
|
@@ -28797,9 +28721,171 @@ async function main() {
|
|
|
28797
28721
|
return;
|
|
28798
28722
|
}
|
|
28799
28723
|
checkForUpdates();
|
|
28724
|
+
const auth = readAuth();
|
|
28725
|
+
if (!auth && process.stdin.isTTY) {
|
|
28726
|
+
console.log("");
|
|
28727
|
+
console.log(color.bold(" Welcome to RobinPath!"));
|
|
28728
|
+
console.log("");
|
|
28729
|
+
console.log(" To unlock AI assistant, deploy, snippets, and sync \u2014");
|
|
28730
|
+
console.log(" please login to your RobinPath account.");
|
|
28731
|
+
console.log("");
|
|
28732
|
+
console.log(" Without login you can still:");
|
|
28733
|
+
console.log(` ${color.dim("\u2022")} Run scripts: ${color.cyan("robinpath script.rp")}`);
|
|
28734
|
+
console.log(` ${color.dim("\u2022")} Format code: ${color.cyan("robinpath fmt file.rp")}`);
|
|
28735
|
+
console.log(` ${color.dim("\u2022")} Run tests: ${color.cyan("robinpath test")}`);
|
|
28736
|
+
console.log(` ${color.dim("\u2022")} Install modules: ${color.cyan("robinpath add @robinpath/csv")}`);
|
|
28737
|
+
console.log("");
|
|
28738
|
+
const choice = await new Promise((resolve13) => {
|
|
28739
|
+
if (!process.stdin.isTTY) {
|
|
28740
|
+
resolve13("skip");
|
|
28741
|
+
return;
|
|
28742
|
+
}
|
|
28743
|
+
let selected = 0;
|
|
28744
|
+
const options = ["Login", "Skip for now"];
|
|
28745
|
+
function render2() {
|
|
28746
|
+
process.stdout.write("\x1B[2K\r");
|
|
28747
|
+
for (let i = 0; i < options.length; i++) {
|
|
28748
|
+
if (i > 0) process.stdout.write("\n\x1B[2K");
|
|
28749
|
+
const marker = i === selected ? color.cyan(" \u276F ") : " ";
|
|
28750
|
+
const text = i === selected ? color.bold(options[i]) : options[i];
|
|
28751
|
+
process.stdout.write(`${marker}${text}`);
|
|
28752
|
+
}
|
|
28753
|
+
if (options.length > 1) process.stdout.write(`\x1B[${options.length - 1}A`);
|
|
28754
|
+
process.stdout.write("\r");
|
|
28755
|
+
}
|
|
28756
|
+
render2();
|
|
28757
|
+
process.stdin.setRawMode(true);
|
|
28758
|
+
process.stdin.resume();
|
|
28759
|
+
const onKey = (buf) => {
|
|
28760
|
+
const key = buf.toString();
|
|
28761
|
+
if (key === "\x1B[A") {
|
|
28762
|
+
selected = 0;
|
|
28763
|
+
render2();
|
|
28764
|
+
return;
|
|
28765
|
+
}
|
|
28766
|
+
if (key === "\x1B[B") {
|
|
28767
|
+
selected = 1;
|
|
28768
|
+
render2();
|
|
28769
|
+
return;
|
|
28770
|
+
}
|
|
28771
|
+
if (key === "\r" || key === "\n") {
|
|
28772
|
+
process.stdin.removeListener("data", onKey);
|
|
28773
|
+
try {
|
|
28774
|
+
process.stdin.setRawMode(false);
|
|
28775
|
+
} catch {
|
|
28776
|
+
}
|
|
28777
|
+
process.stdin.pause();
|
|
28778
|
+
process.stdout.write("\n".repeat(options.length));
|
|
28779
|
+
resolve13(selected === 0 ? "login" : "skip");
|
|
28780
|
+
return;
|
|
28781
|
+
}
|
|
28782
|
+
if (key === "\x1B" || key === "") {
|
|
28783
|
+
process.stdin.removeListener("data", onKey);
|
|
28784
|
+
try {
|
|
28785
|
+
process.stdin.setRawMode(false);
|
|
28786
|
+
} catch {
|
|
28787
|
+
}
|
|
28788
|
+
process.stdin.pause();
|
|
28789
|
+
process.stdout.write("\n".repeat(options.length));
|
|
28790
|
+
resolve13("skip");
|
|
28791
|
+
return;
|
|
28792
|
+
}
|
|
28793
|
+
};
|
|
28794
|
+
process.stdin.on("data", onKey);
|
|
28795
|
+
});
|
|
28796
|
+
if (choice === "login") {
|
|
28797
|
+
await handleLogin();
|
|
28798
|
+
} else {
|
|
28799
|
+
console.log(color.dim(" Skipped. Run ") + color.cyan("robinpath login") + color.dim(" anytime to unlock AI features."));
|
|
28800
|
+
console.log("");
|
|
28801
|
+
return;
|
|
28802
|
+
}
|
|
28803
|
+
}
|
|
28800
28804
|
const existingConfig = readAiConfig();
|
|
28801
|
-
if (
|
|
28802
|
-
|
|
28805
|
+
if (!existingConfig.apiKey && process.stdin.isTTY) {
|
|
28806
|
+
console.log("");
|
|
28807
|
+
console.log(color.green(" \u2713 Logged in successfully!"));
|
|
28808
|
+
console.log("");
|
|
28809
|
+
console.log(" To explore the AI assistant and agent coding,");
|
|
28810
|
+
console.log(" connect your OpenRouter API key:");
|
|
28811
|
+
console.log("");
|
|
28812
|
+
console.log(color.bold(" Step 1:") + " Go to " + color.cyan("https://openrouter.ai/keys"));
|
|
28813
|
+
console.log(color.bold(" Step 2:") + ' Click "Create Key" and copy it');
|
|
28814
|
+
console.log(color.bold(" Step 3:") + " Run this command:");
|
|
28815
|
+
console.log("");
|
|
28816
|
+
console.log(" " + color.cyan(color.bold("robinpath ai config set-key sk-or-...")));
|
|
28817
|
+
console.log("");
|
|
28818
|
+
const ready = await new Promise((resolve13) => {
|
|
28819
|
+
if (!process.stdin.isTTY) {
|
|
28820
|
+
resolve13("later");
|
|
28821
|
+
return;
|
|
28822
|
+
}
|
|
28823
|
+
let selected = 0;
|
|
28824
|
+
const options = ["Yes, I'm ready", "Maybe later"];
|
|
28825
|
+
function render2() {
|
|
28826
|
+
process.stdout.write("\x1B[2K\r");
|
|
28827
|
+
for (let i = 0; i < options.length; i++) {
|
|
28828
|
+
if (i > 0) process.stdout.write("\n\x1B[2K");
|
|
28829
|
+
const marker = i === selected ? color.cyan(" \u276F ") : " ";
|
|
28830
|
+
const text = i === selected ? color.bold(options[i]) : options[i];
|
|
28831
|
+
process.stdout.write(`${marker}${text}`);
|
|
28832
|
+
}
|
|
28833
|
+
if (options.length > 1) process.stdout.write(`\x1B[${options.length - 1}A`);
|
|
28834
|
+
process.stdout.write("\r");
|
|
28835
|
+
}
|
|
28836
|
+
render2();
|
|
28837
|
+
process.stdin.setRawMode(true);
|
|
28838
|
+
process.stdin.resume();
|
|
28839
|
+
const onKey = (buf) => {
|
|
28840
|
+
const key = buf.toString();
|
|
28841
|
+
if (key === "\x1B[A") {
|
|
28842
|
+
selected = 0;
|
|
28843
|
+
render2();
|
|
28844
|
+
return;
|
|
28845
|
+
}
|
|
28846
|
+
if (key === "\x1B[B") {
|
|
28847
|
+
selected = 1;
|
|
28848
|
+
render2();
|
|
28849
|
+
return;
|
|
28850
|
+
}
|
|
28851
|
+
if (key === "\r" || key === "\n") {
|
|
28852
|
+
process.stdin.removeListener("data", onKey);
|
|
28853
|
+
try {
|
|
28854
|
+
process.stdin.setRawMode(false);
|
|
28855
|
+
} catch {
|
|
28856
|
+
}
|
|
28857
|
+
process.stdin.pause();
|
|
28858
|
+
process.stdout.write("\n".repeat(options.length));
|
|
28859
|
+
resolve13(selected === 0 ? "ready" : "later");
|
|
28860
|
+
return;
|
|
28861
|
+
}
|
|
28862
|
+
if (key === "\x1B" || key === "") {
|
|
28863
|
+
process.stdin.removeListener("data", onKey);
|
|
28864
|
+
try {
|
|
28865
|
+
process.stdin.setRawMode(false);
|
|
28866
|
+
} catch {
|
|
28867
|
+
}
|
|
28868
|
+
process.stdin.pause();
|
|
28869
|
+
process.stdout.write("\n".repeat(options.length));
|
|
28870
|
+
resolve13("later");
|
|
28871
|
+
return;
|
|
28872
|
+
}
|
|
28873
|
+
};
|
|
28874
|
+
process.stdin.on("data", onKey);
|
|
28875
|
+
});
|
|
28876
|
+
console.log("");
|
|
28877
|
+
if (ready === "ready") {
|
|
28878
|
+
console.log(" Copy and paste this command in your terminal:");
|
|
28879
|
+
console.log("");
|
|
28880
|
+
console.log(" " + color.cyan(color.bold("robinpath ai config set-key")) + color.dim(" <paste-your-key-here>"));
|
|
28881
|
+
console.log("");
|
|
28882
|
+
console.log(color.dim(" After setting the key, run ") + color.cyan("robinpath") + color.dim(" to start the AI assistant."));
|
|
28883
|
+
} else {
|
|
28884
|
+
console.log(color.dim(" No problem! When you're ready, run:"));
|
|
28885
|
+
console.log(" " + color.cyan("robinpath ai config set-key") + color.dim(" <your-openrouter-key>"));
|
|
28886
|
+
}
|
|
28887
|
+
console.log("");
|
|
28888
|
+
return;
|
|
28803
28889
|
}
|
|
28804
28890
|
await startInkOrFallback(null, null, { autoAccept: FLAG_AUTO_ACCEPT, devMode: FLAG_DEV_MODE });
|
|
28805
28891
|
}
|