@rely-ai/caliber 1.48.0 → 1.48.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 +56 -24
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -276,6 +276,21 @@ var init_resolve_caliber = __esm({
276
276
  }
277
277
  });
278
278
 
279
+ // src/utils/windows.ts
280
+ function quoteForWindows(arg) {
281
+ if (!arg) return '""';
282
+ if (!/[ \t\n\v"]/.test(arg)) return arg;
283
+ return '"' + arg.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\+)$/, "$1$1") + '"';
284
+ }
285
+ function bashPath(p) {
286
+ return p.replace(/\\/g, "/");
287
+ }
288
+ var init_windows = __esm({
289
+ "src/utils/windows.ts"() {
290
+ "use strict";
291
+ }
292
+ });
293
+
279
294
  // src/llm/types.ts
280
295
  var types_exports = {};
281
296
  __export(types_exports, {
@@ -961,10 +976,20 @@ function openDiffsInEditor(editor, files) {
961
976
  try {
962
977
  const leftPath = file.originalPath ?? getEmptyFilePath(file.proposedPath);
963
978
  if (IS_WINDOWS5) {
964
- const quote = (s) => `"${s}"`;
965
- spawn4([cmd, "--diff", quote(leftPath), quote(file.proposedPath)].join(" "), { shell: true, stdio: "ignore", detached: true }).unref();
979
+ spawn4(
980
+ [
981
+ quoteForWindows(cmd),
982
+ "--diff",
983
+ quoteForWindows(leftPath),
984
+ quoteForWindows(file.proposedPath)
985
+ ].join(" "),
986
+ { shell: true, stdio: "ignore", detached: true }
987
+ ).unref();
966
988
  } else {
967
- spawn4(cmd, ["--diff", leftPath, file.proposedPath], { stdio: "ignore", detached: true }).unref();
989
+ spawn4(cmd, ["--diff", leftPath, file.proposedPath], {
990
+ stdio: "ignore",
991
+ detached: true
992
+ }).unref();
968
993
  }
969
994
  } catch {
970
995
  continue;
@@ -975,6 +1000,7 @@ var IS_WINDOWS5, DIFF_TEMP_DIR;
975
1000
  var init_editor = __esm({
976
1001
  "src/utils/editor.ts"() {
977
1002
  "use strict";
1003
+ init_windows();
978
1004
  IS_WINDOWS5 = process.platform === "win32";
979
1005
  DIFF_TEMP_DIR = path25.join(os6.tmpdir(), "caliber-diff");
980
1006
  }
@@ -2622,12 +2648,8 @@ function estimateTokens(text) {
2622
2648
  return Math.ceil(text.length / 4);
2623
2649
  }
2624
2650
 
2625
- // src/utils/windows.ts
2626
- function quoteForWindows(arg) {
2627
- if (!arg) return '""';
2628
- if (!/[ \t\n\v"]/.test(arg)) return arg;
2629
- return '"' + arg.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\+)$/, "$1$1") + '"';
2630
- }
2651
+ // src/llm/cursor-acp.ts
2652
+ init_windows();
2631
2653
 
2632
2654
  // src/lib/subprocess-sentinel.ts
2633
2655
  var CALIBER_SUBPROCESS_ENV = "CALIBER_SUBPROCESS";
@@ -2977,6 +2999,7 @@ function isCursorLoggedIn() {
2977
2999
  // src/llm/claude-cli.ts
2978
3000
  import fs7 from "fs";
2979
3001
  import { spawn as spawn2, execSync as execSync7, execFileSync as execFileSync2 } from "child_process";
3002
+ init_windows();
2980
3003
  var DEFAULT_TIMEOUT_MS3 = 10 * 60 * 1e3;
2981
3004
  var IS_WINDOWS2 = process.platform === "win32";
2982
3005
  function candidateClaudePaths() {
@@ -3027,12 +3050,18 @@ function cleanClaudeEnv() {
3027
3050
  function spawnClaude(args) {
3028
3051
  const bin = resolveClaudeBin();
3029
3052
  const env = withCaliberSubprocessEnv(cleanClaudeEnv());
3030
- return IS_WINDOWS2 ? spawn2([bin, ...args].join(" "), {
3031
- cwd: process.cwd(),
3032
- stdio: ["pipe", "pipe", "pipe"],
3033
- env,
3034
- shell: true
3035
- }) : spawn2(bin, args, {
3053
+ return IS_WINDOWS2 ? (
3054
+ // Windows path: shell:true skips Node's exe quoting, so paths like
3055
+ // `C:\Program Files\caliber\claude.cmd` (with spaces) would be parsed by
3056
+ // cmd.exe as multiple words. Quote each piece explicitly. Mirrors the
3057
+ // pattern used in cursor-acp.ts and the learn-finalize background spawn.
3058
+ spawn2([quoteForWindows(bin), ...args.map(quoteForWindows)].join(" "), {
3059
+ cwd: process.cwd(),
3060
+ stdio: ["pipe", "pipe", "pipe"],
3061
+ env,
3062
+ shell: true
3063
+ })
3064
+ ) : spawn2(bin, args, {
3036
3065
  cwd: process.cwd(),
3037
3066
  stdio: ["pipe", "pipe", "pipe"],
3038
3067
  env
@@ -4607,6 +4636,7 @@ function getCursorConfigDir() {
4607
4636
 
4608
4637
  // src/lib/hooks.ts
4609
4638
  init_resolve_caliber();
4639
+ init_windows();
4610
4640
  import fs11 from "fs";
4611
4641
  import path10 from "path";
4612
4642
  import { execSync as execSync10 } from "child_process";
@@ -4794,22 +4824,24 @@ function getPrecommitBlock() {
4794
4824
  let guard;
4795
4825
  let invoke;
4796
4826
  if (npx) {
4797
- const npxBin = cmd.split(" ")[0];
4798
- if (npxBin.startsWith("/")) {
4827
+ const npxBinRaw = cmd.split(" ")[0];
4828
+ const npxBin = bashPath(npxBinRaw);
4829
+ if (path10.isAbsolute(npxBinRaw)) {
4799
4830
  guard = `[ -x "${npxBin}" ]`;
4800
- const npxArgs = cmd.slice(npxBin.length);
4831
+ const npxArgs = cmd.slice(npxBinRaw.length);
4801
4832
  invoke = `"${npxBin}"${npxArgs}`;
4802
4833
  } else {
4803
4834
  guard = "command -v npx >/dev/null 2>&1";
4804
4835
  invoke = cmd;
4805
4836
  }
4806
4837
  } else {
4807
- if (cmd.startsWith("/")) {
4808
- guard = `[ -x "${cmd}" ]`;
4838
+ const cmdBash = bashPath(cmd);
4839
+ if (path10.isAbsolute(cmd)) {
4840
+ guard = `[ -x "${cmdBash}" ]`;
4809
4841
  } else {
4810
- guard = `[ -x "${cmd}" ] || command -v "${cmd}" >/dev/null 2>&1`;
4842
+ guard = `[ -x "${cmdBash}" ] || command -v "${cmdBash}" >/dev/null 2>&1`;
4811
4843
  }
4812
- invoke = `"${cmd}"`;
4844
+ invoke = `"${cmdBash}"`;
4813
4845
  }
4814
4846
  return `${PRECOMMIT_START}
4815
4847
  if ${guard}; then
@@ -13454,6 +13486,7 @@ async function configCommand() {
13454
13486
  }
13455
13487
 
13456
13488
  // src/commands/learn.ts
13489
+ init_windows();
13457
13490
  import fs48 from "fs";
13458
13491
  import path39 from "path";
13459
13492
  import chalk23 from "chalk";
@@ -15223,10 +15256,9 @@ function parseAgentOption(value) {
15223
15256
  )
15224
15257
  ];
15225
15258
  if (agents.length === 0) {
15226
- console.error(
15259
+ throw new Error(
15227
15260
  `Invalid agent "${value}". Choose from: claude, cursor, codex, opencode, github-copilot (comma-separated for multiple)`
15228
15261
  );
15229
- process.exit(1);
15230
15262
  }
15231
15263
  return agents;
15232
15264
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rely-ai/caliber",
3
- "version": "1.48.0",
3
+ "version": "1.48.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": {