@rely-ai/caliber 1.30.0-dev.1774286800 → 1.30.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/bin.js +52 -45
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -415,7 +415,7 @@ async function interactiveDiffExplorer(files) {
415
415
  stdout.write(output + "\n");
416
416
  lineCount = output.split("\n").length;
417
417
  }
418
- return new Promise((resolve2) => {
418
+ return new Promise((resolve3) => {
419
419
  console.log("");
420
420
  draw(true);
421
421
  stdin.setRawMode(true);
@@ -450,7 +450,7 @@ async function interactiveDiffExplorer(files) {
450
450
  case "":
451
451
  cleanup();
452
452
  console.log("");
453
- resolve2();
453
+ resolve3();
454
454
  break;
455
455
  }
456
456
  } else {
@@ -473,7 +473,7 @@ async function interactiveDiffExplorer(files) {
473
473
  case "":
474
474
  cleanup();
475
475
  console.log("");
476
- resolve2();
476
+ resolve3();
477
477
  break;
478
478
  }
479
479
  }
@@ -1722,7 +1722,7 @@ var CursorAcpProvider = class {
1722
1722
  return stderr ? `${base}: ${stderr.slice(0, 200)}` : base;
1723
1723
  }
1724
1724
  runPrint(model, prompt) {
1725
- return new Promise((resolve2, reject) => {
1725
+ return new Promise((resolve3, reject) => {
1726
1726
  const { child, stderrChunks } = this.spawnAgent(model, false);
1727
1727
  let settled = false;
1728
1728
  const chunks = [];
@@ -1750,7 +1750,7 @@ var CursorAcpProvider = class {
1750
1750
  if (code !== 0 && !output) {
1751
1751
  reject(new Error(this.buildErrorMessage(code, stderrChunks)));
1752
1752
  } else {
1753
- resolve2(output);
1753
+ resolve3(output);
1754
1754
  }
1755
1755
  });
1756
1756
  child.stdin.write(prompt);
@@ -1758,7 +1758,7 @@ var CursorAcpProvider = class {
1758
1758
  });
1759
1759
  }
1760
1760
  runPrintStream(model, prompt, callbacks) {
1761
- return new Promise((resolve2, reject) => {
1761
+ return new Promise((resolve3, reject) => {
1762
1762
  const { child, stderrChunks } = this.spawnAgent(model, true);
1763
1763
  let buffer = "";
1764
1764
  let endCalled = false;
@@ -1840,7 +1840,7 @@ var CursorAcpProvider = class {
1840
1840
  reject(err);
1841
1841
  }
1842
1842
  } else {
1843
- resolve2();
1843
+ resolve3();
1844
1844
  }
1845
1845
  });
1846
1846
  child.stdin.write(prompt);
@@ -1977,7 +1977,7 @@ var ClaudeCliProvider = class {
1977
1977
  return combined;
1978
1978
  }
1979
1979
  runClaudePrint(combinedPrompt, model) {
1980
- return new Promise((resolve2, reject) => {
1980
+ return new Promise((resolve3, reject) => {
1981
1981
  const args = ["-p"];
1982
1982
  if (model) args.push("--model", model);
1983
1983
  const child = spawnClaude(args);
@@ -1994,7 +1994,7 @@ var ClaudeCliProvider = class {
1994
1994
  clearTimeout(timer);
1995
1995
  const stdout = Buffer.concat(chunks).toString("utf-8").trim();
1996
1996
  if (code === 0) {
1997
- resolve2(stdout);
1997
+ resolve3(stdout);
1998
1998
  } else {
1999
1999
  const stderr = Buffer.concat(stderrChunks).toString("utf-8").trim();
2000
2000
  const friendly = parseSeatBasedError(stderr, code);
@@ -3891,7 +3891,7 @@ async function streamGeneration(config) {
3891
3891
  config.baseMaxTokens + attempt * config.tokenIncrement,
3892
3892
  config.maxTokensCap
3893
3893
  );
3894
- return new Promise((resolve2) => {
3894
+ return new Promise((resolve3) => {
3895
3895
  let preJsonBuffer = "";
3896
3896
  let jsonContent = "";
3897
3897
  let inJson = false;
@@ -3946,7 +3946,7 @@ async function streamGeneration(config) {
3946
3946
  }
3947
3947
  if (!setup && stopReason === "max_tokens" && attempt < MAX_RETRIES2) {
3948
3948
  if (config.callbacks) config.callbacks.onStatus("Output was truncated, retrying with higher token limit...");
3949
- setTimeout(() => attemptGeneration().then(resolve2), 1e3);
3949
+ setTimeout(() => attemptGeneration().then(resolve3), 1e3);
3950
3950
  return;
3951
3951
  }
3952
3952
  let explanation;
@@ -3956,24 +3956,24 @@ async function streamGeneration(config) {
3956
3956
  }
3957
3957
  if (setup) {
3958
3958
  if (config.callbacks) config.callbacks.onComplete(setup, explanation);
3959
- resolve2({ setup, explanation, stopReason: stopReason ?? void 0 });
3959
+ resolve3({ setup, explanation, stopReason: stopReason ?? void 0 });
3960
3960
  } else {
3961
- resolve2({ setup: null, explanation, raw: preJsonBuffer, stopReason: stopReason ?? void 0 });
3961
+ resolve3({ setup: null, explanation, raw: preJsonBuffer, stopReason: stopReason ?? void 0 });
3962
3962
  }
3963
3963
  },
3964
3964
  onError: (error) => {
3965
3965
  if (isTransientError2(error) && attempt < MAX_RETRIES2) {
3966
3966
  if (config.callbacks) config.callbacks.onStatus("Connection interrupted, retrying...");
3967
- setTimeout(() => attemptGeneration().then(resolve2), 2e3);
3967
+ setTimeout(() => attemptGeneration().then(resolve3), 2e3);
3968
3968
  return;
3969
3969
  }
3970
3970
  if (config.callbacks) config.callbacks.onError(error.message);
3971
- resolve2({ setup: null, raw: error.message, stopReason: "error" });
3971
+ resolve3({ setup: null, raw: error.message, stopReason: "error" });
3972
3972
  }
3973
3973
  }
3974
3974
  ).catch((error) => {
3975
3975
  if (config.callbacks) config.callbacks.onError(error.message);
3976
- resolve2({ setup: null, raw: error.message, stopReason: "error" });
3976
+ resolve3({ setup: null, raw: error.message, stopReason: "error" });
3977
3977
  });
3978
3978
  });
3979
3979
  };
@@ -5066,10 +5066,10 @@ import chalk2 from "chalk";
5066
5066
  import readline from "readline";
5067
5067
  function promptInput(question) {
5068
5068
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
5069
- return new Promise((resolve2) => {
5069
+ return new Promise((resolve3) => {
5070
5070
  rl.question(chalk2.cyan(`${question} `), (answer) => {
5071
5071
  rl.close();
5072
- resolve2(answer.trim());
5072
+ resolve3(answer.trim());
5073
5073
  });
5074
5074
  });
5075
5075
  }
@@ -6371,7 +6371,7 @@ import chalk6 from "chalk";
6371
6371
  import ora from "ora";
6372
6372
  import select3 from "@inquirer/select";
6373
6373
  import { mkdirSync, readFileSync as readFileSync4, readdirSync as readdirSync4, existsSync as existsSync8, writeFileSync } from "fs";
6374
- import { join as join10, dirname as dirname2 } from "path";
6374
+ import { join as join10, dirname as dirname2, resolve as resolve2 } from "path";
6375
6375
  init_config();
6376
6376
 
6377
6377
  // src/telemetry/index.ts
@@ -6408,11 +6408,12 @@ function getMachineId() {
6408
6408
  writeConfig({ ...config, machineId });
6409
6409
  return machineId;
6410
6410
  }
6411
+ var EMAIL_HASH_KEY = "caliber-telemetry-v1";
6411
6412
  function getGitEmailHash() {
6412
6413
  try {
6413
6414
  const email = execSync12("git config user.email", { encoding: "utf-8" }).trim();
6414
6415
  if (!email) return void 0;
6415
- return crypto4.createHash("sha256").update(email).digest("hex");
6416
+ return crypto4.createHmac("sha256", EMAIL_HASH_KEY).update(email).digest("hex");
6416
6417
  } catch {
6417
6418
  return void 0;
6418
6419
  }
@@ -6581,14 +6582,19 @@ function detectLocalPlatforms() {
6581
6582
  }
6582
6583
  return platforms.size > 0 ? Array.from(platforms) : ["claude"];
6583
6584
  }
6585
+ function sanitizeSlug(slug) {
6586
+ return slug.replace(/[^a-zA-Z0-9_\-]/g, "-").replace(/^-+|-+$/g, "");
6587
+ }
6584
6588
  function getSkillPath(platform, slug) {
6585
- if (platform === "cursor") {
6586
- return join10(".cursor", "skills", slug, "SKILL.md");
6587
- }
6588
- if (platform === "codex") {
6589
- return join10(".agents", "skills", slug, "SKILL.md");
6589
+ const safe = sanitizeSlug(slug);
6590
+ if (!safe) throw new Error(`Invalid skill slug: "${slug}"`);
6591
+ const baseDir = platform === "cursor" ? join10(".cursor", "skills") : platform === "codex" ? join10(".agents", "skills") : join10(".claude", "skills");
6592
+ const cwd = process.cwd();
6593
+ const fullPath = resolve2(cwd, baseDir, safe, "SKILL.md");
6594
+ if (!fullPath.startsWith(resolve2(cwd, baseDir) + "/")) {
6595
+ throw new Error(`Skill path escapes base directory: "${slug}"`);
6590
6596
  }
6591
- return join10(".claude", "skills", slug, "SKILL.md");
6597
+ return join10(baseDir, safe, "SKILL.md");
6592
6598
  }
6593
6599
  function getSkillDir(platform) {
6594
6600
  if (platform === "cursor") return join10(process.cwd(), ".cursor", "skills");
@@ -7121,7 +7127,7 @@ async function interactiveSelect(recs) {
7121
7127
  stdout.write(output + "\n");
7122
7128
  lineCount = output.split("\n").length;
7123
7129
  }
7124
- return new Promise((resolve2) => {
7130
+ return new Promise((resolve3) => {
7125
7131
  console.log("");
7126
7132
  draw(true);
7127
7133
  stdin.setRawMode(true);
@@ -7159,9 +7165,9 @@ async function interactiveSelect(recs) {
7159
7165
  cleanup();
7160
7166
  if (selected.size === 0) {
7161
7167
  console.log(chalk6.dim("\n No skills selected.\n"));
7162
- resolve2(null);
7168
+ resolve3(null);
7163
7169
  } else {
7164
- resolve2(Array.from(selected).sort().map((i) => recs[i]));
7170
+ resolve3(Array.from(selected).sort().map((i) => recs[i]));
7165
7171
  }
7166
7172
  break;
7167
7173
  case "q":
@@ -7169,7 +7175,7 @@ async function interactiveSelect(recs) {
7169
7175
  case "":
7170
7176
  cleanup();
7171
7177
  console.log(chalk6.dim("\n Cancelled.\n"));
7172
- resolve2(null);
7178
+ resolve3(null);
7173
7179
  break;
7174
7180
  }
7175
7181
  }
@@ -8089,7 +8095,7 @@ ${JSON.stringify(currentSetup, null, 2)}
8089
8095
  User request: ${message}
8090
8096
 
8091
8097
  Return the complete updated AgentSetup JSON incorporating the user's changes. Respond with ONLY the JSON.`;
8092
- return new Promise((resolve2) => {
8098
+ return new Promise((resolve3) => {
8093
8099
  let buffer = "";
8094
8100
  provider.stream(
8095
8101
  {
@@ -8109,20 +8115,20 @@ Return the complete updated AgentSetup JSON incorporating the user's changes. Re
8109
8115
  try {
8110
8116
  const setup = JSON.parse(jsonToParse);
8111
8117
  if (callbacks) callbacks.onComplete(setup);
8112
- resolve2(setup);
8118
+ resolve3(setup);
8113
8119
  } catch {
8114
8120
  if (callbacks) callbacks.onError("Failed to parse AI response. Try rephrasing your request.");
8115
- resolve2(null);
8121
+ resolve3(null);
8116
8122
  }
8117
8123
  },
8118
8124
  onError: (error) => {
8119
8125
  if (callbacks) callbacks.onError(error.message);
8120
- resolve2(null);
8126
+ resolve3(null);
8121
8127
  }
8122
8128
  }
8123
8129
  ).catch((error) => {
8124
8130
  if (callbacks) callbacks.onError(error.message);
8125
- resolve2(null);
8131
+ resolve3(null);
8126
8132
  });
8127
8133
  });
8128
8134
  }
@@ -10394,7 +10400,7 @@ async function hooksCommand(options) {
10394
10400
  stdout.write(output + "\n");
10395
10401
  lineCount = output.split("\n").length;
10396
10402
  }
10397
- return new Promise((resolve2) => {
10403
+ return new Promise((resolve3) => {
10398
10404
  console.log("");
10399
10405
  draw(true);
10400
10406
  stdin.setRawMode(true);
@@ -10452,14 +10458,14 @@ async function hooksCommand(options) {
10452
10458
  case "\n":
10453
10459
  cleanup();
10454
10460
  apply();
10455
- resolve2();
10461
+ resolve3();
10456
10462
  break;
10457
10463
  case "q":
10458
10464
  case "\x1B":
10459
10465
  case "":
10460
10466
  cleanup();
10461
10467
  console.log(chalk20.dim("\n Cancelled.\n"));
10462
- resolve2();
10468
+ resolve3();
10463
10469
  break;
10464
10470
  }
10465
10471
  }
@@ -10519,21 +10525,21 @@ import chalk23 from "chalk";
10519
10525
  // src/learner/stdin.ts
10520
10526
  var STDIN_TIMEOUT_MS = 5e3;
10521
10527
  function readStdin() {
10522
- return new Promise((resolve2, reject) => {
10528
+ return new Promise((resolve3, reject) => {
10523
10529
  if (process.stdin.isTTY) {
10524
- resolve2("");
10530
+ resolve3("");
10525
10531
  return;
10526
10532
  }
10527
10533
  const chunks = [];
10528
10534
  const timer = setTimeout(() => {
10529
10535
  process.stdin.removeAllListeners();
10530
10536
  process.stdin.destroy();
10531
- resolve2(Buffer.concat(chunks).toString("utf-8"));
10537
+ resolve3(Buffer.concat(chunks).toString("utf-8"));
10532
10538
  }, STDIN_TIMEOUT_MS);
10533
10539
  process.stdin.on("data", (chunk) => chunks.push(chunk));
10534
10540
  process.stdin.on("end", () => {
10535
10541
  clearTimeout(timer);
10536
- resolve2(Buffer.concat(chunks).toString("utf-8"));
10542
+ resolve3(Buffer.concat(chunks).toString("utf-8"));
10537
10543
  });
10538
10544
  process.stdin.on("error", (err) => {
10539
10545
  clearTimeout(timer);
@@ -12031,7 +12037,7 @@ learn.command("add <content>").description("Add a learning directly (used by age
12031
12037
  import fs48 from "fs";
12032
12038
  import path39 from "path";
12033
12039
  import { fileURLToPath as fileURLToPath2 } from "url";
12034
- import { execSync as execSync16 } from "child_process";
12040
+ import { execSync as execSync16, execFileSync as execFileSync3 } from "child_process";
12035
12041
  import chalk27 from "chalk";
12036
12042
  import ora8 from "ora";
12037
12043
  import confirm2 from "@inquirer/confirm";
@@ -12107,9 +12113,10 @@ Update available: ${current} -> ${latest}`)
12107
12113
  return;
12108
12114
  }
12109
12115
  const tag = channel === "latest" ? latest : channel;
12116
+ if (!/^[\w.\-]+$/.test(tag)) return;
12110
12117
  const spinner = ora8("Updating caliber...").start();
12111
12118
  try {
12112
- execSync16(`npm install -g @rely-ai/caliber@${tag}`, {
12119
+ execFileSync3("npm", ["install", "-g", `@rely-ai/caliber@${tag}`], {
12113
12120
  stdio: "pipe",
12114
12121
  timeout: 12e4,
12115
12122
  env: { ...process.env, npm_config_fund: "false", npm_config_audit: "false" }
@@ -12126,7 +12133,7 @@ Update available: ${current} -> ${latest}`)
12126
12133
  console.log(chalk27.dim(`
12127
12134
  Restarting: caliber ${args.join(" ")}
12128
12135
  `));
12129
- execSync16(`caliber ${args.map((a) => JSON.stringify(a)).join(" ")}`, {
12136
+ execFileSync3("caliber", args, {
12130
12137
  stdio: "inherit",
12131
12138
  env: { ...process.env, CALIBER_SKIP_UPDATE_CHECK: "1" }
12132
12139
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rely-ai/caliber",
3
- "version": "1.30.0-dev.1774286800",
3
+ "version": "1.30.1",
4
4
  "description": "AI context infrastructure for coding agents — keeps CLAUDE.md, Cursor rules, and skills in sync as your codebase evolves",
5
5
  "type": "module",
6
6
  "bin": {