@rely-ai/caliber 1.47.1 → 1.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/bin.js +52 -19
  2. package/package.json +4 -1
package/dist/bin.js CHANGED
@@ -2629,6 +2629,20 @@ function quoteForWindows(arg) {
2629
2629
  return '"' + arg.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\+)$/, "$1$1") + '"';
2630
2630
  }
2631
2631
 
2632
+ // src/lib/subprocess-sentinel.ts
2633
+ var CALIBER_SUBPROCESS_ENV = "CALIBER_SUBPROCESS";
2634
+ var CALIBER_SUBPROCESS_LEGACY_ENV = "CALIBER_SPAWNED";
2635
+ function isCaliberSubprocess() {
2636
+ return process.env[CALIBER_SUBPROCESS_ENV] === "1";
2637
+ }
2638
+ function withCaliberSubprocessEnv(env) {
2639
+ return {
2640
+ ...env,
2641
+ [CALIBER_SUBPROCESS_ENV]: "1",
2642
+ [CALIBER_SUBPROCESS_LEGACY_ENV]: "1"
2643
+ };
2644
+ }
2645
+
2632
2646
  // src/llm/cursor-acp.ts
2633
2647
  var IS_WINDOWS = process.platform === "win32";
2634
2648
  var _agentBin = null;
@@ -2704,7 +2718,10 @@ var CursorAcpProvider = class {
2704
2718
  const targetModel = model || this.defaultModel;
2705
2719
  if (this.warmProcess && !this.warmProcess.killed && this.warmModel === targetModel) return;
2706
2720
  const args = this.buildArgs(targetModel, false);
2707
- const env = { ...process.env, ...this.cursorApiKey && { CURSOR_API_KEY: this.cursorApiKey } };
2721
+ const env = withCaliberSubprocessEnv({
2722
+ ...process.env,
2723
+ ...this.cursorApiKey && { CURSOR_API_KEY: this.cursorApiKey }
2724
+ });
2708
2725
  this.warmProcess = IS_WINDOWS ? spawn([quoteForWindows(resolveAgentBin()), ...args.map(quoteForWindows)].join(" "), {
2709
2726
  stdio: ["pipe", "pipe", "pipe"],
2710
2727
  env,
@@ -2755,7 +2772,10 @@ var CursorAcpProvider = class {
2755
2772
  return { child: warm, stderrChunks: stderrChunks2 };
2756
2773
  }
2757
2774
  const args = this.buildArgs(model, streaming);
2758
- const env = { ...process.env, ...this.cursorApiKey && { CURSOR_API_KEY: this.cursorApiKey } };
2775
+ const env = withCaliberSubprocessEnv({
2776
+ ...process.env,
2777
+ ...this.cursorApiKey && { CURSOR_API_KEY: this.cursorApiKey }
2778
+ });
2759
2779
  const child = IS_WINDOWS ? spawn([quoteForWindows(resolveAgentBin()), ...args.map(quoteForWindows)].join(" "), {
2760
2780
  stdio: ["pipe", "pipe", "pipe"],
2761
2781
  env,
@@ -3006,7 +3026,7 @@ function cleanClaudeEnv() {
3006
3026
  }
3007
3027
  function spawnClaude(args) {
3008
3028
  const bin = resolveClaudeBin();
3009
- const env = { ...cleanClaudeEnv(), CALIBER_SPAWNED: "1" };
3029
+ const env = withCaliberSubprocessEnv(cleanClaudeEnv());
3010
3030
  return IS_WINDOWS2 ? spawn2([bin, ...args].join(" "), {
3011
3031
  cwd: process.cwd(),
3012
3032
  stdio: ["pipe", "pipe", "pipe"],
@@ -3174,7 +3194,7 @@ function isClaudeCliLoggedIn() {
3174
3194
  input: "",
3175
3195
  stdio: ["pipe", "pipe", "pipe"],
3176
3196
  timeout: 5e3,
3177
- env: cleanClaudeEnv()
3197
+ env: withCaliberSubprocessEnv(cleanClaudeEnv())
3178
3198
  });
3179
3199
  const output = result.toString().trim();
3180
3200
  try {
@@ -3224,7 +3244,7 @@ function isOpenCodeLoggedIn() {
3224
3244
  return cachedLoggedIn2;
3225
3245
  }
3226
3246
  function spawnOpenCode(args) {
3227
- const env = { ...process.env, OPENCODE_DISABLE_AUTOCOMPACT: "TRUE" };
3247
+ const env = withCaliberSubprocessEnv({ ...process.env, OPENCODE_DISABLE_AUTOCOMPACT: "TRUE" });
3228
3248
  if (IS_WINDOWS3) {
3229
3249
  return spawn3([OPENCODE_BIN, ...args].join(" "), {
3230
3250
  cwd: process.cwd(),
@@ -4705,6 +4725,10 @@ function createScriptHook(config) {
4705
4725
  return { isInstalled, install, remove };
4706
4726
  }
4707
4727
  var STOP_HOOK_SCRIPT_CONTENT = `#!/bin/sh
4728
+ # Don't block headless claude sessions spawned by caliber itself (e.g. during caliber refresh)
4729
+ if [ "$CALIBER_SUBPROCESS" = "1" ] || [ -n "$CALIBER_SPAWNED" ]; then
4730
+ exit 0
4731
+ fi
4708
4732
  if grep -q "caliber" .git/hooks/pre-commit 2>/dev/null; then
4709
4733
  exit 0
4710
4734
  fi
@@ -4718,7 +4742,7 @@ printf '{"decision":"block","reason":"Caliber agent config sync is not set up on
4718
4742
  `;
4719
4743
  var stopHook = createScriptHook({
4720
4744
  eventName: "Stop",
4721
- scriptPath: path10.join(".claude", "hooks", "caliber-check-sync.sh"),
4745
+ scriptPath: path10.posix.join(".claude", "hooks", "caliber-check-sync.sh"),
4722
4746
  scriptContent: STOP_HOOK_SCRIPT_CONTENT,
4723
4747
  description: "Caliber: offer setup if not configured"
4724
4748
  });
@@ -4727,6 +4751,11 @@ var removeStopHook = stopHook.remove;
4727
4751
  function getFreshnessScript() {
4728
4752
  const bin = resolveCaliber();
4729
4753
  return `#!/bin/sh
4754
+ # Don't run inside a caliber-spawned headless session \u2014 the systemMessage would
4755
+ # pollute the spawned agent's output and serves no purpose there.
4756
+ if [ "$CALIBER_SUBPROCESS" = "1" ] || [ -n "$CALIBER_SPAWNED" ]; then
4757
+ exit 0
4758
+ fi
4730
4759
  STATE_FILE=".caliber/.caliber-state.json"
4731
4760
  [ ! -f "$STATE_FILE" ] && exit 0
4732
4761
  LAST_SHA=$(grep -o '"lastRefreshSha":"[^"]*"' "$STATE_FILE" 2>/dev/null | cut -d'"' -f4)
@@ -4741,7 +4770,7 @@ fi
4741
4770
  }
4742
4771
  var sessionStartHook = createScriptHook({
4743
4772
  eventName: "SessionStart",
4744
- scriptPath: path10.join(".claude", "hooks", "caliber-session-freshness.sh"),
4773
+ scriptPath: path10.posix.join(".claude", "hooks", "caliber-session-freshness.sh"),
4745
4774
  scriptContent: getFreshnessScript,
4746
4775
  description: "Caliber: check config freshness on session start"
4747
4776
  });
@@ -4750,7 +4779,7 @@ var installSessionStartHook = sessionStartHook.install;
4750
4779
  var removeSessionStartHook = sessionStartHook.remove;
4751
4780
  var notificationHook = createScriptHook({
4752
4781
  eventName: "Notification",
4753
- scriptPath: path10.join(".claude", "hooks", "caliber-freshness-notify.sh"),
4782
+ scriptPath: path10.posix.join(".claude", "hooks", "caliber-freshness-notify.sh"),
4754
4783
  scriptContent: getFreshnessScript,
4755
4784
  description: "Caliber: warn when agent configs are stale"
4756
4785
  });
@@ -8555,13 +8584,15 @@ function trackEvent(name, properties) {
8555
8584
  properties: { ...superProperties, ...properties }
8556
8585
  });
8557
8586
  }
8587
+ var flushPromise = null;
8558
8588
  async function flushTelemetry() {
8559
8589
  if (!client) return;
8560
- try {
8561
- await client.shutdown();
8562
- } catch {
8563
- }
8590
+ if (flushPromise) return flushPromise;
8591
+ const c = client;
8564
8592
  client = null;
8593
+ flushPromise = c.shutdown().catch(() => {
8594
+ });
8595
+ return flushPromise;
8565
8596
  }
8566
8597
 
8567
8598
  // src/telemetry/events.ts
@@ -13112,7 +13143,7 @@ async function refreshSingleRepo(repoDir, options) {
13112
13143
  }
13113
13144
  async function refreshCommand(options) {
13114
13145
  const quiet = !!options.quiet;
13115
- if (quiet && process.env.CALIBER_SPAWNED === "1") return;
13146
+ if (quiet && isCaliberSubprocess()) return;
13116
13147
  if (quiet) {
13117
13148
  const { isCaliberRunning: isCaliberRunning2 } = await Promise.resolve().then(() => (init_lock(), lock_exports));
13118
13149
  if (isCaliberRunning2()) return;
@@ -14080,7 +14111,7 @@ function readFinalizeError() {
14080
14111
  }
14081
14112
  }
14082
14113
  async function learnObserveCommand(options) {
14083
- if (process.env.CALIBER_SPAWNED === "1") return;
14114
+ if (isCaliberSubprocess()) return;
14084
14115
  try {
14085
14116
  const raw = await readStdin();
14086
14117
  if (!raw.trim()) return;
@@ -14160,7 +14191,7 @@ async function learnObserveCommand(options) {
14160
14191
  async function learnFinalizeCommand(options) {
14161
14192
  const isAuto = options?.auto === true;
14162
14193
  const isIncremental = options?.incremental === true;
14163
- if (isAuto && process.env.CALIBER_SPAWNED === "1") return;
14194
+ if (isAuto && isCaliberSubprocess()) return;
14164
14195
  if (!options?.force && !isAuto) {
14165
14196
  const { isCaliberRunning: isCaliberRunning2 } = await Promise.resolve().then(() => (init_lock(), lock_exports));
14166
14197
  if (isCaliberRunning2()) {
@@ -15383,16 +15414,17 @@ function restoreTerminal() {
15383
15414
 
15384
15415
  // src/bin.ts
15385
15416
  var signalCleanupDone = false;
15386
- function signalCleanup(code) {
15417
+ async function signalCleanup(code) {
15387
15418
  if (signalCleanupDone) return;
15388
15419
  signalCleanupDone = true;
15389
15420
  restoreTerminal();
15390
15421
  releaseLock();
15422
+ await flushTelemetry();
15391
15423
  process.exit(code);
15392
15424
  }
15393
15425
  process.on("exit", restoreTerminal);
15394
- process.on("SIGINT", () => signalCleanup(130));
15395
- process.on("SIGTERM", () => signalCleanup(143));
15426
+ process.on("SIGINT", () => void signalCleanup(130));
15427
+ process.on("SIGTERM", () => void signalCleanup(143));
15396
15428
  acquireLock();
15397
15429
  if (process.env.CALIBER_LOCAL) {
15398
15430
  process.env.CALIBER_SKIP_UPDATE_CHECK = "1";
@@ -15412,6 +15444,7 @@ program.parseAsync().catch((err) => {
15412
15444
  }).finally(async () => {
15413
15445
  releaseLock();
15414
15446
  await flushTelemetry();
15415
- process.exit(Number(process.exitCode ?? 0));
15447
+ const safetyExit = setTimeout(() => process.exit(Number(process.exitCode ?? 0)), 200);
15448
+ safetyExit.unref();
15416
15449
  });
15417
15450
  //# sourceMappingURL=bin.js.map
package/package.json CHANGED
@@ -1,13 +1,16 @@
1
1
  {
2
2
  "name": "@rely-ai/caliber",
3
- "version": "1.47.1",
3
+ "version": "1.48.0",
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": {
7
7
  "caliber": "./dist/bin.js"
8
8
  },
9
9
  "scripts": {
10
+ "prebuild": "npm run build:skills:check",
10
11
  "build": "tsup",
12
+ "build:skills": "node scripts/generate-skills.mjs",
13
+ "build:skills:check": "node scripts/generate-skills.mjs --check",
11
14
  "dev": "tsup --watch",
12
15
  "dev:install": "npm run build && npm link",
13
16
  "test": "vitest run",