clawfast 1.0.0 → 1.0.2

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 (3) hide show
  1. package/README.md +19 -36
  2. package/dist/clawfast.cjs +713 -283
  3. package/package.json +1 -1
package/dist/clawfast.cjs CHANGED
@@ -85,8 +85,8 @@ var init_boot_ui = __esm({
85
85
  var require_main = __commonJS({
86
86
  "../node_modules/.pnpm/dotenv@17.4.2/node_modules/dotenv/lib/main.js"(exports2, module2) {
87
87
  "use strict";
88
- var fs3 = require("fs");
89
- var path5 = require("path");
88
+ var fs4 = require("fs");
89
+ var path6 = require("path");
90
90
  var os5 = require("os");
91
91
  var crypto2 = require("crypto");
92
92
  var TIPS = [
@@ -217,7 +217,7 @@ var require_main = __commonJS({
217
217
  if (options && options.path && options.path.length > 0) {
218
218
  if (Array.isArray(options.path)) {
219
219
  for (const filepath of options.path) {
220
- if (fs3.existsSync(filepath)) {
220
+ if (fs4.existsSync(filepath)) {
221
221
  possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
222
222
  }
223
223
  }
@@ -225,15 +225,15 @@ var require_main = __commonJS({
225
225
  possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
226
226
  }
227
227
  } else {
228
- possibleVaultPath = path5.resolve(process.cwd(), ".env.vault");
228
+ possibleVaultPath = path6.resolve(process.cwd(), ".env.vault");
229
229
  }
230
- if (fs3.existsSync(possibleVaultPath)) {
230
+ if (fs4.existsSync(possibleVaultPath)) {
231
231
  return possibleVaultPath;
232
232
  }
233
233
  return null;
234
234
  }
235
235
  function _resolveHome(envPath) {
236
- return envPath[0] === "~" ? path5.join(os5.homedir(), envPath.slice(1)) : envPath;
236
+ return envPath[0] === "~" ? path6.join(os5.homedir(), envPath.slice(1)) : envPath;
237
237
  }
238
238
  function _configVault(options) {
239
239
  const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || options && options.debug);
@@ -250,7 +250,7 @@ var require_main = __commonJS({
250
250
  return { parsed };
251
251
  }
252
252
  function configDotenv(options) {
253
- const dotenvPath = path5.resolve(process.cwd(), ".env");
253
+ const dotenvPath = path6.resolve(process.cwd(), ".env");
254
254
  let encoding = "utf8";
255
255
  let processEnv = process.env;
256
256
  if (options && options.processEnv != null) {
@@ -278,13 +278,13 @@ var require_main = __commonJS({
278
278
  }
279
279
  let lastError;
280
280
  const parsedAll = {};
281
- for (const path6 of optionPaths) {
281
+ for (const path7 of optionPaths) {
282
282
  try {
283
- const parsed = DotenvModule.parse(fs3.readFileSync(path6, { encoding }));
283
+ const parsed = DotenvModule.parse(fs4.readFileSync(path7, { encoding }));
284
284
  DotenvModule.populate(parsedAll, parsed, options);
285
285
  } catch (e) {
286
286
  if (debug) {
287
- _debug(`failed to load ${path6} ${e.message}`);
287
+ _debug(`failed to load ${path7} ${e.message}`);
288
288
  }
289
289
  lastError = e;
290
290
  }
@@ -297,7 +297,7 @@ var require_main = __commonJS({
297
297
  const shortPaths = [];
298
298
  for (const filePath of optionPaths) {
299
299
  try {
300
- const relative2 = path5.relative(process.cwd(), filePath);
300
+ const relative2 = path6.relative(process.cwd(), filePath);
301
301
  shortPaths.push(relative2);
302
302
  } catch (e) {
303
303
  if (debug) {
@@ -442,7 +442,7 @@ async function ensureProviderKey() {
442
442
  if (hasAnyProviderKey()) return true;
443
443
  if (!process.stdin.isTTY) {
444
444
  process.stderr.write(
445
- `Nenhuma chave de modelo configurada. Defina OPENROUTER_API_KEY (ou HUGGINGFACE_API_KEY/HF_TOKEN/OPENAI_API_KEY) em ${clawfastEnvPath()} ou como vari\xE1vel de ambiente.
445
+ `Nenhuma chave de modelo configurada. Defina NVIDIA_API_KEY (ou OPENAI_API_KEY) em ${clawfastEnvPath()} ou como vari\xE1vel de ambiente.
446
446
  `
447
447
  );
448
448
  return false;
@@ -450,15 +450,15 @@ async function ensureProviderKey() {
450
450
  process.stdout.write(
451
451
  `
452
452
  ${C.greenB}Bem-vindo ao clawfast!${C.reset}
453
- ${C.dim}Para come\xE7ar, preciso de uma chave de modelo. A mais simples \xE9 o OpenRouter (tem modelos gratuitos):${C.reset}
454
- ${C.cyan}1.${C.reset} crie uma chave em ${C.green}https://openrouter.ai/keys${C.reset}
453
+ ${C.dim}Para come\xE7ar, preciso de uma chave de modelo. Use a NVIDIA build (modelos gratuitos):${C.reset}
454
+ ${C.cyan}1.${C.reset} crie uma chave em ${C.green}https://build.nvidia.com/${C.reset}
455
455
  ${C.cyan}2.${C.reset} cole abaixo (fica salva em ${clawfastEnvPath()})
456
456
 
457
457
  `
458
458
  );
459
459
  let key = "";
460
460
  while (!key) {
461
- key = await promptLine(`${C.greenB}Chave OpenRouter${C.reset} \u276F `);
461
+ key = await promptLine(`${C.greenB}Chave NVIDIA${C.reset} \u276F `);
462
462
  if (!key) {
463
463
  process.stdout.write(
464
464
  `${C.dim}chave vazia \u2014 cole de novo, ou Ctrl+C para sair.${C.reset}
@@ -466,8 +466,8 @@ ${C.dim}Para come\xE7ar, preciso de uma chave de modelo. A mais simples \xE9 o O
466
466
  );
467
467
  }
468
468
  }
469
- setEnvVar(clawfastEnvPath(), "OPENROUTER_API_KEY", key);
470
- process.env.OPENROUTER_API_KEY = key;
469
+ setEnvVar(clawfastEnvPath(), "NVIDIA_API_KEY", key);
470
+ process.env.NVIDIA_API_KEY = key;
471
471
  process.stdout.write(
472
472
  `${C.green}\u2713 chave salva em ${clawfastEnvPath()}${C.reset}
473
473
  `
@@ -485,12 +485,7 @@ var init_config = __esm({
485
485
  import_node_readline = __toESM(require("node:readline"));
486
486
  clawfastHome = () => process.env.CLAWFAST_HOME?.trim() || import_node_path.default.join(import_node_os.default.homedir(), ".clawfast");
487
487
  clawfastEnvPath = () => import_node_path.default.join(clawfastHome(), ".env");
488
- PROVIDER_KEYS = [
489
- "OPENROUTER_API_KEY",
490
- "OPENAI_API_KEY",
491
- "HUGGINGFACE_API_KEY",
492
- "HF_TOKEN"
493
- ];
488
+ PROVIDER_KEYS = ["NVIDIA_API_KEY", "OPENAI_API_KEY"];
494
489
  hasAnyProviderKey = () => PROVIDER_KEYS.some((name25) => Boolean(process.env[name25]?.trim()));
495
490
  C = {
496
491
  reset: "\x1B[0m",
@@ -634,6 +629,151 @@ var init_paste_input = __esm({
634
629
  }
635
630
  });
636
631
 
632
+ // src/skills.ts
633
+ function listSkills() {
634
+ const dir = skillsDir();
635
+ let entries = [];
636
+ try {
637
+ entries = import_node_fs2.default.readdirSync(dir).filter((f) => f.endsWith(".md"));
638
+ } catch {
639
+ return [];
640
+ }
641
+ const skills = [];
642
+ for (const entry of entries.sort()) {
643
+ const file2 = import_node_path2.default.join(dir, entry);
644
+ let raw = "";
645
+ try {
646
+ raw = import_node_fs2.default.readFileSync(file2, "utf8");
647
+ } catch {
648
+ continue;
649
+ }
650
+ const { meta: meta3, body } = parseFrontmatter(raw);
651
+ const name25 = meta3.name?.trim() || entry.replace(/\.md$/, "");
652
+ const triggers = parseTriggers(meta3.triggers);
653
+ skills.push({
654
+ name: name25,
655
+ description: meta3.description?.trim() || "(sem descricao)",
656
+ // Default matching keywords = the slug's word parts when none were given.
657
+ triggers: triggers.length > 0 ? triggers : name25.split("-").filter(Boolean),
658
+ always: isTrue(meta3.always),
659
+ body: body.trim(),
660
+ file: file2
661
+ });
662
+ }
663
+ return skills;
664
+ }
665
+ function saveSkill(input) {
666
+ const slug = slugify(input.name);
667
+ if (!slug) {
668
+ throw new Error("nome de skill invalido (vazio apos normalizacao)");
669
+ }
670
+ const dir = skillsDir();
671
+ import_node_fs2.default.mkdirSync(dir, { recursive: true });
672
+ const file2 = import_node_path2.default.join(dir, `${slug}.md`);
673
+ const overwritten = import_node_fs2.default.existsSync(file2);
674
+ const triggers = (input.triggers ?? []).map((t) => t.trim().toLowerCase()).filter(Boolean);
675
+ const frontmatter = [
676
+ "---",
677
+ `name: ${slug}`,
678
+ `description: ${escapeFrontmatterValue(input.description ?? "")}`,
679
+ `triggers: ${triggers.join(", ")}`,
680
+ `always: ${input.always ? "true" : "false"}`,
681
+ "---",
682
+ ""
683
+ ].join("\n");
684
+ import_node_fs2.default.writeFileSync(file2, frontmatter + input.body.trim() + "\n", {
685
+ encoding: "utf8"
686
+ });
687
+ return {
688
+ skill: {
689
+ name: slug,
690
+ description: input.description?.trim() || "(sem descricao)",
691
+ triggers: triggers.length > 0 ? triggers : slug.split("-").filter(Boolean),
692
+ always: Boolean(input.always),
693
+ body: input.body.trim(),
694
+ file: file2
695
+ },
696
+ file: file2,
697
+ overwritten
698
+ };
699
+ }
700
+ function deleteSkill(name25) {
701
+ const slug = slugify(name25);
702
+ const file2 = import_node_path2.default.join(skillsDir(), `${slug}.md`);
703
+ try {
704
+ import_node_fs2.default.unlinkSync(file2);
705
+ return true;
706
+ } catch {
707
+ return false;
708
+ }
709
+ }
710
+ function buildSkillsIndexSection(skills = listSkills()) {
711
+ if (skills.length === 0) return "";
712
+ const lines = skills.map((s) => `- ${s.name}: ${s.description}`).join("\n");
713
+ return `
714
+
715
+ <skills_disponiveis>
716
+ Voce tem skills instaladas \u2014 conhecimento e procedimentos reutilizaveis criados pelo usuario. Quando o pedido do usuario casar com uma skill, o runtime do CLI carrega AUTOMATICAMENTE o conteudo completo dela neste turno (voce nao precisa pedir). Trate o conteudo carregado como instrucao de alta prioridade. Skills instaladas:
717
+ ${lines}
718
+ </skills_disponiveis>`;
719
+ }
720
+ function selectSkillsForInput(userInput, skills = listSkills()) {
721
+ const haystack = userInput.toLowerCase();
722
+ const matched = [];
723
+ for (const skill of skills) {
724
+ if (skill.always) {
725
+ matched.push(skill);
726
+ continue;
727
+ }
728
+ const keywords = [skill.name, ...skill.triggers].map((k) => k.toLowerCase()).filter((k) => k.length >= 3);
729
+ if (keywords.some((k) => haystack.includes(k))) {
730
+ matched.push(skill);
731
+ }
732
+ }
733
+ return matched;
734
+ }
735
+ function renderSkillBodies(skills) {
736
+ if (skills.length === 0) return "";
737
+ const blocks = skills.map((s) => `<skill name="${s.name}">
738
+ ${s.body}
739
+ </skill>`).join("\n\n");
740
+ return `
741
+
742
+ <active_skills>
743
+ As skills a seguir foram carregadas porque o pedido atual casou com elas (ou estao marcadas como sempre-ativas). Siga o conhecimento e os procedimentos delas como instrucao de alta prioridade nesta tarefa.
744
+
745
+ ${blocks}
746
+ </active_skills>`;
747
+ }
748
+ var import_node_fs2, import_node_path2, skillsDir, slugify, FRONTMATTER_RE, parseFrontmatter, parseTriggers, isTrue, escapeFrontmatterValue;
749
+ var init_skills = __esm({
750
+ "src/skills.ts"() {
751
+ "use strict";
752
+ import_node_fs2 = __toESM(require("node:fs"));
753
+ import_node_path2 = __toESM(require("node:path"));
754
+ init_config();
755
+ skillsDir = () => import_node_path2.default.join(clawfastHome(), "skills");
756
+ slugify = (name25) => name25.trim().toLowerCase().normalize("NFD").replace(/[̀-ͯ]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64);
757
+ FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
758
+ parseFrontmatter = (raw) => {
759
+ const match = raw.match(FRONTMATTER_RE);
760
+ if (!match) return { meta: {}, body: raw };
761
+ const meta3 = {};
762
+ for (const line of match[1].split(/\r?\n/)) {
763
+ const idx = line.indexOf(":");
764
+ if (idx === -1) continue;
765
+ const key = line.slice(0, idx).trim().toLowerCase();
766
+ const value = line.slice(idx + 1).trim();
767
+ if (key) meta3[key] = value;
768
+ }
769
+ return { meta: meta3, body: raw.slice(match[0].length) };
770
+ };
771
+ parseTriggers = (raw) => (raw ?? "").split(",").map((t) => t.trim().toLowerCase()).filter(Boolean);
772
+ isTrue = (raw) => /^(1|true|yes|sim)$/i.test((raw ?? "").trim());
773
+ escapeFrontmatterValue = (value) => value.replace(/\r?\n/g, " ").trim();
774
+ }
775
+ });
776
+
637
777
  // ../node_modules/.pnpm/@ai-sdk+provider@3.0.10/node_modules/@ai-sdk/provider/dist/index.mjs
638
778
  function getErrorMessage(error51) {
639
779
  if (error51 == null) {
@@ -1100,7 +1240,7 @@ __export(util_exports, {
1100
1240
  required: () => required,
1101
1241
  safeExtend: () => safeExtend,
1102
1242
  shallowClone: () => shallowClone,
1103
- slugify: () => slugify,
1243
+ slugify: () => slugify2,
1104
1244
  stringifyPrimitive: () => stringifyPrimitive,
1105
1245
  uint8ArrayToBase64: () => uint8ArrayToBase64,
1106
1246
  uint8ArrayToBase64url: () => uint8ArrayToBase64url,
@@ -1206,10 +1346,10 @@ function mergeDefs(...defs) {
1206
1346
  function cloneDef(schema) {
1207
1347
  return mergeDefs(schema._zod.def);
1208
1348
  }
1209
- function getElementAtPath(obj, path5) {
1210
- if (!path5)
1349
+ function getElementAtPath(obj, path6) {
1350
+ if (!path6)
1211
1351
  return obj;
1212
- return path5.reduce((acc, key) => acc?.[key], obj);
1352
+ return path6.reduce((acc, key) => acc?.[key], obj);
1213
1353
  }
1214
1354
  function promiseAllObject(promisesObj) {
1215
1355
  const keys = Object.keys(promisesObj);
@@ -1233,7 +1373,7 @@ function randomString(length = 10) {
1233
1373
  function esc(str) {
1234
1374
  return JSON.stringify(str);
1235
1375
  }
1236
- function slugify(input) {
1376
+ function slugify2(input) {
1237
1377
  return input.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
1238
1378
  }
1239
1379
  function isObject(data) {
@@ -1537,11 +1677,11 @@ function explicitlyAborted(x, startIndex = 0) {
1537
1677
  }
1538
1678
  return false;
1539
1679
  }
1540
- function prefixIssues(path5, issues) {
1680
+ function prefixIssues(path6, issues) {
1541
1681
  return issues.map((iss) => {
1542
1682
  var _a25;
1543
1683
  (_a25 = iss).path ?? (_a25.path = []);
1544
- iss.path.unshift(path5);
1684
+ iss.path.unshift(path6);
1545
1685
  return iss;
1546
1686
  });
1547
1687
  }
@@ -1759,16 +1899,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
1759
1899
  }
1760
1900
  function formatError(error51, mapper = (issue2) => issue2.message) {
1761
1901
  const fieldErrors = { _errors: [] };
1762
- const processError = (error52, path5 = []) => {
1902
+ const processError = (error52, path6 = []) => {
1763
1903
  for (const issue2 of error52.issues) {
1764
1904
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1765
- issue2.errors.map((issues) => processError({ issues }, [...path5, ...issue2.path]));
1905
+ issue2.errors.map((issues) => processError({ issues }, [...path6, ...issue2.path]));
1766
1906
  } else if (issue2.code === "invalid_key") {
1767
- processError({ issues: issue2.issues }, [...path5, ...issue2.path]);
1907
+ processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
1768
1908
  } else if (issue2.code === "invalid_element") {
1769
- processError({ issues: issue2.issues }, [...path5, ...issue2.path]);
1909
+ processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
1770
1910
  } else {
1771
- const fullpath = [...path5, ...issue2.path];
1911
+ const fullpath = [...path6, ...issue2.path];
1772
1912
  if (fullpath.length === 0) {
1773
1913
  fieldErrors._errors.push(mapper(issue2));
1774
1914
  } else {
@@ -1795,17 +1935,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
1795
1935
  }
1796
1936
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
1797
1937
  const result = { errors: [] };
1798
- const processError = (error52, path5 = []) => {
1938
+ const processError = (error52, path6 = []) => {
1799
1939
  var _a25, _b18;
1800
1940
  for (const issue2 of error52.issues) {
1801
1941
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1802
- issue2.errors.map((issues) => processError({ issues }, [...path5, ...issue2.path]));
1942
+ issue2.errors.map((issues) => processError({ issues }, [...path6, ...issue2.path]));
1803
1943
  } else if (issue2.code === "invalid_key") {
1804
- processError({ issues: issue2.issues }, [...path5, ...issue2.path]);
1944
+ processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
1805
1945
  } else if (issue2.code === "invalid_element") {
1806
- processError({ issues: issue2.issues }, [...path5, ...issue2.path]);
1946
+ processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
1807
1947
  } else {
1808
- const fullpath = [...path5, ...issue2.path];
1948
+ const fullpath = [...path6, ...issue2.path];
1809
1949
  if (fullpath.length === 0) {
1810
1950
  result.errors.push(mapper(issue2));
1811
1951
  continue;
@@ -1837,8 +1977,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
1837
1977
  }
1838
1978
  function toDotPath(_path) {
1839
1979
  const segs = [];
1840
- const path5 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1841
- for (const seg of path5) {
1980
+ const path6 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1981
+ for (const seg of path6) {
1842
1982
  if (typeof seg === "number")
1843
1983
  segs.push(`[${seg}]`);
1844
1984
  else if (typeof seg === "symbol")
@@ -11979,7 +12119,7 @@ function _toUpperCase() {
11979
12119
  }
11980
12120
  // @__NO_SIDE_EFFECTS__
11981
12121
  function _slugify() {
11982
- return /* @__PURE__ */ _overwrite((input) => slugify(input));
12122
+ return /* @__PURE__ */ _overwrite((input) => slugify2(input));
11983
12123
  }
11984
12124
  // @__NO_SIDE_EFFECTS__
11985
12125
  function _array(Class2, element, params) {
@@ -15341,13 +15481,13 @@ function resolveRef(ref, ctx) {
15341
15481
  if (!ref.startsWith("#")) {
15342
15482
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
15343
15483
  }
15344
- const path5 = ref.slice(1).split("/").filter(Boolean);
15345
- if (path5.length === 0) {
15484
+ const path6 = ref.slice(1).split("/").filter(Boolean);
15485
+ if (path6.length === 0) {
15346
15486
  return ctx.rootSchema;
15347
15487
  }
15348
15488
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
15349
- if (path5[0] === defsKey) {
15350
- const key = path5[1];
15489
+ if (path6[0] === defsKey) {
15490
+ const key = path6[1];
15351
15491
  if (!key || !ctx.defs[key]) {
15352
15492
  throw new Error(`Reference not found: ${ref}`);
15353
15493
  }
@@ -16536,8 +16676,8 @@ var init_parseUtil = __esm({
16536
16676
  init_errors3();
16537
16677
  init_en2();
16538
16678
  makeIssue = (params) => {
16539
- const { data, path: path5, errorMaps, issueData } = params;
16540
- const fullPath = [...path5, ...issueData.path || []];
16679
+ const { data, path: path6, errorMaps, issueData } = params;
16680
+ const fullPath = [...path6, ...issueData.path || []];
16541
16681
  const fullIssue = {
16542
16682
  ...issueData,
16543
16683
  path: fullPath
@@ -16820,11 +16960,11 @@ var init_types = __esm({
16820
16960
  init_parseUtil();
16821
16961
  init_util2();
16822
16962
  ParseInputLazyPath = class {
16823
- constructor(parent, value, path5, key) {
16963
+ constructor(parent, value, path6, key) {
16824
16964
  this._cachedPath = [];
16825
16965
  this.parent = parent;
16826
16966
  this.data = value;
16827
- this._path = path5;
16967
+ this._path = path6;
16828
16968
  this._key = key;
16829
16969
  }
16830
16970
  get path() {
@@ -22863,8 +23003,8 @@ var require_auth_config = __commonJS({
22863
23003
  writeAuthConfig: () => writeAuthConfig
22864
23004
  });
22865
23005
  module2.exports = __toCommonJS(auth_config_exports);
22866
- var fs3 = __toESM2(require("fs"));
22867
- var path5 = __toESM2(require("path"));
23006
+ var fs4 = __toESM2(require("fs"));
23007
+ var path6 = __toESM2(require("path"));
22868
23008
  var import_token_util = require_token_util();
22869
23009
  function getAuthConfigPath() {
22870
23010
  const dataDir = (0, import_token_util.getVercelDataDir)();
@@ -22873,15 +23013,15 @@ var require_auth_config = __commonJS({
22873
23013
  `Unable to find Vercel CLI data directory. Your platform: ${process.platform}. Supported: darwin, linux, win32.`
22874
23014
  );
22875
23015
  }
22876
- return path5.join(dataDir, "auth.json");
23016
+ return path6.join(dataDir, "auth.json");
22877
23017
  }
22878
23018
  function readAuthConfig() {
22879
23019
  try {
22880
23020
  const authPath = getAuthConfigPath();
22881
- if (!fs3.existsSync(authPath)) {
23021
+ if (!fs4.existsSync(authPath)) {
22882
23022
  return null;
22883
23023
  }
22884
- const content = fs3.readFileSync(authPath, "utf8");
23024
+ const content = fs4.readFileSync(authPath, "utf8");
22885
23025
  if (!content) {
22886
23026
  return null;
22887
23027
  }
@@ -22892,11 +23032,11 @@ var require_auth_config = __commonJS({
22892
23032
  }
22893
23033
  function writeAuthConfig(config3) {
22894
23034
  const authPath = getAuthConfigPath();
22895
- const authDir = path5.dirname(authPath);
22896
- if (!fs3.existsSync(authDir)) {
22897
- fs3.mkdirSync(authDir, { mode: 504, recursive: true });
23035
+ const authDir = path6.dirname(authPath);
23036
+ if (!fs4.existsSync(authDir)) {
23037
+ fs4.mkdirSync(authDir, { mode: 504, recursive: true });
22898
23038
  }
22899
- fs3.writeFileSync(authPath, JSON.stringify(config3, null, 2), { mode: 384 });
23039
+ fs4.writeFileSync(authPath, JSON.stringify(config3, null, 2), { mode: 384 });
22900
23040
  }
22901
23041
  function isValidAccessToken(authConfig, expirationBufferMs = 0) {
22902
23042
  if (!authConfig.token)
@@ -23087,8 +23227,8 @@ var require_token_util = __commonJS({
23087
23227
  saveToken: () => saveToken
23088
23228
  });
23089
23229
  module2.exports = __toCommonJS(token_util_exports);
23090
- var path5 = __toESM2(require("path"));
23091
- var fs3 = __toESM2(require("fs"));
23230
+ var path6 = __toESM2(require("path"));
23231
+ var fs4 = __toESM2(require("fs"));
23092
23232
  var import_token_error = require_token_error();
23093
23233
  var import_token_io = require_token_io();
23094
23234
  var import_auth_config = require_auth_config();
@@ -23100,7 +23240,7 @@ var require_token_util = __commonJS({
23100
23240
  if (!dataDir) {
23101
23241
  return null;
23102
23242
  }
23103
- return path5.join(dataDir, vercelFolder);
23243
+ return path6.join(dataDir, vercelFolder);
23104
23244
  }
23105
23245
  async function getVercelToken2(options) {
23106
23246
  const authConfig = (0, import_auth_config.readAuthConfig)();
@@ -23176,13 +23316,13 @@ var require_token_util = __commonJS({
23176
23316
  "Unable to find project root directory. Have you linked your project with `vc link?`"
23177
23317
  );
23178
23318
  }
23179
- const prjPath = path5.join(dir, ".vercel", "project.json");
23180
- if (!fs3.existsSync(prjPath)) {
23319
+ const prjPath = path6.join(dir, ".vercel", "project.json");
23320
+ if (!fs4.existsSync(prjPath)) {
23181
23321
  throw new import_token_error.VercelOidcTokenError(
23182
23322
  "project.json not found, have you linked your project with `vc link?`"
23183
23323
  );
23184
23324
  }
23185
- const prj = JSON.parse(fs3.readFileSync(prjPath, "utf8"));
23325
+ const prj = JSON.parse(fs4.readFileSync(prjPath, "utf8"));
23186
23326
  if (typeof prj.projectId !== "string" && typeof prj.orgId !== "string") {
23187
23327
  throw new TypeError(
23188
23328
  "Expected a string-valued projectId property. Try running `vc link` to re-link your project."
@@ -23197,11 +23337,11 @@ var require_token_util = __commonJS({
23197
23337
  "Unable to find user data directory. Please reach out to Vercel support."
23198
23338
  );
23199
23339
  }
23200
- const tokenPath = path5.join(dir, "com.vercel.token", `${projectId}.json`);
23340
+ const tokenPath = path6.join(dir, "com.vercel.token", `${projectId}.json`);
23201
23341
  const tokenJson = JSON.stringify(token);
23202
- fs3.mkdirSync(path5.dirname(tokenPath), { mode: 504, recursive: true });
23203
- fs3.writeFileSync(tokenPath, tokenJson);
23204
- fs3.chmodSync(tokenPath, 432);
23342
+ fs4.mkdirSync(path6.dirname(tokenPath), { mode: 504, recursive: true });
23343
+ fs4.writeFileSync(tokenPath, tokenJson);
23344
+ fs4.chmodSync(tokenPath, 432);
23205
23345
  return;
23206
23346
  }
23207
23347
  function loadToken(projectId) {
@@ -23211,11 +23351,11 @@ var require_token_util = __commonJS({
23211
23351
  "Unable to find user data directory. Please reach out to Vercel support."
23212
23352
  );
23213
23353
  }
23214
- const tokenPath = path5.join(dir, "com.vercel.token", `${projectId}.json`);
23215
- if (!fs3.existsSync(tokenPath)) {
23354
+ const tokenPath = path6.join(dir, "com.vercel.token", `${projectId}.json`);
23355
+ if (!fs4.existsSync(tokenPath)) {
23216
23356
  return null;
23217
23357
  }
23218
- const token = JSON.parse(fs3.readFileSync(tokenPath, "utf8"));
23358
+ const token = JSON.parse(fs4.readFileSync(tokenPath, "utf8"));
23219
23359
  assertVercelOidcTokenResponse(token);
23220
23360
  return token;
23221
23361
  }
@@ -35241,7 +35381,7 @@ function createOpenRouter(options = {}) {
35241
35381
  );
35242
35382
  const createChatModel = (modelId, settings = {}) => new OpenRouterChatLanguageModel(modelId, settings, {
35243
35383
  provider: "openrouter.chat",
35244
- url: ({ path: path5 }) => `${baseURL}${path5}`,
35384
+ url: ({ path: path6 }) => `${baseURL}${path6}`,
35245
35385
  headers: getHeaders,
35246
35386
  compatibility,
35247
35387
  fetch: options.fetch,
@@ -35249,7 +35389,7 @@ function createOpenRouter(options = {}) {
35249
35389
  });
35250
35390
  const createCompletionModel = (modelId, settings = {}) => new OpenRouterCompletionLanguageModel(modelId, settings, {
35251
35391
  provider: "openrouter.completion",
35252
- url: ({ path: path5 }) => `${baseURL}${path5}`,
35392
+ url: ({ path: path6 }) => `${baseURL}${path6}`,
35253
35393
  headers: getHeaders,
35254
35394
  compatibility,
35255
35395
  fetch: options.fetch,
@@ -35257,21 +35397,21 @@ function createOpenRouter(options = {}) {
35257
35397
  });
35258
35398
  const createEmbeddingModel = (modelId, settings = {}) => new OpenRouterEmbeddingModel(modelId, settings, {
35259
35399
  provider: "openrouter.embedding",
35260
- url: ({ path: path5 }) => `${baseURL}${path5}`,
35400
+ url: ({ path: path6 }) => `${baseURL}${path6}`,
35261
35401
  headers: getHeaders,
35262
35402
  fetch: options.fetch,
35263
35403
  extraBody: options.extraBody
35264
35404
  });
35265
35405
  const createImageModel = (modelId, settings = {}) => new OpenRouterImageModel(modelId, settings, {
35266
35406
  provider: "openrouter.image",
35267
- url: ({ path: path5 }) => `${baseURL}${path5}`,
35407
+ url: ({ path: path6 }) => `${baseURL}${path6}`,
35268
35408
  headers: getHeaders,
35269
35409
  fetch: options.fetch,
35270
35410
  extraBody: options.extraBody
35271
35411
  });
35272
35412
  const createVideoModel = (modelId, settings = {}) => new OpenRouterVideoModel(modelId, settings, {
35273
35413
  provider: "openrouter.video",
35274
- url: ({ path: path5 }) => `${baseURL}${path5}`,
35414
+ url: ({ path: path6 }) => `${baseURL}${path6}`,
35275
35415
  headers: getHeaders,
35276
35416
  fetch: options.fetch,
35277
35417
  extraBody: options.extraBody
@@ -39807,37 +39947,37 @@ function createOpenAI(options = {}) {
39807
39947
  );
39808
39948
  const createChatModel = (modelId) => new OpenAIChatLanguageModel(modelId, {
39809
39949
  provider: `${providerName}.chat`,
39810
- url: ({ path: path5 }) => `${baseURL}${path5}`,
39950
+ url: ({ path: path6 }) => `${baseURL}${path6}`,
39811
39951
  headers: getHeaders,
39812
39952
  fetch: options.fetch
39813
39953
  });
39814
39954
  const createCompletionModel = (modelId) => new OpenAICompletionLanguageModel(modelId, {
39815
39955
  provider: `${providerName}.completion`,
39816
- url: ({ path: path5 }) => `${baseURL}${path5}`,
39956
+ url: ({ path: path6 }) => `${baseURL}${path6}`,
39817
39957
  headers: getHeaders,
39818
39958
  fetch: options.fetch
39819
39959
  });
39820
39960
  const createEmbeddingModel = (modelId) => new OpenAIEmbeddingModel(modelId, {
39821
39961
  provider: `${providerName}.embedding`,
39822
- url: ({ path: path5 }) => `${baseURL}${path5}`,
39962
+ url: ({ path: path6 }) => `${baseURL}${path6}`,
39823
39963
  headers: getHeaders,
39824
39964
  fetch: options.fetch
39825
39965
  });
39826
39966
  const createImageModel = (modelId) => new OpenAIImageModel(modelId, {
39827
39967
  provider: `${providerName}.image`,
39828
- url: ({ path: path5 }) => `${baseURL}${path5}`,
39968
+ url: ({ path: path6 }) => `${baseURL}${path6}`,
39829
39969
  headers: getHeaders,
39830
39970
  fetch: options.fetch
39831
39971
  });
39832
39972
  const createTranscriptionModel = (modelId) => new OpenAITranscriptionModel(modelId, {
39833
39973
  provider: `${providerName}.transcription`,
39834
- url: ({ path: path5 }) => `${baseURL}${path5}`,
39974
+ url: ({ path: path6 }) => `${baseURL}${path6}`,
39835
39975
  headers: getHeaders,
39836
39976
  fetch: options.fetch
39837
39977
  });
39838
39978
  const createSpeechModel = (modelId) => new OpenAISpeechModel(modelId, {
39839
39979
  provider: `${providerName}.speech`,
39840
- url: ({ path: path5 }) => `${baseURL}${path5}`,
39980
+ url: ({ path: path6 }) => `${baseURL}${path6}`,
39841
39981
  headers: getHeaders,
39842
39982
  fetch: options.fetch
39843
39983
  });
@@ -39852,7 +39992,7 @@ function createOpenAI(options = {}) {
39852
39992
  const createResponsesModel = (modelId) => {
39853
39993
  return new OpenAIResponsesLanguageModel(modelId, {
39854
39994
  provider: `${providerName}.responses`,
39855
- url: ({ path: path5 }) => `${baseURL}${path5}`,
39995
+ url: ({ path: path6 }) => `${baseURL}${path6}`,
39856
39996
  headers: getHeaders,
39857
39997
  fetch: options.fetch,
39858
39998
  fileIdPrefixes: ["file-"]
@@ -45073,7 +45213,7 @@ function supportsMultimodalToolResults(modelName) {
45073
45213
  const normalized = modelName.toLowerCase();
45074
45214
  return normalized === "ask-model" || normalized.includes("gemini") || normalized.includes("google/") || isAnthropicModel(normalized) || normalized.includes("anthropic/") || normalized.includes("claude") || normalized.includes("openai") || normalized.includes("openai/") || normalized.includes("gpt-") || normalized.includes("o1") || normalized.includes("o3") || normalized.includes("o4") || normalized.includes("x-ai/") || normalized.includes("grok");
45075
45215
  }
45076
- var isRecord, isXaiModelSlug, isGeminiModelSlug, requestCanRouteToXai, requestCanRouteToGemini, hasOwnEncryptedContent, stripEncryptedContent, sanitizeOpenRouterRequestForXai, hasJsonRefKey, wrapToolContentIfGeminiRefSensitive, sanitizeOpenRouterRequestForGeminiFunctionResponses, patchKimiReasoningToolCalls, OPENROUTER_METADATA_HEADER, withOpenRouterMetadataHeader, openrouterPatchFetch, openrouter2, openai2, nvidia, huggingface, deepseek, kimi, buildProviderMap, hasEnvValue, hasHuggingFaceKey, isDeepSeekEnabled, isKimiEnabled, CLI_MODEL_CHAIN, baseProviders, modelCutoffDates, modelDisplayNames, getModelDisplayName, getModelCutoffDate, myProvider;
45216
+ var isRecord, isXaiModelSlug, isGeminiModelSlug, requestCanRouteToXai, requestCanRouteToGemini, hasOwnEncryptedContent, stripEncryptedContent, sanitizeOpenRouterRequestForXai, hasJsonRefKey, wrapToolContentIfGeminiRefSensitive, sanitizeOpenRouterRequestForGeminiFunctionResponses, patchKimiReasoningToolCalls, OPENROUTER_METADATA_HEADER, withOpenRouterMetadataHeader, openrouterPatchFetch, openrouter2, openai2, nvidia, deepseek, kimi, buildProviderMap, hasEnvValue, isDeepSeekEnabled, isKimiEnabled, CLI_MODEL_CHAIN, baseProviders, modelCutoffDates, modelDisplayNames, getModelDisplayName, getModelCutoffDate, myProvider;
45077
45217
  var init_providers = __esm({
45078
45218
  "../lib/ai/providers.ts"() {
45079
45219
  "use strict";
@@ -45238,11 +45378,6 @@ var init_providers = __esm({
45238
45378
  baseURL: process.env.NVIDIA_BASE_URL || "https://integrate.api.nvidia.com/v1",
45239
45379
  apiKey: process.env.NVIDIA_API_KEY
45240
45380
  });
45241
- huggingface = createOpenAI({
45242
- name: "huggingface",
45243
- baseURL: process.env.HUGGINGFACE_BASE_URL || "https://router.huggingface.co/v1",
45244
- apiKey: process.env.HUGGINGFACE_API_KEY || process.env.HF_TOKEN
45245
- });
45246
45381
  deepseek = createOpenAI({
45247
45382
  name: "deepseek",
45248
45383
  // Default to the deepsproxy port the clawfast proxy-manager starts it on, so
@@ -45268,19 +45403,14 @@ var init_providers = __esm({
45268
45403
  "model-deepseek-v4-flash": or("z-ai/glm-4.5-air:free"),
45269
45404
  "model-opus-4.6": nvidia("nvidia/nemotron-3-ultra-550b-a55b"),
45270
45405
  "model-kimi-k2.6": or("qwen/qwen3-coder:free"),
45406
+ // NVIDIA build models — primary provider for the local CLI (chat-completions).
45407
+ "model-nvidia-minimax-m3": nvidia.chat("minimaxai/minimax-m3"),
45408
+ "model-nvidia-kimi-k2.6": nvidia.chat("moonshotai/kimi-k2.6"),
45409
+ "model-nvidia-glm-5.1": nvidia.chat("z-ai/glm-5.1"),
45410
+ "model-nvidia-qwen3.5-397b": nvidia.chat("qwen/qwen3.5-397b-a17b"),
45271
45411
  // Extra explicit keys for the CLI.
45272
- "model-glm-4.5-air": or("z-ai/glm-4.5-air:free"),
45273
- "model-qwen3-coder": or("qwen/qwen3-coder:free"),
45274
45412
  "model-openai-chat-latest": openai2("chat-latest"),
45275
45413
  "model-nvidia-nemotron": nvidia("nvidia/nemotron-3-ultra-550b-a55b"),
45276
- "model-hf-qwen3-6-35b-a3b": huggingface.chat("Qwen/Qwen3.6-35B-A3B"),
45277
- "model-hf-glm-5-1-fp8": huggingface.chat("zai-org/GLM-5.1-FP8"),
45278
- "model-hf-deepseek-v4-flash": huggingface.chat(
45279
- "deepseek-ai/DeepSeek-V4-Flash"
45280
- ),
45281
- "model-hf-deepseek-v4-flash-nvfp4": huggingface.chat(
45282
- "nvidia/DeepSeek-V4-Flash-NVFP4"
45283
- ),
45284
45414
  // DeepSeek via logged-in web session (deepsproxy) or official API.
45285
45415
  "model-deepseek-proxy": deepseek.chat(
45286
45416
  process.env.DEEPSEEK_MODEL || "deepseek-v4-flash"
@@ -45297,7 +45427,6 @@ var init_providers = __esm({
45297
45427
  "title-generator-model": or("z-ai/glm-4.5-air:free")
45298
45428
  });
45299
45429
  hasEnvValue = (name25) => Boolean(process.env[name25]?.trim());
45300
- hasHuggingFaceKey = () => hasEnvValue("HUGGINGFACE_API_KEY") || hasEnvValue("HF_TOKEN");
45301
45430
  isDeepSeekEnabled = () => {
45302
45431
  const flag = process.env.DEEPSEEK_ENABLED?.trim().toLowerCase();
45303
45432
  if (flag === "1" || flag === "true" || flag === "yes") return true;
@@ -45311,23 +45440,19 @@ var init_providers = __esm({
45311
45440
  return hasEnvValue("KIMI_BASE_URL") || hasEnvValue("KIMI_API_KEY");
45312
45441
  };
45313
45442
  CLI_MODEL_CHAIN = [
45314
- ...hasEnvValue("OPENROUTER_API_KEY") ? [
45315
- "agent-model",
45316
- // OpenRouter glm-4.5-air:free — real tool calling
45317
- "model-qwen3-coder"
45318
- // OpenRouter qwen/qwen3-coder:free
45443
+ ...hasEnvValue("NVIDIA_API_KEY") ? [
45444
+ "model-nvidia-minimax-m3",
45445
+ // NVIDIA minimaxai/minimax-m3
45446
+ "model-nvidia-kimi-k2.6",
45447
+ // NVIDIA moonshotai/kimi-k2.6
45448
+ "model-nvidia-glm-5.1",
45449
+ // NVIDIA z-ai/glm-5.1
45450
+ "model-nvidia-qwen3.5-397b"
45451
+ // NVIDIA qwen/qwen3.5-397b-a17b
45319
45452
  ] : [],
45320
45453
  // Web-session proxies: chat-grade, selectable via /model, fallbacks here.
45321
45454
  ...isKimiEnabled() ? ["model-kimi-proxy"] : [],
45322
45455
  ...isDeepSeekEnabled() ? ["model-deepseek-proxy"] : [],
45323
- ...hasHuggingFaceKey() ? [
45324
- "model-hf-qwen3-6-35b-a3b",
45325
- // Hugging Face Qwen/Qwen3.6-35B-A3B
45326
- "model-hf-glm-5-1-fp8",
45327
- // Hugging Face zai-org/GLM-5.1-FP8
45328
- "model-hf-deepseek-v4-flash"
45329
- // Hugging Face deepseek-ai/DeepSeek-V4-Flash
45330
- ] : [],
45331
45456
  ...hasEnvValue("OPENAI_API_KEY") ? [
45332
45457
  // OpenAI API model closest to the ChatGPT instant experience.
45333
45458
  "model-openai-chat-latest"
@@ -45344,10 +45469,10 @@ var init_providers = __esm({
45344
45469
  "model-deepseek-v4-flash": "May 2025",
45345
45470
  "model-opus-4.6": "May 2025",
45346
45471
  "model-kimi-k2.6": "April 2024",
45347
- "model-hf-qwen3-6-35b-a3b": "Unknown",
45348
- "model-hf-glm-5-1-fp8": "Unknown",
45349
- "model-hf-deepseek-v4-flash": "Unknown",
45350
- "model-hf-deepseek-v4-flash-nvfp4": "Unknown",
45472
+ "model-nvidia-minimax-m3": "Unknown",
45473
+ "model-nvidia-kimi-k2.6": "April 2024",
45474
+ "model-nvidia-glm-5.1": "Unknown",
45475
+ "model-nvidia-qwen3.5-397b": "Unknown",
45351
45476
  "model-deepseek-proxy": "July 2024",
45352
45477
  "model-kimi-proxy": "April 2024",
45353
45478
  "model-openai-chat-latest": "August 2025",
@@ -45368,10 +45493,10 @@ var init_providers = __esm({
45368
45493
  "model-deepseek-v4-flash": "DeepSeek V4 Flash",
45369
45494
  "model-opus-4.6": "Anthropic Claude Opus 4.6",
45370
45495
  "model-kimi-k2.6": "Moonshot Kimi K2.6",
45371
- "model-hf-qwen3-6-35b-a3b": "Qwen Qwen3.6 35B A3B",
45372
- "model-hf-glm-5-1-fp8": "Z.ai GLM 5.1 FP8",
45373
- "model-hf-deepseek-v4-flash": "DeepSeek V4 Flash",
45374
- "model-hf-deepseek-v4-flash-nvfp4": "NVIDIA DeepSeek V4 Flash NVFP4",
45496
+ "model-nvidia-minimax-m3": "NVIDIA - MiniMax M3",
45497
+ "model-nvidia-kimi-k2.6": "NVIDIA - Moonshot Kimi K2.6",
45498
+ "model-nvidia-glm-5.1": "NVIDIA - Z.ai GLM 5.1",
45499
+ "model-nvidia-qwen3.5-397b": "NVIDIA - Qwen3.5 397B A17B",
45375
45500
  "model-deepseek-proxy": "DeepSeek (sessao web logada / deepsproxy)",
45376
45501
  "model-kimi-proxy": "Kimi (sessao web logada / kimiproxy)",
45377
45502
  "model-openai-chat-latest": "OpenAI Chat Latest",
@@ -48403,8 +48528,8 @@ var init_background_process_tracker = __esm({
48403
48528
  /**
48404
48529
  * Normalize file path for comparison
48405
48530
  */
48406
- normalizePath(path5) {
48407
- let normalized = path5.trim().replace(/\/+/g, "/");
48531
+ normalizePath(path6) {
48532
+ let normalized = path6.trim().replace(/\/+/g, "/");
48408
48533
  if (normalized.startsWith("./")) {
48409
48534
  normalized = normalized.slice(2);
48410
48535
  }
@@ -48642,8 +48767,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
48642
48767
  return decodedFile;
48643
48768
  };
48644
48769
  }
48645
- function normalizeWindowsPath(path5) {
48646
- return path5.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
48770
+ function normalizeWindowsPath(path6) {
48771
+ return path6.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
48647
48772
  }
48648
48773
  var import_path;
48649
48774
  var init_module_node = __esm({
@@ -51532,9 +51657,9 @@ async function addSourceContext(frames) {
51532
51657
  LRU_FILE_CONTENTS_CACHE.reduce();
51533
51658
  return frames;
51534
51659
  }
51535
- function getContextLinesFromFile(path5, ranges, output) {
51660
+ function getContextLinesFromFile(path6, ranges, output) {
51536
51661
  return new Promise((resolve2) => {
51537
- const stream = (0, import_node_fs2.createReadStream)(path5);
51662
+ const stream = (0, import_node_fs3.createReadStream)(path6);
51538
51663
  const lineReaded = (0, import_node_readline2.createInterface)({
51539
51664
  input: stream
51540
51665
  });
@@ -51549,7 +51674,7 @@ function getContextLinesFromFile(path5, ranges, output) {
51549
51674
  let rangeStart = range[0];
51550
51675
  let rangeEnd = range[1];
51551
51676
  function onStreamError() {
51552
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path5, 1);
51677
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path6, 1);
51553
51678
  lineReaded.close();
51554
51679
  lineReaded.removeAllListeners();
51555
51680
  destroyStreamAndResolve();
@@ -51610,8 +51735,8 @@ function clearLineContext(frame2) {
51610
51735
  delete frame2.context_line;
51611
51736
  delete frame2.post_context;
51612
51737
  }
51613
- function shouldSkipContextLinesForFile(path5) {
51614
- return path5.startsWith("node:") || path5.endsWith(".min.js") || path5.endsWith(".min.cjs") || path5.endsWith(".min.mjs") || path5.startsWith("data:");
51738
+ function shouldSkipContextLinesForFile(path6) {
51739
+ return path6.startsWith("node:") || path6.endsWith(".min.js") || path6.endsWith(".min.cjs") || path6.endsWith(".min.mjs") || path6.startsWith("data:");
51615
51740
  }
51616
51741
  function shouldSkipContextLinesForFrame(frame2) {
51617
51742
  if (void 0 !== frame2.lineno && frame2.lineno > MAX_CONTEXTLINES_LINENO) return true;
@@ -51682,12 +51807,12 @@ function snipLine(line, colno) {
51682
51807
  if (end < lineLength) newLine += "...";
51683
51808
  return newLine;
51684
51809
  }
51685
- var import_node_fs2, import_node_readline2, LRU_FILE_CONTENTS_CACHE, LRU_FILE_CONTENTS_FS_READ_FAILED, DEFAULT_LINES_OF_CONTEXT, MAX_CONTEXTLINES_COLNO, MAX_CONTEXTLINES_LINENO;
51810
+ var import_node_fs3, import_node_readline2, LRU_FILE_CONTENTS_CACHE, LRU_FILE_CONTENTS_FS_READ_FAILED, DEFAULT_LINES_OF_CONTEXT, MAX_CONTEXTLINES_COLNO, MAX_CONTEXTLINES_LINENO;
51686
51811
  var init_context_lines_node = __esm({
51687
51812
  "../node_modules/.pnpm/posthog-node@5.35.13_rxjs@7.8.2/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/context-lines.node.mjs"() {
51688
51813
  "use strict";
51689
51814
  init_dist8();
51690
- import_node_fs2 = require("node:fs");
51815
+ import_node_fs3 = require("node:fs");
51691
51816
  import_node_readline2 = require("node:readline");
51692
51817
  LRU_FILE_CONTENTS_CACHE = new error_tracking_exports.ReduceableCache(25);
51693
51818
  LRU_FILE_CONTENTS_FS_READ_FAILED = new error_tracking_exports.ReduceableCache(20);
@@ -67021,8 +67146,8 @@ var init_logger2 = __esm({
67021
67146
  });
67022
67147
 
67023
67148
  // ../lib/ai/tools/file.ts
67024
- function isSpritPath(path5) {
67025
- return path5.split(/[\\/]/).some((segment) => segment.toLowerCase() === "sprit");
67149
+ function isSpritPath(path6) {
67150
+ return path6.split(/[\\/]/).some((segment) => segment.toLowerCase() === "sprit");
67026
67151
  }
67027
67152
  function getViewSandboxType(sandbox) {
67028
67153
  return isCentrifugoSandbox(sandbox) ? "centrifugo" : "e2b";
@@ -67053,7 +67178,7 @@ function captureFileViewImageUsage(args) {
67053
67178
  const {
67054
67179
  context: context2,
67055
67180
  sandbox,
67056
- path: path5,
67181
+ path: path6,
67057
67182
  outcome,
67058
67183
  durationMs,
67059
67184
  mediaType,
@@ -67071,7 +67196,7 @@ function captureFileViewImageUsage(args) {
67071
67196
  model: getActiveModelName(context2),
67072
67197
  configured_model: context2.modelName,
67073
67198
  sandbox_type: getViewSandboxType(sandbox),
67074
- file_extension: getFileExtension(path5),
67199
+ file_extension: getFileExtension(path6),
67075
67200
  outcome,
67076
67201
  success: outcome === "success",
67077
67202
  duration_ms: durationMs,
@@ -67145,22 +67270,22 @@ async function runSandboxCommand(sandbox, command, envVars, timeoutMs = 6e4) {
67145
67270
  function isWindowsSandbox(sandbox) {
67146
67271
  return isCentrifugoSandbox(sandbox) && sandbox.isWindows();
67147
67272
  }
67148
- function getWindowsNativePath(path5) {
67149
- if (/^[A-Za-z]:[\\/]/.test(path5)) return path5;
67150
- if (path5.startsWith("/tmp/")) {
67151
- return `C:\\temp${path5.slice(4).replace(/\//g, "\\")}`;
67273
+ function getWindowsNativePath(path6) {
67274
+ if (/^[A-Za-z]:[\\/]/.test(path6)) return path6;
67275
+ if (path6.startsWith("/tmp/")) {
67276
+ return `C:\\temp${path6.slice(4).replace(/\//g, "\\")}`;
67152
67277
  }
67153
- return path5.replace(/\//g, "\\");
67278
+ return path6.replace(/\//g, "\\");
67154
67279
  }
67155
- function getPythonPathForSandbox(sandbox, path5) {
67156
- return isWindowsSandbox(sandbox) ? getWindowsNativePath(path5) : path5;
67280
+ function getPythonPathForSandbox(sandbox, path6) {
67281
+ return isWindowsSandbox(sandbox) ? getWindowsNativePath(path6) : path6;
67157
67282
  }
67158
- function toWindowsBashPath(path5) {
67159
- const drive = path5.match(/^([A-Za-z]):[\\/](.*)$/);
67283
+ function toWindowsBashPath(path6) {
67284
+ const drive = path6.match(/^([A-Za-z]):[\\/](.*)$/);
67160
67285
  if (drive) {
67161
67286
  return `/${drive[1].toLowerCase()}/${drive[2].replace(/\\/g, "/")}`;
67162
67287
  }
67163
- return path5.replace(/\\/g, "/");
67288
+ return path6.replace(/\\/g, "/");
67164
67289
  }
67165
67290
  async function detectSandboxShell(sandbox) {
67166
67291
  if (!isWindowsSandbox(sandbox)) return "bash";
@@ -67199,8 +67324,8 @@ PY`;
67199
67324
  }
67200
67325
  }
67201
67326
  }
67202
- async function getSandboxFileState(sandbox, path5) {
67203
- const pythonPath = getPythonPathForSandbox(sandbox, path5);
67327
+ async function getSandboxFileState(sandbox, path6) {
67328
+ const pythonPath = getPythonPathForSandbox(sandbox, path6);
67204
67329
  const result = await runPythonScript(
67205
67330
  sandbox,
67206
67331
  FILE_STATE_SCRIPT,
@@ -67217,23 +67342,23 @@ async function getSandboxFileState(sandbox, path5) {
67217
67342
  if (result.exitCode !== 0) {
67218
67343
  return {
67219
67344
  kind: "unknown",
67220
- path: path5,
67345
+ path: path6,
67221
67346
  error: result.stderr || result.stdout || "file state command failed"
67222
67347
  };
67223
67348
  }
67224
67349
  try {
67225
67350
  const payload = JSON.parse(result.stdout.trim());
67226
67351
  if (payload.kind === "file" && typeof payload.sizeBytes === "number" && Number.isFinite(payload.sizeBytes)) {
67227
- return { ...payload, path: path5 };
67352
+ return { ...payload, path: path6 };
67228
67353
  }
67229
67354
  if (payload.kind === "missing" || payload.kind === "not_file") {
67230
- return { ...payload, path: path5 };
67355
+ return { ...payload, path: path6 };
67231
67356
  }
67232
67357
  } catch {
67233
67358
  }
67234
67359
  return {
67235
67360
  kind: "unknown",
67236
- path: path5,
67361
+ path: path6,
67237
67362
  error: result.stderr || result.stdout || "invalid file state response"
67238
67363
  };
67239
67364
  }
@@ -67265,8 +67390,8 @@ ${numberedContent}${truncatedNotice}${footerNotice}`;
67265
67390
  })
67266
67391
  };
67267
67392
  }
67268
- async function readSandboxTextFile(sandbox, path5, range) {
67269
- const pythonPath = getPythonPathForSandbox(sandbox, path5);
67393
+ async function readSandboxTextFile(sandbox, path6, range) {
67394
+ const pythonPath = getPythonPathForSandbox(sandbox, path6);
67270
67395
  const envVars = {
67271
67396
  HACKERAI_FILE_READ_PATH: pythonPath,
67272
67397
  HACKERAI_FILE_READ_RANGE_START: String(range?.[0] ?? 0),
@@ -67294,40 +67419,40 @@ async function readSandboxTextFile(sandbox, path5, range) {
67294
67419
  }
67295
67420
  return payload;
67296
67421
  }
67297
- async function readSandboxTextFileWithFallback(sandbox, path5, range) {
67422
+ async function readSandboxTextFileWithFallback(sandbox, path6, range) {
67298
67423
  try {
67299
- return await readSandboxTextFile(sandbox, path5, range);
67424
+ return await readSandboxTextFile(sandbox, path6, range);
67300
67425
  } catch (error51) {
67301
67426
  const errorMessage = error51 instanceof Error ? error51.message : String(error51);
67302
67427
  if (errorMessage.startsWith("Invalid ") || errorMessage.includes("File not found")) {
67303
67428
  throw error51;
67304
67429
  }
67305
- const state = await getSandboxFileState(sandbox, path5);
67430
+ const state = await getSandboxFileState(sandbox, path6);
67306
67431
  if (state.kind === "unknown") {
67307
67432
  throw new Error(
67308
- `Unable to determine file size for ${path5}; refusing to load the file into memory. ${state.error}`
67433
+ `Unable to determine file size for ${path6}; refusing to load the file into memory. ${state.error}`
67309
67434
  );
67310
67435
  }
67311
67436
  if (state.kind === "missing") {
67312
- throw new Error(`File not found or is not a regular file: ${path5}`);
67437
+ throw new Error(`File not found or is not a regular file: ${path6}`);
67313
67438
  }
67314
67439
  if (state.kind === "not_file") {
67315
- throw new Error(`File is not a regular file: ${path5}`);
67440
+ throw new Error(`File is not a regular file: ${path6}`);
67316
67441
  }
67317
67442
  if (state.sizeBytes > MAX_TEXT_FILE_READ_BYTES) {
67318
67443
  if (range) {
67319
67444
  throw new Error(
67320
- `Unable to perform a bounded range read for ${path5}, and the file is too large to load safely (${formatBytes(state.sizeBytes)}). Use a targeted terminal command that writes a small result to a separate file.`
67445
+ `Unable to perform a bounded range read for ${path6}, and the file is too large to load safely (${formatBytes(state.sizeBytes)}). Use a targeted terminal command that writes a small result to a separate file.`
67321
67446
  );
67322
67447
  }
67323
67448
  return {
67324
- path: path5,
67449
+ path: path6,
67325
67450
  sizeBytes: state.sizeBytes,
67326
67451
  totalLines: 0,
67327
67452
  tooLarge: true
67328
67453
  };
67329
67454
  }
67330
- const fileContent = await sandbox.files.read(path5, {
67455
+ const fileContent = await sandbox.files.read(path6, {
67331
67456
  user: "user"
67332
67457
  });
67333
67458
  const lines = fileContent.split("\n");
@@ -67356,7 +67481,7 @@ async function readSandboxTextFileWithFallback(sandbox, path5, range) {
67356
67481
  const startIndex = start - 1;
67357
67482
  const endIndex = end === -1 ? lines.length : end;
67358
67483
  return {
67359
- path: path5,
67484
+ path: path6,
67360
67485
  sizeBytes: Buffer.byteLength(fileContent),
67361
67486
  totalLines: lines.length,
67362
67487
  content: lines.slice(startIndex, endIndex).join("\n"),
@@ -67364,7 +67489,7 @@ async function readSandboxTextFileWithFallback(sandbox, path5, range) {
67364
67489
  };
67365
67490
  }
67366
67491
  return {
67367
- path: path5,
67492
+ path: path6,
67368
67493
  sizeBytes: Buffer.byteLength(fileContent),
67369
67494
  totalLines: lines.length,
67370
67495
  content: fileContent,
@@ -67372,7 +67497,7 @@ async function readSandboxTextFileWithFallback(sandbox, path5, range) {
67372
67497
  };
67373
67498
  }
67374
67499
  }
67375
- async function appendSandboxTextFile(sandbox, path5, text2) {
67500
+ async function appendSandboxTextFile(sandbox, path6, text2) {
67376
67501
  const tempPath = `/tmp/hackerai_append_${Date.now()}_${Math.random().toString(36).slice(2)}.tmp`;
67377
67502
  await sandbox.files.write(tempPath, text2, {
67378
67503
  user: "user"
@@ -67381,7 +67506,7 @@ async function appendSandboxTextFile(sandbox, path5, text2) {
67381
67506
  sandbox,
67382
67507
  APPEND_TEXT_FILE_SCRIPT,
67383
67508
  {
67384
- HACKERAI_FILE_APPEND_TARGET_PATH: getPythonPathForSandbox(sandbox, path5),
67509
+ HACKERAI_FILE_APPEND_TARGET_PATH: getPythonPathForSandbox(sandbox, path6),
67385
67510
  HACKERAI_FILE_APPEND_SOURCE_PATH: getPythonPathForSandbox(
67386
67511
  sandbox,
67387
67512
  tempPath
@@ -67393,13 +67518,13 @@ async function appendSandboxTextFile(sandbox, path5, text2) {
67393
67518
  throw new Error(result.stderr || result.stdout || "Failed to append file");
67394
67519
  }
67395
67520
  }
67396
- async function readSandboxFileForView(sandbox, path5, includeData) {
67521
+ async function readSandboxFileForView(sandbox, path6, includeData) {
67397
67522
  if (isCentrifugoSandbox(sandbox) && sandbox.isWindows()) {
67398
67523
  throw new Error(
67399
67524
  "The view action is not available for Windows local sandboxes yet. Use a Linux/E2B sandbox or inspect the image manually."
67400
67525
  );
67401
67526
  }
67402
- const sandboxPath = getSandboxViewPath(sandbox, path5);
67527
+ const sandboxPath = getSandboxViewPath(sandbox, path6);
67403
67528
  const viewEnvVars = {
67404
67529
  HACKERAI_FILE_VIEW_PATH: sandboxPath,
67405
67530
  HACKERAI_FILE_VIEW_INCLUDE_DATA: includeData ? "1" : "0",
@@ -67742,19 +67867,19 @@ try:
67742
67867
  except OSError:
67743
67868
  pass
67744
67869
  `;
67745
- getFilename = (path5) => path5.split("/").pop() || path5;
67746
- getFileExtension = (path5) => {
67747
- const filename = getFilename(path5);
67870
+ getFilename = (path6) => path6.split("/").pop() || path6;
67871
+ getFileExtension = (path6) => {
67872
+ const filename = getFilename(path6);
67748
67873
  const dotIndex = filename.lastIndexOf(".");
67749
67874
  if (dotIndex <= 0 || dotIndex === filename.length - 1) return void 0;
67750
67875
  return filename.slice(dotIndex + 1).toLowerCase();
67751
67876
  };
67752
- getSandboxViewPath = (sandbox, path5) => {
67877
+ getSandboxViewPath = (sandbox, path6) => {
67753
67878
  const maybeSandbox = sandbox;
67754
- if (isCentrifugoSandbox(maybeSandbox) && maybeSandbox.isWindows() && path5.startsWith("/tmp/")) {
67755
- return `C:\\temp${path5.slice(4).replace(/\//g, "\\")}`;
67879
+ if (isCentrifugoSandbox(maybeSandbox) && maybeSandbox.isWindows() && path6.startsWith("/tmp/")) {
67880
+ return `C:\\temp${path6.slice(4).replace(/\//g, "\\")}`;
67756
67881
  }
67757
- return path5;
67882
+ return path6;
67758
67883
  };
67759
67884
  stripTrailingWs = (line) => line.replace(/[ \t]+$/u, "");
67760
67885
  editSchema = external_exports.object({
@@ -67828,7 +67953,7 @@ ${instructionsDescription}`,
67828
67953
  "A list of edits to be sequentially applied to the file. Required for `edit` action."
67829
67954
  )
67830
67955
  }),
67831
- execute: async ({ action, path: path5, text: text2, range, edits }) => {
67956
+ execute: async ({ action, path: path6, text: text2, range, edits }) => {
67832
67957
  try {
67833
67958
  const { sandbox } = await sandboxManager.getSandbox();
67834
67959
  switch (action) {
@@ -67838,7 +67963,7 @@ ${instructionsDescription}`,
67838
67963
  captureFileViewImageUsage({
67839
67964
  context: context2,
67840
67965
  sandbox,
67841
- path: path5,
67966
+ path: path6,
67842
67967
  outcome: "unsupported_model",
67843
67968
  durationMs: Date.now() - viewStartedAt,
67844
67969
  failureReason: "unsupported_model"
@@ -67847,26 +67972,26 @@ ${instructionsDescription}`,
67847
67972
  }
67848
67973
  let viewPayload;
67849
67974
  try {
67850
- viewPayload = await readSandboxFileForView(sandbox, path5, false);
67975
+ viewPayload = await readSandboxFileForView(sandbox, path6, false);
67851
67976
  } catch (error51) {
67852
67977
  captureFileViewImageUsage({
67853
67978
  context: context2,
67854
67979
  sandbox,
67855
- path: path5,
67980
+ path: path6,
67856
67981
  outcome: "inspection_failed",
67857
67982
  durationMs: Date.now() - viewStartedAt,
67858
67983
  failureReason: classifyFileViewError(error51)
67859
67984
  });
67860
67985
  throw error51;
67861
67986
  }
67862
- const filename = getFilename(path5);
67987
+ const filename = getFilename(path6);
67863
67988
  let previewFiles = [];
67864
67989
  let previewUploadError;
67865
67990
  try {
67866
67991
  previewFiles = await uploadViewPreviewFiles({
67867
67992
  context: context2,
67868
67993
  sandbox,
67869
- sourcePath: path5,
67994
+ sourcePath: path6,
67870
67995
  payload: viewPayload
67871
67996
  });
67872
67997
  } catch (error51) {
@@ -67880,7 +68005,7 @@ ${instructionsDescription}`,
67880
68005
  user_id: context2.userID,
67881
68006
  sandbox_type: getViewSandboxType(sandbox),
67882
68007
  file_name: filename,
67883
- source_path: path5,
68008
+ source_path: path6,
67884
68009
  kind: viewPayload.kind,
67885
68010
  media_type: viewPayload.mediaType,
67886
68011
  size_bytes: viewPayload.sizeBytes,
@@ -67891,7 +68016,7 @@ ${instructionsDescription}`,
67891
68016
  captureFileViewImageUsage({
67892
68017
  context: context2,
67893
68018
  sandbox,
67894
- path: path5,
68019
+ path: path6,
67895
68020
  outcome: "success",
67896
68021
  durationMs: Date.now() - viewStartedAt,
67897
68022
  mediaType: viewPayload.mediaType,
@@ -67901,7 +68026,7 @@ ${instructionsDescription}`,
67901
68026
  return {
67902
68027
  action: "view",
67903
68028
  content: `Viewing image file: ${filename} (${viewPayload.mediaType}, ${viewPayload.sizeBytes} bytes).`,
67904
- path: path5,
68029
+ path: path6,
67905
68030
  filename,
67906
68031
  mediaType: viewPayload.mediaType,
67907
68032
  sizeBytes: viewPayload.sizeBytes,
@@ -67911,8 +68036,8 @@ ${instructionsDescription}`,
67911
68036
  };
67912
68037
  }
67913
68038
  case "read": {
67914
- const filename = path5.split("/").pop() || path5;
67915
- const spritChunked = isSpritPath(path5);
68039
+ const filename = path6.split("/").pop() || path6;
68040
+ const spritChunked = isSpritPath(path6);
67916
68041
  let effectiveRange = range;
67917
68042
  if (spritChunked) {
67918
68043
  const start = range && range[0] > 0 ? range[0] : 1;
@@ -67925,7 +68050,7 @@ ${instructionsDescription}`,
67925
68050
  }
67926
68051
  const readPayload = await readSandboxTextFileWithFallback(
67927
68052
  sandbox,
67928
- path5,
68053
+ path6,
67929
68054
  effectiveRange
67930
68055
  );
67931
68056
  if (readPayload.tooLarge) {
@@ -67962,46 +68087,46 @@ File is too large to read in full (${formatBytes(readPayload.sizeBytes)}, ${tota
67962
68087
  if (text2 === void 0) {
67963
68088
  return { error: "text is required for write action" };
67964
68089
  }
67965
- await sandbox.files.write(path5, text2, {
68090
+ await sandbox.files.write(path6, text2, {
67966
68091
  user: "user"
67967
68092
  });
67968
- return `File written: ${path5}`;
68093
+ return `File written: ${path6}`;
67969
68094
  }
67970
68095
  case "append": {
67971
68096
  if (text2 === void 0) {
67972
68097
  return { error: "text is required for append action" };
67973
68098
  }
67974
- const existingState = await getSandboxFileState(sandbox, path5);
68099
+ const existingState = await getSandboxFileState(sandbox, path6);
67975
68100
  if (existingState.kind === "unknown") {
67976
68101
  return {
67977
- error: `Cannot append safely because the existing file size could not be determined for ${path5}. ${existingState.error}`
68102
+ error: `Cannot append safely because the existing file size could not be determined for ${path6}. ${existingState.error}`
67978
68103
  };
67979
68104
  }
67980
68105
  if (existingState.kind === "not_file") {
67981
68106
  return {
67982
- error: `Cannot append to ${path5} because it is not a file.`
68107
+ error: `Cannot append to ${path6} because it is not a file.`
67983
68108
  };
67984
68109
  }
67985
68110
  if (existingState.kind === "file" && existingState.sizeBytes > MAX_TEXT_FILE_READ_BYTES) {
67986
- await appendSandboxTextFile(sandbox, path5, text2);
68111
+ await appendSandboxTextFile(sandbox, path6, text2);
67987
68112
  return {
67988
- content: `File appended: ${path5}
68113
+ content: `File appended: ${path6}
67989
68114
  Existing file is ${formatBytes(existingState.sizeBytes)}, so the full diff preview was skipped to avoid loading the entire file into memory.`
67990
68115
  };
67991
68116
  }
67992
68117
  let existingContent = "";
67993
68118
  try {
67994
- existingContent = await sandbox.files.read(path5, {
68119
+ existingContent = await sandbox.files.read(path6, {
67995
68120
  user: "user"
67996
68121
  });
67997
68122
  } catch {
67998
68123
  }
67999
68124
  const newContent = existingContent + text2;
68000
- await sandbox.files.write(path5, newContent, {
68125
+ await sandbox.files.write(path6, newContent, {
68001
68126
  user: "user"
68002
68127
  });
68003
68128
  return {
68004
- content: `File appended: ${path5}`,
68129
+ content: `File appended: ${path6}`,
68005
68130
  originalContent: truncateOutput({
68006
68131
  content: existingContent,
68007
68132
  mode: "read-file"
@@ -68016,31 +68141,31 @@ Existing file is ${formatBytes(existingState.sizeBytes)}, so the full diff previ
68016
68141
  if (!edits || edits.length === 0) {
68017
68142
  return { error: "edits array is required for edit action" };
68018
68143
  }
68019
- const existingState = await getSandboxFileState(sandbox, path5);
68144
+ const existingState = await getSandboxFileState(sandbox, path6);
68020
68145
  if (existingState.kind === "unknown") {
68021
68146
  return {
68022
- error: `Cannot edit ${path5} safely because the file size could not be determined. ${existingState.error}`
68147
+ error: `Cannot edit ${path6} safely because the file size could not be determined. ${existingState.error}`
68023
68148
  };
68024
68149
  }
68025
68150
  if (existingState.kind === "missing") {
68026
68151
  return {
68027
- error: `Cannot edit file ${path5} - file is empty or does not exist`
68152
+ error: `Cannot edit file ${path6} - file is empty or does not exist`
68028
68153
  };
68029
68154
  }
68030
68155
  if (existingState.kind === "not_file") {
68031
- return { error: `Cannot edit ${path5} because it is not a file.` };
68156
+ return { error: `Cannot edit ${path6} because it is not a file.` };
68032
68157
  }
68033
68158
  if (existingState.sizeBytes > MAX_TEXT_FILE_READ_BYTES) {
68034
68159
  return {
68035
- error: `File ${path5} is too large for the edit action (${formatBytes(existingState.sizeBytes)}). Use a targeted shell command, restore the file from a clean source, or replace it with the write action instead of loading the whole file into memory.`
68160
+ error: `File ${path6} is too large for the edit action (${formatBytes(existingState.sizeBytes)}). Use a targeted shell command, restore the file from a clean source, or replace it with the write action instead of loading the whole file into memory.`
68036
68161
  };
68037
68162
  }
68038
- const originalContent = await sandbox.files.read(path5, {
68163
+ const originalContent = await sandbox.files.read(path6, {
68039
68164
  user: "user"
68040
68165
  });
68041
68166
  if (!originalContent) {
68042
68167
  return {
68043
- error: `Cannot edit file ${path5} - file is empty or does not exist`
68168
+ error: `Cannot edit file ${path6} - file is empty or does not exist`
68044
68169
  };
68045
68170
  }
68046
68171
  const resolvedEdits = [];
@@ -68085,7 +68210,7 @@ ${hint}` : "")
68085
68210
  }
68086
68211
  }
68087
68212
  }
68088
- await sandbox.files.write(path5, content, {
68213
+ await sandbox.files.write(path6, content, {
68089
68214
  user: "user"
68090
68215
  });
68091
68216
  const lines = content.split("\n");
@@ -68361,20 +68486,20 @@ var init_utils4 = __esm({
68361
68486
 
68362
68487
  // src/local-sandbox.ts
68363
68488
  function inferShellFlag(shell2) {
68364
- const base = import_node_path2.default.basename(shell2).toLowerCase();
68489
+ const base = import_node_path3.default.basename(shell2).toLowerCase();
68365
68490
  if (base === "cmd" || base === "cmd.exe") return "/C";
68366
68491
  if (base === "powershell" || base === "powershell.exe" || base === "pwsh") {
68367
68492
  return "-Command";
68368
68493
  }
68369
68494
  return "-c";
68370
68495
  }
68371
- var import_node_child_process, import_node_fs3, import_node_path2, import_node_os2, import_node_url, import_meta, LocalSandbox;
68496
+ var import_node_child_process, import_node_fs4, import_node_path3, import_node_os2, import_node_url, import_meta, LocalSandbox;
68372
68497
  var init_local_sandbox = __esm({
68373
68498
  "src/local-sandbox.ts"() {
68374
68499
  "use strict";
68375
68500
  import_node_child_process = require("node:child_process");
68376
- import_node_fs3 = require("node:fs");
68377
- import_node_path2 = __toESM(require("node:path"));
68501
+ import_node_fs4 = require("node:fs");
68502
+ import_node_path3 = __toESM(require("node:path"));
68378
68503
  import_node_os2 = __toESM(require("node:os"));
68379
68504
  import_node_url = require("node:url");
68380
68505
  init_utils4();
@@ -68472,15 +68597,15 @@ var init_local_sandbox = __esm({
68472
68597
  this.files = {
68473
68598
  write: async (filePath, content) => {
68474
68599
  const resolved = this.resolvePath(filePath);
68475
- await import_node_fs3.promises.mkdir(import_node_path2.default.dirname(resolved), { recursive: true });
68600
+ await import_node_fs4.promises.mkdir(import_node_path3.default.dirname(resolved), { recursive: true });
68476
68601
  const data = typeof content === "string" ? content : content instanceof ArrayBuffer ? Buffer.from(content) : content;
68477
- await import_node_fs3.promises.writeFile(resolved, data);
68602
+ await import_node_fs4.promises.writeFile(resolved, data);
68478
68603
  },
68479
68604
  read: async (filePath) => {
68480
- return import_node_fs3.promises.readFile(this.resolvePath(filePath), "utf8");
68605
+ return import_node_fs4.promises.readFile(this.resolvePath(filePath), "utf8");
68481
68606
  },
68482
68607
  remove: async (filePath) => {
68483
- await import_node_fs3.promises.rm(this.resolvePath(filePath), {
68608
+ await import_node_fs4.promises.rm(this.resolvePath(filePath), {
68484
68609
  recursive: true,
68485
68610
  force: true
68486
68611
  });
@@ -68488,8 +68613,8 @@ var init_local_sandbox = __esm({
68488
68613
  list: async (dirPath = ".") => {
68489
68614
  const resolved = this.resolvePath(dirPath);
68490
68615
  try {
68491
- const entries = await import_node_fs3.promises.readdir(resolved, { withFileTypes: true });
68492
- return entries.filter((e) => e.isFile()).map((e) => ({ name: import_node_path2.default.join(resolved, e.name) }));
68616
+ const entries = await import_node_fs4.promises.readdir(resolved, { withFileTypes: true });
68617
+ return entries.filter((e) => e.isFile()).map((e) => ({ name: import_node_path3.default.join(resolved, e.name) }));
68493
68618
  } catch {
68494
68619
  return [];
68495
68620
  }
@@ -68504,11 +68629,11 @@ var init_local_sandbox = __esm({
68504
68629
  this.shellBin = shell2.shell;
68505
68630
  this.shellFlag = shell2.shellFlag;
68506
68631
  }
68507
- const base = opts?.workdir || process.env.CLI_WORKDIR || import_node_path2.default.join(process.cwd(), "SPRIT");
68508
- this.workdir = import_node_path2.default.resolve(base).replace(/\\/g, "/");
68632
+ const base = opts?.workdir || process.env.CLI_WORKDIR || import_node_path3.default.join(process.cwd(), "SPRIT");
68633
+ this.workdir = import_node_path3.default.resolve(base).replace(/\\/g, "/");
68509
68634
  }
68510
68635
  async init() {
68511
- await import_node_fs3.promises.mkdir(this.workdir, { recursive: true });
68636
+ await import_node_fs4.promises.mkdir(this.workdir, { recursive: true });
68512
68637
  await this.seedReconToolkit();
68513
68638
  }
68514
68639
  /**
@@ -68524,8 +68649,8 @@ var init_local_sandbox = __esm({
68524
68649
  const assetsDir = (0, import_node_url.fileURLToPath)(
68525
68650
  new URL("../assets/recon", import_meta.url)
68526
68651
  );
68527
- const destDir = import_node_path2.default.join(this.workdir, "recon");
68528
- await import_node_fs3.promises.mkdir(destDir, { recursive: true });
68652
+ const destDir = import_node_path3.default.join(this.workdir, "recon");
68653
+ await import_node_fs4.promises.mkdir(destDir, { recursive: true });
68529
68654
  const files = [
68530
68655
  ["recon_deep.py", true],
68531
68656
  ["console_recon.js", true],
@@ -68533,17 +68658,17 @@ var init_local_sandbox = __esm({
68533
68658
  ["scope.txt", false]
68534
68659
  ];
68535
68660
  for (const [name25, overwrite] of files) {
68536
- const dest = import_node_path2.default.join(destDir, name25);
68661
+ const dest = import_node_path3.default.join(destDir, name25);
68537
68662
  if (!overwrite) {
68538
68663
  try {
68539
- await import_node_fs3.promises.access(dest);
68664
+ await import_node_fs4.promises.access(dest);
68540
68665
  continue;
68541
68666
  } catch {
68542
68667
  }
68543
68668
  }
68544
68669
  try {
68545
- const content = await import_node_fs3.promises.readFile(import_node_path2.default.join(assetsDir, name25));
68546
- await import_node_fs3.promises.writeFile(dest, content);
68670
+ const content = await import_node_fs4.promises.readFile(import_node_path3.default.join(assetsDir, name25));
68671
+ await import_node_fs4.promises.writeFile(dest, content);
68547
68672
  } catch {
68548
68673
  }
68549
68674
  }
@@ -68659,15 +68784,15 @@ EDITING SCRIPTS:
68659
68784
  }
68660
68785
  }
68661
68786
  resolvePath(p) {
68662
- if (import_node_path2.default.isAbsolute(p)) return p;
68663
- return import_node_path2.default.join(this.workdir, p);
68787
+ if (import_node_path3.default.isAbsolute(p)) return p;
68788
+ return import_node_path3.default.join(this.workdir, p);
68664
68789
  }
68665
68790
  isBashLikeShell() {
68666
- const base = import_node_path2.default.basename(this.shellBin).toLowerCase();
68791
+ const base = import_node_path3.default.basename(this.shellBin).toLowerCase();
68667
68792
  return base === "bash" || base === "bash.exe" || base === "sh";
68668
68793
  }
68669
68794
  isCmdShell() {
68670
- const base = import_node_path2.default.basename(this.shellBin).toLowerCase();
68795
+ const base = import_node_path3.default.basename(this.shellBin).toLowerCase();
68671
68796
  return base === "cmd" || base === "cmd.exe";
68672
68797
  }
68673
68798
  getWindowsShellNotes() {
@@ -68871,7 +68996,7 @@ function formatToolCall(toolName, input) {
68871
68996
  return `${C2.cyan}executando${C2.reset} ${C2.bold}$ ${truncate3(cmd, 400)}${C2.reset}${bg}`;
68872
68997
  }
68873
68998
  case "file": {
68874
- const path5 = String(i.path ?? "");
68999
+ const path6 = String(i.path ?? "");
68875
69000
  const brief = i.brief ? `${C2.dim} - ${truncate3(String(i.brief))}${C2.reset}` : "";
68876
69001
  const map2 = {
68877
69002
  write: `${C2.green}criando arquivo${C2.reset}`,
@@ -68882,7 +69007,7 @@ function formatToolCall(toolName, input) {
68882
69007
  };
68883
69008
  const action = typeof i.action === "string" ? i.action : "";
68884
69009
  const label = map2[action] ?? (action ? `${C2.blue}arquivo (${action})${C2.reset}` : `${C2.blue}preparando operacao de arquivo${C2.reset}`);
68885
- const target = path5 ? ` ${C2.bold}${path5}${C2.reset}` : "";
69010
+ const target = path6 ? ` ${C2.bold}${path6}${C2.reset}` : "";
68886
69011
  return `${label}${target}${brief}`;
68887
69012
  }
68888
69013
  case "todo_write":
@@ -68976,7 +69101,11 @@ async function ensureProxyReady(id, log2) {
68976
69101
  };
68977
69102
  if (await ping(healthUrl(def))) {
68978
69103
  markEnabled();
68979
- return { ok: true, message: `${def.label} j\xE1 est\xE1 no ar`, baseUrl: baseUrl(def) };
69104
+ return {
69105
+ ok: true,
69106
+ message: `${def.label} j\xE1 est\xE1 no ar`,
69107
+ baseUrl: baseUrl(def)
69108
+ };
68980
69109
  }
68981
69110
  if (!hasCommand("git") || !hasCommand("npm")) {
68982
69111
  return {
@@ -68985,17 +69114,20 @@ async function ensureProxyReady(id, log2) {
68985
69114
  };
68986
69115
  }
68987
69116
  let freshSetup = false;
68988
- if (!(0, import_node_fs4.existsSync)(dir)) {
69117
+ if (!(0, import_node_fs5.existsSync)(dir)) {
68989
69118
  log2(`${def.label}: baixando o proxy (uma vez) em ${dir} \u2026`);
68990
69119
  const root = proxiesRoot();
68991
- (0, import_node_fs4.mkdirSync)(root, { recursive: true });
69120
+ (0, import_node_fs5.mkdirSync)(root, { recursive: true });
68992
69121
  const cloned = run("git", ["clone", def.repoUrl, dir], root);
68993
- if (!cloned.ok || !(0, import_node_fs4.existsSync)(dir)) {
68994
- return { ok: false, message: `${def.label}: falha ao clonar o proxy (git).` };
69122
+ if (!cloned.ok || !(0, import_node_fs5.existsSync)(dir)) {
69123
+ return {
69124
+ ok: false,
69125
+ message: `${def.label}: falha ao clonar o proxy (git).`
69126
+ };
68995
69127
  }
68996
69128
  freshSetup = true;
68997
69129
  }
68998
- if (!(0, import_node_fs4.existsSync)(import_node_path3.default.join(dir, "node_modules"))) {
69130
+ if (!(0, import_node_fs5.existsSync)(import_node_path4.default.join(dir, "node_modules"))) {
68999
69131
  log2(`${def.label}: instalando depend\xEAncias (pode demorar) \u2026`);
69000
69132
  if (!run("npm", ["install"], dir).ok) {
69001
69133
  return { ok: false, message: `${def.label}: 'npm install' falhou.` };
@@ -69005,17 +69137,19 @@ async function ensureProxyReady(id, log2) {
69005
69137
  freshSetup = true;
69006
69138
  }
69007
69139
  if (freshSetup) {
69008
- log2(`${def.label}: abrindo o login no navegador \u2014 fa\xE7a login na sua conta\u2026`);
69140
+ log2(
69141
+ `${def.label}: abrindo o login no navegador \u2014 fa\xE7a login na sua conta\u2026`
69142
+ );
69009
69143
  if (!run("npm", ["run", "login"], dir).ok) {
69010
69144
  log2(`${def.label}: login n\xE3o confirmou; vou tentar subir mesmo assim.`);
69011
69145
  }
69012
69146
  }
69013
69147
  log2(`${def.label}: iniciando o proxy\u2026`);
69014
- const child = (0, import_node_child_process2.spawn)("npm", ["start"], {
69148
+ const child = (0, import_node_child_process2.spawn)(asShellCommand("npm", ["start"]), {
69015
69149
  cwd: dir,
69016
69150
  shell: true,
69017
69151
  stdio: ["ignore", "ignore", "ignore"],
69018
- env: childEnv()
69152
+ env: { ...childEnv(), PORT: String(def.port) }
69019
69153
  });
69020
69154
  started.add(child);
69021
69155
  child.on("exit", () => started.delete(child));
@@ -69038,13 +69172,13 @@ async function ensureProxyReady(id, log2) {
69038
69172
  message: `${def.label}: o proxy n\xE3o respondeu em 90s. Tente de novo, ou rode 'npm run login' em ${dir}.`
69039
69173
  };
69040
69174
  }
69041
- var import_node_os3, import_node_path3, import_node_fs4, import_node_child_process2, DEFS, PROXY_MODEL_KEYS, proxyIdForModelKey, proxiesRoot, dirFor, healthUrl, baseUrl, wait, started, exitHooksInstalled, run, hasCommand;
69175
+ var import_node_os3, import_node_path4, import_node_fs5, import_node_child_process2, DEFS, PROXY_MODEL_KEYS, proxyIdForModelKey, proxiesRoot, dirFor, healthUrl, baseUrl, wait, started, exitHooksInstalled, quoteArg, asShellCommand, run, hasCommand;
69042
69176
  var init_proxy_manager2 = __esm({
69043
69177
  "src/proxy-manager.ts"() {
69044
69178
  "use strict";
69045
69179
  import_node_os3 = __toESM(require("node:os"));
69046
- import_node_path3 = __toESM(require("node:path"));
69047
- import_node_fs4 = require("node:fs");
69180
+ import_node_path4 = __toESM(require("node:path"));
69181
+ import_node_fs5 = require("node:fs");
69048
69182
  import_node_child_process2 = require("node:child_process");
69049
69183
  DEFS = {
69050
69184
  deepseek: {
@@ -69077,18 +69211,20 @@ var init_proxy_manager2 = __esm({
69077
69211
  if (key === PROXY_MODEL_KEYS.kimi) return "kimi";
69078
69212
  return null;
69079
69213
  };
69080
- proxiesRoot = () => import_node_path3.default.join(
69081
- process.env.CLAWFAST_HOME?.trim() || import_node_path3.default.join(import_node_os3.default.homedir(), ".clawfast"),
69214
+ proxiesRoot = () => import_node_path4.default.join(
69215
+ process.env.CLAWFAST_HOME?.trim() || import_node_path4.default.join(import_node_os3.default.homedir(), ".clawfast"),
69082
69216
  "proxies"
69083
69217
  );
69084
- dirFor = (def) => process.env[def.dirEnv]?.trim() || import_node_path3.default.join(proxiesRoot(), def.folder);
69218
+ dirFor = (def) => process.env[def.dirEnv]?.trim() || import_node_path4.default.join(proxiesRoot(), def.folder);
69085
69219
  healthUrl = (def) => `http://localhost:${def.port}/health`;
69086
69220
  baseUrl = (def) => `http://localhost:${def.port}/v1`;
69087
69221
  wait = (ms) => new Promise((r) => setTimeout(r, ms));
69088
69222
  started = /* @__PURE__ */ new Set();
69089
69223
  exitHooksInstalled = false;
69224
+ quoteArg = (s) => /[\s"&|<>^()]/.test(s) ? `"${s.replace(/"/g, '\\"')}"` : s;
69225
+ asShellCommand = (cmd, args) => [cmd, ...args.map(quoteArg)].join(" ");
69090
69226
  run = (cmd, args, cwd) => {
69091
- const res = (0, import_node_child_process2.spawnSync)(cmd, args, {
69227
+ const res = (0, import_node_child_process2.spawnSync)(asShellCommand(cmd, args), {
69092
69228
  cwd,
69093
69229
  shell: true,
69094
69230
  stdio: "inherit",
@@ -69098,7 +69234,10 @@ var init_proxy_manager2 = __esm({
69098
69234
  };
69099
69235
  hasCommand = (cmd) => {
69100
69236
  const probe = process.platform === "win32" ? "where" : "which";
69101
- return (0, import_node_child_process2.spawnSync)(probe, [cmd], { stdio: "ignore", shell: true }).status === 0;
69237
+ return (0, import_node_child_process2.spawnSync)(asShellCommand(probe, [cmd]), {
69238
+ stdio: "ignore",
69239
+ shell: true
69240
+ }).status === 0;
69102
69241
  };
69103
69242
  }
69104
69243
  });
@@ -69240,7 +69379,7 @@ async function createAgent() {
69240
69379
  const sandboxManager = new LocalSandboxManager(sandbox);
69241
69380
  const writer = createConsoleWriter();
69242
69381
  const render = createRenderer();
69243
- const initialModelName = CLI_MODEL_CHAIN[0] ?? "agent-model";
69382
+ const initialModelName = CLI_MODEL_CHAIN[0] ?? "model-nvidia-minimax-m3";
69244
69383
  let currentModelName = initialModelName;
69245
69384
  let selectedModelKey = null;
69246
69385
  const context2 = {
@@ -69289,6 +69428,8 @@ async function createAgent() {
69289
69428
  system += pythonOnlyPolicy();
69290
69429
  system += deepReconPolicy(sandbox.getWorkdir());
69291
69430
  system += buildCliNotesSection();
69431
+ system += buildSkillsIndexSection();
69432
+ system += skillsScopePolicy();
69292
69433
  if (isWebSessionProxyModel(modelName)) {
69293
69434
  system += proxyToolProtocolPolicy();
69294
69435
  }
@@ -69326,25 +69467,18 @@ async function createAgent() {
69326
69467
  }
69327
69468
  function getUnavailableModelGroups() {
69328
69469
  const groups = [];
69329
- if (!hasEnvValue2("HUGGINGFACE_API_KEY") && !hasEnvValue2("HF_TOKEN")) {
69470
+ if (!hasEnvValue2("NVIDIA_API_KEY")) {
69330
69471
  groups.push({
69331
- provider: "Hugging Face",
69332
- reason: "faltando HUGGINGFACE_API_KEY ou HF_TOKEN em .env.local",
69472
+ provider: "NVIDIA build",
69473
+ reason: "faltando NVIDIA_API_KEY em .env.local (https://build.nvidia.com/)",
69333
69474
  models: [
69334
- "model-hf-qwen3-6-35b-a3b",
69335
- "model-hf-glm-5-1-fp8",
69336
- "model-hf-deepseek-v4-flash"
69475
+ "model-nvidia-minimax-m3",
69476
+ "model-nvidia-kimi-k2.6",
69477
+ "model-nvidia-glm-5.1",
69478
+ "model-nvidia-qwen3.5-397b"
69337
69479
  ].map((key) => ({ key, label: labelFor(key) }))
69338
69480
  });
69339
69481
  }
69340
- groups.push({
69341
- provider: "Hugging Face chat router",
69342
- reason: "indisponivel no endpoint /v1/chat/completions com a configuracao atual",
69343
- models: ["model-hf-deepseek-v4-flash-nvfp4"].map((key) => ({
69344
- key,
69345
- label: labelFor(key)
69346
- }))
69347
- });
69348
69482
  if (!hasEnvValue2("OPENAI_API_KEY")) {
69349
69483
  groups.push({
69350
69484
  provider: "OpenAI",
@@ -69439,7 +69573,11 @@ async function createAgent() {
69439
69573
  (line) => render.info(line)
69440
69574
  );
69441
69575
  if (!result.ok) {
69442
- return { ok: false, message: result.message, selection: getModelSelection() };
69576
+ return {
69577
+ ok: false,
69578
+ message: result.message,
69579
+ selection: getModelSelection()
69580
+ };
69443
69581
  }
69444
69582
  render.info(result.message);
69445
69583
  }
@@ -69494,11 +69632,20 @@ ${seen}`);
69494
69632
  }
69495
69633
  async function send(userInput, signal) {
69496
69634
  history.push({ role: "user", content: userInput });
69635
+ const matchedSkills = selectSkillsForInput(userInput);
69636
+ const turnSystem = matchedSkills.length ? system + renderSkillBodies(matchedSkills) : system;
69637
+ if (matchedSkills.length) {
69638
+ render.info(
69639
+ `\u25B8 skills ativadas: ${matchedSkills.map((s) => s.name).join(", ")}`
69640
+ );
69641
+ }
69497
69642
  let lastError = null;
69498
69643
  let autoContinues = 0;
69499
69644
  let bridgeSteps = 0;
69500
- const modelChain = getActiveModelChain();
69645
+ const modelChain = [...getActiveModelChain()];
69501
69646
  const usingFixedModel = selectedModelKey !== null;
69647
+ let rateLimitWaits = 0;
69648
+ let addedRateLimitFallbacks = false;
69502
69649
  for (let idx = 0; idx < modelChain.length; idx++) {
69503
69650
  const modelKey = modelChain[idx];
69504
69651
  currentModelName = modelKey;
@@ -69516,7 +69663,7 @@ ${seen}`);
69516
69663
  try {
69517
69664
  const result = streamText({
69518
69665
  model: myProvider.languageModel(modelKey),
69519
- system,
69666
+ system: turnSystem,
69520
69667
  messages: history,
69521
69668
  tools,
69522
69669
  stopWhen: stepCountIs(MAX_STEPS),
@@ -69634,6 +69781,17 @@ ${resultText}`
69634
69781
  }
69635
69782
  lastError = err ?? streamError;
69636
69783
  const msg = lastError instanceof Error ? lastError.message : String(lastError);
69784
+ const rateLimited = isRateLimitError(msg);
69785
+ if (rateLimited && !addedRateLimitFallbacks) {
69786
+ const extras = CLI_MODEL_CHAIN.filter((k) => !modelChain.includes(k));
69787
+ if (extras.length) {
69788
+ modelChain.push(...extras);
69789
+ addedRateLimitFallbacks = true;
69790
+ render.info(
69791
+ `\u25B8 ${labelFor(modelKey)} no limite (429) \u2014 tentando como conting\xEAncia: ${extras.map(labelFor).join(", ")}`
69792
+ );
69793
+ }
69794
+ }
69637
69795
  const hasNext = idx + 1 < modelChain.length;
69638
69796
  const hint = loginRequiredHint(msg);
69639
69797
  if (hint) {
@@ -69646,6 +69804,22 @@ ${resultText}`
69646
69804
  while (history.length && history[history.length - 1]?.role !== "user") {
69647
69805
  history.pop();
69648
69806
  }
69807
+ if (rateLimited && rateLimitWaits < MAX_RATE_LIMIT_WAITS) {
69808
+ const waitMs = Math.min(3e3 * 2 ** rateLimitWaits, 15e3);
69809
+ rateLimitWaits++;
69810
+ render.info(
69811
+ `\u25B8 rate limit \u2014 aguardando ${Math.round(waitMs / 1e3)}s antes da pr\xF3xima tentativa (Ctrl+C cancela)\u2026`
69812
+ );
69813
+ await sleep(waitMs, signal);
69814
+ if (signal?.aborted) {
69815
+ render.endTurn();
69816
+ return;
69817
+ }
69818
+ if (!hasNext) {
69819
+ idx = -1;
69820
+ continue;
69821
+ }
69822
+ }
69649
69823
  }
69650
69824
  }
69651
69825
  render.error(
@@ -69658,6 +69832,9 @@ ${resultText}`
69658
69832
  function getSystemPromptAudit() {
69659
69833
  return systemPromptAudit;
69660
69834
  }
69835
+ async function refreshSkills() {
69836
+ await rebuildSystemPrompt(currentModelName);
69837
+ }
69661
69838
  function isRunningCommand() {
69662
69839
  return sandbox.isProcessRunning();
69663
69840
  }
@@ -69673,19 +69850,20 @@ ${resultText}`
69673
69850
  sendStdin,
69674
69851
  getSystemPrompt,
69675
69852
  getSystemPromptAudit,
69853
+ refreshSkills,
69676
69854
  getModelChoices,
69677
69855
  getModelSelection,
69678
69856
  setModelSelection,
69679
69857
  close
69680
69858
  };
69681
69859
  }
69682
- var import_promises, import_node_path4, MAX_STEPS, MAX_OUTPUT_TOKENS, MAX_AUTO_CONTINUES, UNFINISHED_TAIL_RE, BENIGN_CLOSER_RE, TOOL_CALL_NUDGE, MAX_BRIDGE_STEPS, BRIDGE_RESULT_PREAMBLE, truncateBridgeSummary, isWebSessionProxyModel, proxyToolProtocolPolicy, SYSTEM_PROMPT_SOURCE, REQUIRED_SYSTEM_PROMPT_MARKERS, MODEL_LABELS, labelFor, loginRequiredHint, CLI_PYTHON_ONLY_POLICY, pythonOnlyPolicy, scriptFilePolicy, deepReconPolicy, hasEnvValue2, envFlagEnabled, CLI_PERSONALITIES, buildCliUserCustomization, buildCliNotesSection, cliGuardrailsConfig, maybeDumpSystemPrompt, auditSystemPrompt, assertFullSystemPrompt;
69860
+ var import_promises, import_node_path5, MAX_STEPS, MAX_OUTPUT_TOKENS, MAX_AUTO_CONTINUES, MAX_RATE_LIMIT_WAITS, isRateLimitError, sleep, UNFINISHED_TAIL_RE, BENIGN_CLOSER_RE, TOOL_CALL_NUDGE, MAX_BRIDGE_STEPS, BRIDGE_RESULT_PREAMBLE, truncateBridgeSummary, isWebSessionProxyModel, proxyToolProtocolPolicy, SYSTEM_PROMPT_SOURCE, REQUIRED_SYSTEM_PROMPT_MARKERS, MODEL_LABELS, labelFor, loginRequiredHint, CLI_PYTHON_ONLY_POLICY, pythonOnlyPolicy, scriptFilePolicy, deepReconPolicy, skillsScopePolicy, hasEnvValue2, envFlagEnabled, CLI_PERSONALITIES, buildCliUserCustomization, buildCliNotesSection, cliGuardrailsConfig, maybeDumpSystemPrompt, auditSystemPrompt, assertFullSystemPrompt;
69683
69861
  var init_agent = __esm({
69684
69862
  "src/agent.ts"() {
69685
69863
  "use strict";
69686
69864
  init_dist5();
69687
69865
  import_promises = require("node:fs/promises");
69688
- import_node_path4 = __toESM(require("node:path"));
69866
+ import_node_path5 = __toESM(require("node:path"));
69689
69867
  init_providers();
69690
69868
  init_system_prompt();
69691
69869
  init_notes();
@@ -69702,10 +69880,27 @@ var init_agent = __esm({
69702
69880
  init_local_sandbox_manager();
69703
69881
  init_console_writer();
69704
69882
  init_render();
69883
+ init_skills();
69705
69884
  init_proxy_manager2();
69706
69885
  MAX_STEPS = 100;
69707
69886
  MAX_OUTPUT_TOKENS = 16384;
69708
69887
  MAX_AUTO_CONTINUES = 3;
69888
+ MAX_RATE_LIMIT_WAITS = 4;
69889
+ isRateLimitError = (msg) => /\b429\b|too many requests|rate.?limit|resource_exhausted|quota|insufficient_quota/i.test(
69890
+ msg
69891
+ );
69892
+ sleep = (ms, signal) => new Promise((resolve2) => {
69893
+ if (signal?.aborted) return resolve2();
69894
+ const timer2 = setTimeout(resolve2, ms);
69895
+ signal?.addEventListener(
69896
+ "abort",
69897
+ () => {
69898
+ clearTimeout(timer2);
69899
+ resolve2();
69900
+ },
69901
+ { once: true }
69902
+ );
69903
+ });
69709
69904
  UNFINISHED_TAIL_RE = /(?::|\.\.\.|…)\s*$|\b(?:vou|irei|deixe-me|deixa eu|em seguida|pr[oó]ximo passo|agora (?:vou|irei|preciso)|let me|i(?:'|’)?ll|i will|i(?:'|’)?m going to|going to|next,? i)\b[^.!?\n]{0,120}[.!?]?\s*$/i;
69710
69905
  BENIGN_CLOSER_RE = /\b(?:let me know|just let me know|deixa eu saber|me avis(?:e|a)|qualquer (?:coisa|d[uú]vida)|fico (?:à|a) disposi[cç][aã]o)\b[^.!?:\n]{0,80}[.!?]?\s*$/i;
69711
69906
  TOOL_CALL_NUDGE = "Voc\xEA anunciou uma a\xE7\xE3o mas n\xE3o executou nenhuma ferramenta neste turno. Pare de descrever o que vai fazer e CHAME a ferramenta agora: use a ferramenta `file` (action write para criar, edit para alterar) para qualquer arquivo ou script, e `run_terminal_cmd` para rodar comandos. N\xC3O escreva o conte\xFAdo do arquivo na resposta nem cole markup de tool call \u2014 emita a chamada de ferramenta de verdade.";
@@ -69746,18 +69941,14 @@ Regras:
69746
69941
  "DANGEROUS MODE"
69747
69942
  ];
69748
69943
  MODEL_LABELS = {
69749
- "agent-model": "OpenRouter - glm-4.5-air:free",
69750
- "model-glm-4.5-air": "OpenRouter - glm-4.5-air:free",
69751
- "model-qwen3-coder": "OpenRouter - qwen3-coder:free",
69944
+ "model-nvidia-minimax-m3": "NVIDIA - minimaxai/minimax-m3",
69945
+ "model-nvidia-kimi-k2.6": "NVIDIA - moonshotai/kimi-k2.6",
69946
+ "model-nvidia-glm-5.1": "NVIDIA - z-ai/glm-5.1",
69947
+ "model-nvidia-qwen3.5-397b": "NVIDIA - qwen/qwen3.5-397b-a17b",
69752
69948
  "model-openai-chat-latest": "OpenAI - chat-latest",
69753
- "model-hf-qwen3-6-35b-a3b": "Hugging Face - Qwen3.6 35B A3B",
69754
- "model-hf-glm-5-1-fp8": "Hugging Face - GLM 5.1 FP8",
69755
- "model-hf-deepseek-v4-flash": "Hugging Face - DeepSeek V4 Flash",
69756
- "model-hf-deepseek-v4-flash-nvfp4": "Hugging Face - DeepSeek V4 Flash NVFP4",
69757
69949
  "model-deepseek-proxy": "DeepSeek - sessao web logada (deepsproxy)",
69758
69950
  "model-kimi-proxy": "Kimi - sessao web logada (kimiproxy)",
69759
69951
  "fallback-openai-chat-latest": "OpenAI - chat-latest",
69760
- "fallback-agent-model": "NVIDIA - nemotron-3-ultra-550b",
69761
69952
  "model-nvidia-nemotron": "NVIDIA - nemotron-3-ultra-550b"
69762
69953
  };
69763
69954
  labelFor = (key) => MODEL_LABELS[key] ?? key;
@@ -69827,6 +70018,17 @@ Workflow:
69827
70018
 
69828
70019
  You MAY extend the toolkit (edit recon/recon_deep.py via the file tool) when a task needs a capability it lacks \u2014 keep it Python and keep the scope gate intact. recon/console_recon.js is an in-page payload string injected by Python Playwright (page.evaluate), NOT a Node script \u2014 never run it with \`node\`.
69829
70020
  </deep_recon_tooling>`;
70021
+ skillsScopePolicy = () => `
70022
+
70023
+ <skills_scope>
70024
+ ABSOLUTE RULE FOR THIS LOCAL CLI SESSION \u2014 applies to EVERY model and EVERY task:
70025
+
70026
+ Your skills are INTERNAL to you and live ONLY in ${skillsDir()}. The skills currently installed are listed in the <skills_disponiveis> block, and the full body of a matching skill is injected in <active_skills> when relevant.
70027
+
70028
+ - To list, describe, or "analyze" YOUR skills, use <skills_disponiveis> / <active_skills>. If you need the raw text of one of your skills, read ONLY the .md files inside ${skillsDir()}.
70029
+ - NEVER treat any other skills directory on this machine as yours. Folders such as ~/.agents/skills, ~/.claude/skills, ~/.augment/skills, ~/.cursor, and any other agent/tool skill folder belong to OTHER tools and are OUT OF SCOPE \u2014 ignore them completely and never read, list, summarize, or load them as your skills.
70030
+ - Do NOT scan the filesystem hunting for "skills". When asked about your skills, answer from your internal skills above, not from a disk search.
70031
+ </skills_scope>`;
69830
70032
  hasEnvValue2 = (name25) => Boolean(process.env[name25]?.trim());
69831
70033
  envFlagEnabled = (value) => {
69832
70034
  const normalized = value?.trim().toLowerCase();
@@ -69884,7 +70086,7 @@ ${section}` : "";
69884
70086
  return null;
69885
70087
  }
69886
70088
  await (0, import_promises.mkdir)(workdir, { recursive: true });
69887
- const outputPath = import_node_path4.default.join(workdir, "system-prompt.txt");
70089
+ const outputPath = import_node_path5.default.join(workdir, "system-prompt.txt");
69888
70090
  await (0, import_promises.writeFile)(outputPath, system, "utf8");
69889
70091
  return outputPath;
69890
70092
  };
@@ -70054,8 +70256,11 @@ async function main() {
70054
70256
  let closing = false;
70055
70257
  let commandQueue = Promise.resolve();
70056
70258
  let awaitingModelSelection = false;
70259
+ let skillCreator = null;
70057
70260
  const prompt = () => {
70058
- rl.setPrompt(awaitingModelSelection ? modelPrompt() : shellPrompt2());
70261
+ rl.setPrompt(
70262
+ skillCreator ? skillPrompt(skillCreator.phase) : awaitingModelSelection ? modelPrompt() : shellPrompt2()
70263
+ );
70059
70264
  rl.prompt();
70060
70265
  };
70061
70266
  let activeAbort = null;
@@ -70108,14 +70313,235 @@ ${ui2.C.dim}Ctrl+C de novo para fechar${ui2.C.reset}
70108
70313
  process.removeAllListeners("SIGINT");
70109
70314
  process.on("SIGINT", handleSigint);
70110
70315
  rl.on("SIGINT", handleSigint);
70316
+ const printSkillList = () => {
70317
+ const skills = listSkills();
70318
+ if (skills.length === 0) {
70319
+ process.stdout.write(
70320
+ `
70321
+ ${ui2.C.dim}nenhuma skill instalada. crie uma com /skillcreator${ui2.C.reset}
70322
+ `
70323
+ );
70324
+ return;
70325
+ }
70326
+ process.stdout.write(
70327
+ `
70328
+ ${ui2.C.cyan}skills instaladas${ui2.C.reset} ${ui2.C.dim}(${skillsDir()})${ui2.C.reset}
70329
+ `
70330
+ );
70331
+ for (const s of skills) {
70332
+ const flags = s.always ? ` ${ui2.C.yellow}[sempre]${ui2.C.reset}` : "";
70333
+ process.stdout.write(
70334
+ ` ${ui2.C.green}${s.name}${ui2.C.reset}${flags} ${ui2.C.dim}\u2014${ui2.C.reset} ${s.description}
70335
+ `
70336
+ );
70337
+ }
70338
+ process.stdout.write(
70339
+ `${ui2.C.dim}remover: /skill delete <nome>${ui2.C.reset}
70340
+ `
70341
+ );
70342
+ };
70343
+ const handleSkillCommand = (input) => {
70344
+ if (input === "/skillcreator") {
70345
+ skillCreator = {
70346
+ phase: "name",
70347
+ name: "",
70348
+ description: "",
70349
+ triggers: [],
70350
+ bodyLines: []
70351
+ };
70352
+ process.stdout.write(
70353
+ `
70354
+ ${ui2.C.greenB}criar skill${ui2.C.reset} ${ui2.C.dim}(/cancelar para abortar)${ui2.C.reset}
70355
+ ${ui2.C.dim}skills ficam disponiveis para TODOS os modelos; o conteudo completo so e carregado quando o pedido casa com a skill.${ui2.C.reset}
70356
+ ${ui2.C.cyan}nome da skill?${ui2.C.reset} ${ui2.C.dim}(ex: xss-recon)${ui2.C.reset}
70357
+ `
70358
+ );
70359
+ return;
70360
+ }
70361
+ printSkillList();
70362
+ };
70363
+ const handleSkillSubcommand = async (input) => {
70364
+ const rest = input.replace(/^\/skills?\s+/, "").trim();
70365
+ const parts = rest.split(/\s+/);
70366
+ const sub = (parts.shift() ?? "").toLowerCase();
70367
+ const arg = parts.join(" ").trim();
70368
+ if (sub === "list" || sub === "ls") {
70369
+ printSkillList();
70370
+ return;
70371
+ }
70372
+ if (sub === "delete" || sub === "rm" || sub === "remove") {
70373
+ if (!arg) {
70374
+ process.stdout.write(
70375
+ `${ui2.C.yellow}uso: /skill delete <nome>${ui2.C.reset}
70376
+ `
70377
+ );
70378
+ return;
70379
+ }
70380
+ if (deleteSkill(arg)) {
70381
+ await agent.refreshSkills();
70382
+ process.stdout.write(
70383
+ `${ui2.C.green}\u2713 skill '${slugify(arg)}' removida${ui2.C.reset}
70384
+ `
70385
+ );
70386
+ } else {
70387
+ process.stdout.write(
70388
+ `${ui2.C.yellow}skill '${arg}' nao encontrada${ui2.C.reset}
70389
+ `
70390
+ );
70391
+ }
70392
+ return;
70393
+ }
70394
+ process.stdout.write(
70395
+ `${ui2.C.yellow}subcomando desconhecido: ${sub}${ui2.C.reset}
70396
+ ${ui2.C.dim}use: /skillcreator | /skills | /skill delete <nome>${ui2.C.reset}
70397
+ `
70398
+ );
70399
+ };
70400
+ const printBodyTally = (sc) => {
70401
+ const text2 = sc.bodyLines.join("\n");
70402
+ const lines = text2 ? text2.split("\n").length : 0;
70403
+ process.stdout.write(
70404
+ `${ui2.C.dim} capturado: ${lines} linhas, ${text2.length} chars \u2014 continue colando, /fim para salvar, /desfazer para remover o ultimo, /cancelar para abortar${ui2.C.reset}
70405
+ `
70406
+ );
70407
+ };
70408
+ const handleSkillCreatorLine = async (line, input) => {
70409
+ const sc = skillCreator;
70410
+ if (!sc) return;
70411
+ if (input === "/cancelar" || input === "/cancel") {
70412
+ skillCreator = null;
70413
+ process.stdout.write(
70414
+ `
70415
+ ${ui2.C.dim}criacao de skill cancelada${ui2.C.reset}
70416
+ `
70417
+ );
70418
+ return;
70419
+ }
70420
+ switch (sc.phase) {
70421
+ case "name": {
70422
+ const slug = slugify(input);
70423
+ if (!slug) {
70424
+ process.stdout.write(
70425
+ `${ui2.C.yellow}nome invalido \u2014 tente de novo${ui2.C.reset}
70426
+ `
70427
+ );
70428
+ return;
70429
+ }
70430
+ sc.name = slug;
70431
+ if (listSkills().some((s) => s.name === slug)) {
70432
+ process.stdout.write(
70433
+ `${ui2.C.yellow}ja existe uma skill '${slug}' \u2014 sera sobrescrita${ui2.C.reset}
70434
+ `
70435
+ );
70436
+ }
70437
+ sc.phase = "desc";
70438
+ process.stdout.write(
70439
+ `${ui2.C.cyan}descricao curta (1 linha)?${ui2.C.reset}
70440
+ `
70441
+ );
70442
+ return;
70443
+ }
70444
+ case "desc": {
70445
+ sc.description = input;
70446
+ sc.phase = "triggers";
70447
+ process.stdout.write(
70448
+ `${ui2.C.cyan}palavras-gatilho?${ui2.C.reset} ${ui2.C.dim}(separadas por virgula; Enter usa o proprio nome)${ui2.C.reset}
70449
+ `
70450
+ );
70451
+ return;
70452
+ }
70453
+ case "triggers": {
70454
+ const looksLikeBody = /[\r\n]/.test(input) || input.length > 200;
70455
+ if (looksLikeBody) {
70456
+ sc.triggers = [];
70457
+ sc.phase = "body";
70458
+ sc.bodyLines.push(line.replace(/\r$/, ""));
70459
+ process.stdout.write(
70460
+ `${ui2.C.yellow}isso parece a skill, nao gatilhos \u2014 capturei como conteudo.${ui2.C.reset}
70461
+ `
70462
+ );
70463
+ printBodyTally(sc);
70464
+ return;
70465
+ }
70466
+ sc.triggers = input ? input.split(",").map((t) => t.trim()).filter(Boolean) : [];
70467
+ sc.phase = "body";
70468
+ process.stdout.write(
70469
+ `${ui2.C.cyan}cole ou escreva a skill agora${ui2.C.reset} ${ui2.C.dim}(qualquer tamanho). termine com uma linha contendo so /fim${ui2.C.reset}
70470
+ `
70471
+ );
70472
+ return;
70473
+ }
70474
+ case "body": {
70475
+ if (input === "/fim") {
70476
+ const body = sc.bodyLines.join("\n").trim();
70477
+ if (!body) {
70478
+ process.stdout.write(
70479
+ `${ui2.C.yellow}corpo vazio \u2014 cole algum conteudo ou /cancelar${ui2.C.reset}
70480
+ `
70481
+ );
70482
+ return;
70483
+ }
70484
+ const res = saveSkill({
70485
+ name: sc.name,
70486
+ description: sc.description,
70487
+ triggers: sc.triggers,
70488
+ body
70489
+ });
70490
+ skillCreator = null;
70491
+ await agent.refreshSkills();
70492
+ process.stdout.write(
70493
+ `
70494
+ ${ui2.C.green}\u2713 skill '${res.skill.name}' ${res.overwritten ? "atualizada" : "criada"}${ui2.C.reset} ${ui2.C.dim}(${res.file})${ui2.C.reset}
70495
+ ${ui2.C.dim}ja disponivel para todos os modelos nesta sessao.${ui2.C.reset}
70496
+ `
70497
+ );
70498
+ return;
70499
+ }
70500
+ if (input === "/desfazer" || input === "/undo") {
70501
+ if (sc.bodyLines.length === 0) {
70502
+ process.stdout.write(
70503
+ `${ui2.C.dim}nada para desfazer${ui2.C.reset}
70504
+ `
70505
+ );
70506
+ } else {
70507
+ sc.bodyLines.pop();
70508
+ process.stdout.write(
70509
+ `${ui2.C.yellow}ultimo trecho removido.${ui2.C.reset}
70510
+ `
70511
+ );
70512
+ printBodyTally(sc);
70513
+ }
70514
+ return;
70515
+ }
70516
+ sc.bodyLines.push(line.replace(/\r$/, ""));
70517
+ printBodyTally(sc);
70518
+ return;
70519
+ }
70520
+ }
70521
+ };
70111
70522
  const handleLine = async (line) => {
70112
70523
  if (closing) return;
70113
70524
  const input = line.trim();
70525
+ if (skillCreator) {
70526
+ await handleSkillCreatorLine(line, input);
70527
+ if (!closing) prompt();
70528
+ return;
70529
+ }
70114
70530
  if (input === "/exit" || input === "/quit") {
70115
70531
  closing = true;
70116
70532
  rl.close();
70117
70533
  return;
70118
70534
  }
70535
+ if (input === "/skillcreator" || input === "/skill" || input === "/skills") {
70536
+ handleSkillCommand(input);
70537
+ if (!closing) prompt();
70538
+ return;
70539
+ }
70540
+ if (input.startsWith("/skill ") || input.startsWith("/skills ")) {
70541
+ await handleSkillSubcommand(input);
70542
+ if (!closing) prompt();
70543
+ return;
70544
+ }
70119
70545
  if (awaitingModelSelection) {
70120
70546
  if (!input || input === "cancelar" || input === "cancel" || input === "sair" || input === "q") {
70121
70547
  awaitingModelSelection = false;
@@ -70234,6 +70660,10 @@ ${ui2.C.dim}selecao de modelo cancelada${ui2.C.reset}
70234
70660
  function modelPrompt() {
70235
70661
  return "\n\x1B[96m\x1B[1mmodelo\x1B[0m\x1B[92m\x1B[1m>\x1B[0m ";
70236
70662
  }
70663
+ function skillPrompt(phase) {
70664
+ const label = phase === "name" ? "nome" : phase === "desc" ? "descricao" : phase === "triggers" ? "gatilhos" : "skill";
70665
+ return `\x1B[96m\x1B[1m${label}\x1B[0m\x1B[92m\x1B[1m>\x1B[0m `;
70666
+ }
70237
70667
  function formatModelSelection(result, options = {}) {
70238
70668
  const { C: C4 } = {
70239
70669
  C: {
@@ -70285,17 +70715,17 @@ var init_index = __esm({
70285
70715
  init_paste_input();
70286
70716
  init_boot_ui();
70287
70717
  init_config();
70718
+ init_skills();
70288
70719
  loadClawfastEnv();
70289
70720
  deepseekEnabled = /^(1|true|yes)$/i.test(process.env.DEEPSEEK_ENABLED?.trim() ?? "") || Boolean(process.env.DEEPSEEK_BASE_URL?.trim()) || Boolean(process.env.DEEPSEEK_API_KEY?.trim());
70290
70721
  configuredModelProviders = [
70291
70722
  deepseekEnabled ? "DeepSeek (proxy/web session)" : null,
70292
- process.env.OPENROUTER_API_KEY?.trim() ? "OpenRouter" : null,
70293
- process.env.HUGGINGFACE_API_KEY?.trim() || process.env.HF_TOKEN?.trim() ? "Hugging Face" : null,
70723
+ process.env.NVIDIA_API_KEY?.trim() ? "NVIDIA build" : null,
70294
70724
  process.env.OPENAI_API_KEY?.trim() ? "OpenAI" : null
70295
70725
  ].filter((name25) => Boolean(name25));
70296
70726
  if (configuredModelProviders.length === 0) {
70297
70727
  console.error(
70298
- `Nenhuma chave de modelo configurada. Defina OPENROUTER_API_KEY (ou HUGGINGFACE_API_KEY/HF_TOKEN/OPENAI_API_KEY) em ${clawfastEnvPath()} ou como vari\xE1vel de ambiente.`
70728
+ `Nenhuma chave de modelo configurada. Defina NVIDIA_API_KEY (ou OPENAI_API_KEY) em ${clawfastEnvPath()} ou como vari\xE1vel de ambiente.`
70299
70729
  );
70300
70730
  process.exit(1);
70301
70731
  }