@robinpath/cli 1.99.0 → 2.1.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.
Files changed (2) hide show
  1. package/dist/cli.mjs +38 -105
  2. 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.99.0" : "1.99.0";
18601
+ var CLI_VERSION = true ? "2.1.0" : "2.1.0";
18602
18602
  var FLAG_QUIET = false;
18603
18603
  var FLAG_VERBOSE = false;
18604
18604
  var FLAG_AUTO_ACCEPT = false;
@@ -18915,7 +18915,7 @@ async function autoCompact(conversationMessages) {
18915
18915
 
18916
18916
  ${summaryText}`,
18917
18917
  topK: 0,
18918
- model: "robinpath-default"
18918
+ model: "anthropic/claude-sonnet-4.6"
18919
18919
  }),
18920
18920
  signal: AbortSignal.timeout(1e4)
18921
18921
  });
@@ -19706,7 +19706,6 @@ HEADLESS MODE (-p):
19706
19706
  - Piping: robinpath -p "explain this" | less
19707
19707
 
19708
19708
  AVAILABLE MODELS:
19709
- robinpath-default (free, no key needed)
19710
19709
  anthropic/claude-sonnet-4.6 (recommended)
19711
19710
  anthropic/claude-opus-4.6 (most capable)
19712
19711
  anthropic/claude-haiku-4.5 (fastest)
@@ -21863,7 +21862,7 @@ async function fetchBrainContext(prompt) {
21863
21862
  body: JSON.stringify({
21864
21863
  prompt,
21865
21864
  topK: 10,
21866
- model: "robinpath-default"
21865
+ model: "anthropic/claude-sonnet-4.6"
21867
21866
  }),
21868
21867
  signal: AbortSignal.timeout(15e3)
21869
21868
  });
@@ -21895,7 +21894,7 @@ async function fetchBrainStream(prompt, { onToken, conversationHistory, provider
21895
21894
  const body = {
21896
21895
  prompt,
21897
21896
  topK: 10,
21898
- model: model || "robinpath-default",
21897
+ model: model || "anthropic/claude-sonnet-4.6",
21899
21898
  stream: true
21900
21899
  };
21901
21900
  if (provider) body.provider = provider;
@@ -22537,8 +22536,7 @@ var MODEL_PRICING = {
22537
22536
  "openai/gpt-5.2-pro": { input: 10, output: 40 },
22538
22537
  "openai/gpt-5-mini": { input: 0.4, output: 1.6 },
22539
22538
  "google/gemini-3-flash-preview": { input: 0.1, output: 0.4 },
22540
- "google/gemini-3.1-pro-preview": { input: 1.25, output: 5 },
22541
- "robinpath-default": { input: 0, output: 0 }
22539
+ "google/gemini-3.1-pro-preview": { input: 1.25, output: 5 }
22542
22540
  };
22543
22541
  function estimateCost(model, promptTokens, completionTokens) {
22544
22542
  const pricing = MODEL_PRICING[model] || MODEL_PRICING[model?.split(":")[0]];
@@ -22546,50 +22544,38 @@ function estimateCost(model, promptTokens, completionTokens) {
22546
22544
  return promptTokens / 1e6 * pricing.input + completionTokens / 1e6 * pricing.output;
22547
22545
  }
22548
22546
  var AI_MODELS = [
22549
- {
22550
- group: "Free",
22551
- id: "robinpath-default",
22552
- name: "Gemini 2.0 Flash",
22553
- desc: "free, no key needed",
22554
- requiresKey: false
22555
- },
22556
22547
  {
22557
22548
  group: "Anthropic",
22558
22549
  id: "anthropic/claude-sonnet-4.6",
22559
22550
  name: "Claude Sonnet 4.6",
22560
- desc: "fast + smart",
22561
- requiresKey: true
22551
+ desc: "fast + smart"
22562
22552
  },
22563
22553
  {
22564
22554
  group: "Anthropic",
22565
22555
  id: "anthropic/claude-opus-4.6",
22566
22556
  name: "Claude Opus 4.6",
22567
- desc: "most capable",
22568
- requiresKey: true
22557
+ desc: "most capable"
22569
22558
  },
22570
22559
  {
22571
22560
  group: "Anthropic",
22572
22561
  id: "anthropic/claude-haiku-4.5",
22573
22562
  name: "Claude Haiku 4.5",
22574
- desc: "fastest + cheapest",
22575
- requiresKey: true
22563
+ desc: "fastest + cheapest"
22576
22564
  },
22577
- { group: "OpenAI", id: "openai/gpt-5.2", name: "GPT-5.2", desc: "instant", requiresKey: true },
22578
- { group: "OpenAI", id: "openai/gpt-5.2-pro", name: "GPT-5.2 Pro", desc: "reasoning", requiresKey: true },
22579
- { group: "OpenAI", id: "openai/gpt-5-mini", name: "GPT-5 mini", desc: "budget-friendly", requiresKey: true },
22565
+ { group: "OpenAI", id: "openai/gpt-5.2", name: "GPT-5.2", desc: "instant" },
22566
+ { group: "OpenAI", id: "openai/gpt-5.2-pro", name: "GPT-5.2 Pro", desc: "reasoning" },
22567
+ { group: "OpenAI", id: "openai/gpt-5-mini", name: "GPT-5 mini", desc: "budget-friendly" },
22580
22568
  {
22581
22569
  group: "Google",
22582
22570
  id: "google/gemini-3-flash-preview",
22583
22571
  name: "Gemini 3 Flash",
22584
- desc: "1M context",
22585
- requiresKey: true
22572
+ desc: "1M context"
22586
22573
  },
22587
22574
  {
22588
22575
  group: "Google",
22589
22576
  id: "google/gemini-3.1-pro-preview",
22590
22577
  name: "Gemini 3.1 Pro",
22591
- desc: "65K output",
22592
- requiresKey: true
22578
+ desc: "65K output"
22593
22579
  }
22594
22580
  ];
22595
22581
 
@@ -22753,8 +22739,7 @@ function createInteractivePicker({ renderFn, onKeyFn }) {
22753
22739
  });
22754
22740
  }
22755
22741
  function selectModelInteractive(currentModelId) {
22756
- const hasKey = !!readAiConfig().apiKey;
22757
- const models = hasKey ? AI_MODELS : AI_MODELS.filter((m) => !m.requiresKey);
22742
+ const models = AI_MODELS;
22758
22743
  let cursor = Math.max(
22759
22744
  0,
22760
22745
  models.findIndex((m) => m.id === currentModelId)
@@ -22763,10 +22748,6 @@ function selectModelInteractive(currentModelId) {
22763
22748
  renderFn: (out) => {
22764
22749
  out("");
22765
22750
  out(color.bold(" Select AI Model"));
22766
- if (!hasKey) {
22767
- out(color.dim(" Set an API key to unlock premium models:"));
22768
- out(color.dim(` ${color.cyan("robinpath ai config set-key <key>")}`));
22769
- }
22770
22751
  out(color.dim(" \u2191\u2193 navigate Enter select Esc cancel"));
22771
22752
  out("");
22772
22753
  let lastGroup = "";
@@ -22999,46 +22980,12 @@ function listReferenceableFiles(cwd, prefix) {
22999
22980
 
23000
22981
  // src/repl.ts
23001
22982
  async function welcomeWizard() {
23002
- const options = [
23003
- { name: "Start with free tier (no key needed)", value: "free" },
23004
- { name: "I have an API key (OpenRouter, OpenAI, Anthropic)", value: "key" }
23005
- ];
23006
- let cursor = 0;
23007
- const picked = await createInteractivePicker({
23008
- renderFn: (out) => {
23009
- out("");
23010
- out(color.bold(" Welcome to RobinPath AI!"));
23011
- out(color.dim(" Your AI-powered scripting assistant"));
23012
- out("");
23013
- for (let i = 0; i < options.length; i++) {
23014
- const marker = i === cursor ? color.cyan("\u276F") : " ";
23015
- const text = i === cursor ? color.cyan(color.bold(options[i].name)) : options[i].name;
23016
- out(` ${marker} ${text}`);
23017
- }
23018
- out("");
23019
- out(color.dim(" \u2191\u2193 navigate Enter select"));
23020
- },
23021
- onKeyFn: (key2) => {
23022
- if (key2 === "\r" || key2 === "\n") return options[cursor].value;
23023
- if (key2 === "\x1B") return "free";
23024
- if (key2 === "\x1B[A" || key2 === "k") {
23025
- cursor = Math.max(0, cursor - 1);
23026
- return "render";
23027
- }
23028
- if (key2 === "\x1B[B" || key2 === "j") {
23029
- cursor = Math.min(options.length - 1, cursor + 1);
23030
- return "render";
23031
- }
23032
- return void 0;
23033
- }
23034
- }) || "free";
23035
- if (picked === "free") {
23036
- writeAiConfig({ model: "robinpath-default" });
23037
- log(color.green(" \u2713 Free tier activated \u2014 using Gemini 2.0 Flash"));
23038
- log(color.dim(` Upgrade anytime: ${color.cyan("robinpath ai config set-key <api-key>")}`));
23039
- log("");
23040
- return;
23041
- }
22983
+ log("");
22984
+ log(color.bold(" Welcome to RobinPath AI!"));
22985
+ log(color.dim(" Your AI-powered scripting assistant"));
22986
+ log("");
22987
+ log(color.dim(" An OpenRouter API key is required."));
22988
+ log(color.dim(" Get one at: https://openrouter.ai/keys"));
23042
22989
  log("");
23043
22990
  const key = await new Promise((resolve13) => {
23044
22991
  if (process.stdin.isTTY) {
@@ -23085,8 +23032,8 @@ async function welcomeWizard() {
23085
23032
  }
23086
23033
  });
23087
23034
  if (!key || !key.trim()) {
23088
- writeAiConfig({ model: "robinpath-default" });
23089
- log(color.dim(" No key provided \u2014 using free tier."));
23035
+ log(color.red(" An OpenRouter API key is required to use RobinPath AI."));
23036
+ log(color.dim(` Set one with: ${color.cyan("robinpath ai config set-key <api-key>")}`));
23090
23037
  return;
23091
23038
  }
23092
23039
  const k2 = key.trim();
@@ -23222,11 +23169,11 @@ Start chatting with: ${color.cyan("robinpath ai")}`);
23222
23169
  log(color.bold(" AI Configuration:"));
23223
23170
  log(color.dim(" " + "\u2500".repeat(40)));
23224
23171
  if (!config.apiKey) {
23225
- log(` Provider: ${color.cyan("gemini")} (free, no key needed)`);
23226
- log(` Model: ${color.cyan("gemini-2.0-flash")}`);
23227
- log(` API Key: ${color.dim("(none \u2014 using free tier)")}`);
23172
+ log(` Provider: ${color.dim("(not configured)")}`);
23173
+ log(` Model: ${color.cyan(config.model || "anthropic/claude-sonnet-4.6")}`);
23174
+ log(` API Key: ${color.red("(none \u2014 API key required)")}`);
23228
23175
  log("");
23229
- log(color.dim(" Optional: set a key for premium models:"));
23176
+ log(color.dim(" Set an OpenRouter API key:"));
23230
23177
  log(color.dim(` ${color.cyan("robinpath ai config set-key <api-key>")}`));
23231
23178
  } else {
23232
23179
  log(` Provider: ${color.cyan(config.provider || "openrouter")}`);
@@ -23245,7 +23192,7 @@ Start chatting with: ${color.cyan("robinpath ai")}`);
23245
23192
  } else {
23246
23193
  console.error(color.red("Error:") + " Usage: robinpath ai config <set-key|set-model|show|remove>");
23247
23194
  console.error("");
23248
- console.error(" robinpath ai config set-key <key> Set API key (optional, free tier works without)");
23195
+ console.error(" robinpath ai config set-key <key> Set API key (required)");
23249
23196
  console.error(" robinpath ai config set-model <model> Set model (e.g. openai/gpt-4o)");
23250
23197
  console.error(" robinpath ai config show Show current configuration");
23251
23198
  console.error(" robinpath ai config remove Remove configuration");
@@ -23258,16 +23205,16 @@ async function startAiREPL(initialPrompt, resumeSessionId, opts = {}) {
23258
23205
  const devMode = opts.devMode || false;
23259
23206
  if (devMode) setFlags({ verbose: true });
23260
23207
  const resolveProvider = (key) => {
23261
- if (!key) return "gemini";
23208
+ if (!key) return "openrouter";
23262
23209
  if (key.startsWith("sk-or-")) return "openrouter";
23263
23210
  if (key.startsWith("sk-ant-")) return "anthropic";
23264
23211
  if (key.startsWith("sk-")) return "openai";
23265
- return config.provider || "gemini";
23212
+ return config.provider || "openrouter";
23266
23213
  };
23267
23214
  const apiKey = config.apiKey || null;
23268
23215
  const provider = resolveProvider(apiKey);
23269
- const model = apiKey ? config.model || "anthropic/claude-sonnet-4.6" : "robinpath-default";
23270
- const modelShort = model === "robinpath-default" ? "gemini-2.0-flash (free)" : model.includes("/") ? model.split("/").pop() : model;
23216
+ const model = config.model || "anthropic/claude-sonnet-4.6";
23217
+ const modelShort = model.includes("/") ? model.split("/").pop() : model;
23271
23218
  const cliContext = {
23272
23219
  platform: platform6(),
23273
23220
  shell: getShellConfig().name,
@@ -23510,8 +23457,7 @@ ${readFileSync9(rpJson, "utf-8")}
23510
23457
  continue;
23511
23458
  }
23512
23459
  if (trimmed === "/model") {
23513
- const hasKey = !!readAiConfig().apiKey;
23514
- const models = hasKey ? AI_MODELS : AI_MODELS.filter((m) => !m.requiresKey);
23460
+ const models = AI_MODELS;
23515
23461
  const currentModel = readAiConfig().model || model;
23516
23462
  log("");
23517
23463
  let lastGroup = "";
@@ -23752,7 +23698,7 @@ ${readFileSync9(rpJson, "utf-8")}
23752
23698
  if (usage.cost > 0) {
23753
23699
  log(` Est. cost: ${color.yellow("$" + usage.cost.toFixed(4))}`);
23754
23700
  } else {
23755
- log(` Est. cost: ${color.green("$0.00 (free tier)")}`);
23701
+ log(` Est. cost: ${color.green("$0.00")}`);
23756
23702
  }
23757
23703
  log("");
23758
23704
  continue;
@@ -24582,16 +24528,6 @@ function ChatApp({ engine }) {
24582
24528
  ] })
24583
24529
  ] })
24584
24530
  ] }) : null,
24585
- !isFirst || loading ? /* @__PURE__ */ jsx2(Box2, { marginBottom: 1, paddingX: 1, children: /* @__PURE__ */ jsxs2(Text2, { children: [
24586
- /* @__PURE__ */ jsx2(Text2, { color: "cyan", bold: true, children: "\u25C6" }),
24587
- " ",
24588
- /* @__PURE__ */ jsx2(Text2, { bold: true, children: "RobinPath" }),
24589
- " ",
24590
- /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
24591
- "v",
24592
- CLI_VERSION
24593
- ] })
24594
- ] }) }) : null,
24595
24531
  /* @__PURE__ */ jsx2(Static, { items: messages, children: (msg) => /* @__PURE__ */ jsx2(Box2, { paddingX: 1, marginBottom: msg.text.startsWith("\u276F") ? 0 : 1, flexDirection: "column", children: msg.text.startsWith("\u276F") ? /* @__PURE__ */ jsxs2(Text2, { children: [
24596
24532
  /* @__PURE__ */ jsx2(Text2, { color: "cyan", bold: true, children: "\u276F" }),
24597
24533
  /* @__PURE__ */ jsx2(Text2, { bold: true, children: msg.text.slice(1) })
@@ -24599,10 +24535,7 @@ function ChatApp({ engine }) {
24599
24535
  showModelPicker ? /* @__PURE__ */ jsx2(
24600
24536
  ModelSelector,
24601
24537
  {
24602
- models: (() => {
24603
- const hasKey = !!readAiConfig().apiKey;
24604
- return hasKey ? AI_MODELS : AI_MODELS.filter((m) => !m.requiresKey);
24605
- })(),
24538
+ models: AI_MODELS,
24606
24539
  currentId: readAiConfig().model || engine.model,
24607
24540
  onSelect: (id) => {
24608
24541
  engine.config.model = id;
@@ -24643,7 +24576,7 @@ var ReplEngine = class {
24643
24576
  this.autoAccept = opts.autoAccept || false;
24644
24577
  if (opts.devMode) setFlags({ verbose: true });
24645
24578
  this.apiKey = this.config.apiKey || null;
24646
- this.model = this.apiKey ? this.config.model || "anthropic/claude-sonnet-4.6" : "robinpath-default";
24579
+ this.model = this.config.model || "anthropic/claude-sonnet-4.6";
24647
24580
  this.sessionId = resumeSessionId || randomUUID4().slice(0, 8);
24648
24581
  this.sessionName = `session-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}`;
24649
24582
  this.usage = createUsageTracker();
@@ -24671,11 +24604,11 @@ var ReplEngine = class {
24671
24604
  }
24672
24605
  }
24673
24606
  resolveProvider(key) {
24674
- if (!key) return "gemini";
24607
+ if (!key) return "openrouter";
24675
24608
  if (key.startsWith("sk-or-")) return "openrouter";
24676
24609
  if (key.startsWith("sk-ant-")) return "anthropic";
24677
24610
  if (key.startsWith("sk-")) return "openai";
24678
- return this.config.provider || "gemini";
24611
+ return this.config.provider || "openrouter";
24679
24612
  }
24680
24613
  updateStatus() {
24681
24614
  const m = this.model.includes("/") ? this.model.split("/").pop() : this.model;
@@ -24826,7 +24759,7 @@ Type / to see available commands.`;
24826
24759
  }
24827
24760
  if (!result.code) {
24828
24761
  const model = readAiConfig().model || this.model;
24829
- const hint = model === "robinpath-default" ? "The free model may be temporarily unavailable. Try again or switch to a paid model with /model." : "The AI returned an empty response. Try rephrasing or check your API key with /usage.";
24762
+ const hint = "The AI returned an empty response. Try rephrasing or check your API key with /usage.";
24830
24763
  finalResponse = fullText || `\u26A0 ${hint}`;
24831
24764
  break;
24832
24765
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robinpath/cli",
3
- "version": "1.99.0",
3
+ "version": "2.1.0",
4
4
  "description": "AI-powered scripting CLI — automate anything from your terminal",
5
5
  "type": "module",
6
6
  "license": "MIT",