@rely-ai/caliber 1.49.1 → 1.49.4

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 +123 -37
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -333,6 +333,19 @@ __export(pre_commit_block_exports, {
333
333
  hasSyncBlock: () => hasSyncBlock,
334
334
  stripManagedBlocks: () => stripManagedBlocks
335
335
  });
336
+ function getManagedDocPaths(activeTargets) {
337
+ if (!activeTargets) {
338
+ return "CLAUDE.md .claude/ .cursor/ .cursorrules .github/copilot-instructions.md .github/instructions/ AGENTS.md CALIBER_LEARNINGS.md .agents/ .opencode/";
339
+ }
340
+ const paths = ["CALIBER_LEARNINGS.md"];
341
+ if (activeTargets.includes("claude")) paths.push("CLAUDE.md", ".claude/");
342
+ if (activeTargets.includes("cursor")) paths.push(".cursor/", ".cursorrules");
343
+ if (activeTargets.includes("github-copilot"))
344
+ paths.push(".github/copilot-instructions.md", ".github/instructions/");
345
+ if (activeTargets.includes("codex")) paths.push("AGENTS.md", ".agents/");
346
+ if (activeTargets.includes("opencode")) paths.push(".opencode/");
347
+ return paths.join(" ");
348
+ }
336
349
  function getCaliberNotFoundFallback(platform, bin) {
337
350
  switch (platform) {
338
351
  case "claude":
@@ -347,8 +360,9 @@ npx @rely-ai/caliber refresh
347
360
  \`\`\``;
348
361
  }
349
362
  }
350
- function getPreCommitBlock(platform = "claude") {
363
+ function getPreCommitBlock(platform = "claude", activeTargets) {
351
364
  const bin = displayCaliberName();
365
+ const docPaths = getManagedDocPaths(activeTargets);
352
366
  return `${BLOCK_START}
353
367
  ## Before Committing
354
368
 
@@ -362,7 +376,7 @@ grep -q "caliber" .git/hooks/pre-commit 2>/dev/null && echo "hook-active" || ech
362
376
  - If **hook-active**: the hook handles sync automatically \u2014 just commit normally. Tell the user: "Caliber will sync your agent configs automatically via the pre-commit hook."
363
377
  - If **no-hook**: run Caliber manually before committing:
364
378
  1. Tell the user: "Caliber: Syncing agent configs with your latest changes..."
365
- 2. Run: \`${bin} refresh && git add ${MANAGED_DOC_PATHS} 2>/dev/null\`
379
+ 2. Run: \`${bin} refresh && git add ${docPaths} 2>/dev/null\`
366
380
  3. After it completes, briefly tell the user what Caliber updated. Then proceed with the commit.
367
381
 
368
382
  **Valid \`${bin} refresh\` options:** \`--quiet\` (suppress output) and \`--dry-run\` (preview without writing). Do not pass any other flags \u2014 options like \`--auto-approve\`, \`--debug\`, or \`--force\` do not exist and will cause errors.
@@ -372,8 +386,9 @@ grep -q "caliber" .git/hooks/pre-commit 2>/dev/null && echo "hook-active" || ech
372
386
  ${getCaliberNotFoundFallback(platform, bin)}
373
387
  ${BLOCK_END}`;
374
388
  }
375
- function getCursorRuleContent() {
389
+ function getCursorRuleContent(activeTargets) {
376
390
  const bin = displayCaliberName();
391
+ const docPaths = getManagedDocPaths(activeTargets);
377
392
  return `---
378
393
  description: Run Caliber sync before git commits to keep agent configs up to date
379
394
  alwaysApply: true
@@ -382,7 +397,7 @@ Before every git commit, check if the Caliber pre-commit hook is installed:
382
397
  Run: \`grep -q "caliber" .git/hooks/pre-commit 2>/dev/null && echo "hook-active" || echo "no-hook"\`
383
398
 
384
399
  If hook-active: just commit normally \u2014 Caliber syncs automatically via the hook. Tell the user: "Caliber will sync your agent configs automatically."
385
- If no-hook: run \`${bin} refresh && git add ${MANAGED_DOC_PATHS} 2>/dev/null\` before committing, and tell the user what was updated.
400
+ If no-hook: run \`${bin} refresh && git add ${docPaths} 2>/dev/null\` before committing, and tell the user what was updated.
386
401
 
387
402
  Valid \`${bin} refresh\` options: \`--quiet\` and \`--dry-run\` only. Do not pass \`--auto-approve\`, \`--debug\`, \`--force\`, or any other flags.
388
403
  \`${bin} config\` takes no flags \u2014 it is interactive. Do not pass \`--provider\`, \`--api-key\`, or \`--endpoint\`.
@@ -390,19 +405,34 @@ Valid \`${bin} refresh\` options: \`--quiet\` and \`--dry-run\` only. Do not pas
390
405
  If \`${bin}\` is not found, read the setup-caliber skill from .cursor/skills/setup-caliber/SKILL.md and follow its instructions to install Caliber.
391
406
  `;
392
407
  }
408
+ function getSectionBody(content, headingRe) {
409
+ const match = content.match(headingRe);
410
+ if (!match || match.index === void 0) return null;
411
+ const start = match.index + match[0].length;
412
+ const tail = content.slice(start);
413
+ const nextHeadingMatch = tail.match(/^##\s/m);
414
+ const end = nextHeadingMatch?.index ?? tail.length;
415
+ return tail.slice(0, end);
416
+ }
393
417
  function hasPreCommitBlock(content) {
394
- return content.includes(BLOCK_START);
418
+ if (content.includes(BLOCK_START)) return true;
419
+ const body = getSectionBody(content, PRECOMMIT_HEADING_RE);
420
+ if (body && /caliber/i.test(body)) return true;
421
+ return false;
395
422
  }
396
- function appendPreCommitBlock(content, platform = "claude") {
423
+ function appendPreCommitBlock(content, platform = "claude", activeTargets) {
397
424
  if (hasPreCommitBlock(content)) return content;
398
425
  const trimmed = content.trimEnd();
399
- return trimmed + "\n\n" + getPreCommitBlock(platform) + "\n";
426
+ return trimmed + "\n\n" + getPreCommitBlock(platform, activeTargets) + "\n";
400
427
  }
401
- function getCursorPreCommitRule() {
402
- return { filename: CURSOR_RULE_FILENAME, content: getCursorRuleContent() };
428
+ function getCursorPreCommitRule(activeTargets) {
429
+ return { filename: CURSOR_RULE_FILENAME, content: getCursorRuleContent(activeTargets) };
403
430
  }
404
431
  function hasLearningsBlock(content) {
405
- return content.includes(LEARNINGS_BLOCK_START);
432
+ if (content.includes(LEARNINGS_BLOCK_START)) return true;
433
+ const body = getSectionBody(content, LEARNINGS_HEADING_RE);
434
+ if (body && /CALIBER_LEARNINGS/.test(body)) return true;
435
+ return false;
406
436
  }
407
437
  function appendLearningsBlock(content) {
408
438
  if (hasLearningsBlock(content)) return content;
@@ -424,50 +454,59 @@ Pin your choice (\`/model\` in Claude Code, or \`CALIBER_MODEL\` when using Cali
424
454
  ${MODEL_BLOCK_END}`;
425
455
  }
426
456
  function hasModelBlock(content) {
427
- return content.includes(MODEL_BLOCK_START);
457
+ if (content.includes(MODEL_BLOCK_START)) return true;
458
+ const body = getSectionBody(content, MODEL_HEADING_RE);
459
+ if (body && /CALIBER_MODEL/.test(body)) return true;
460
+ return false;
428
461
  }
429
462
  function appendModelBlock(content) {
430
463
  if (hasModelBlock(content)) return content;
431
464
  const trimmed = content.trimEnd();
432
465
  return trimmed + "\n\n" + buildManagedModelBlock() + "\n";
433
466
  }
434
- function getSyncSetupInstruction(platform) {
467
+ function getSyncSetupInstruction(platform, activeTargets) {
435
468
  switch (platform) {
436
469
  case "claude":
437
470
  return `If the pre-commit hook is not set up, run \`/setup-caliber\` to configure everything automatically.`;
438
471
  case "codex":
439
472
  return `If the pre-commit hook is not set up, read \`.agents/skills/setup-caliber/SKILL.md\` and follow the setup instructions.`;
440
- case "copilot":
473
+ case "copilot": {
474
+ const docPaths = getManagedDocPaths(activeTargets);
441
475
  return `If the pre-commit hook is not set up, the developer should run \`/setup-caliber\` in Claude Code or Cursor for automated setup. Alternatively, run in terminal:
442
476
  \`\`\`bash
443
477
  npx @rely-ai/caliber hooks --install
444
478
  npx @rely-ai/caliber refresh
445
- git add ${MANAGED_DOC_PATHS} 2>/dev/null
479
+ git add ${docPaths} 2>/dev/null
446
480
  \`\`\``;
481
+ }
447
482
  }
448
483
  }
449
- function getSyncBlock(platform = "claude") {
484
+ function getSyncBlock(platform = "claude", activeTargets) {
450
485
  const bin = displayCaliberName();
451
486
  return `${SYNC_BLOCK_START}
452
487
  ## Context Sync
453
488
 
454
489
  This project uses [Caliber](https://github.com/caliber-ai-org/ai-setup) to keep AI agent configs in sync across Claude Code, Cursor, Copilot, and Codex.
455
490
  Configs update automatically before each commit via \`${bin} refresh\`.
456
- ${getSyncSetupInstruction(platform)}
491
+ ${getSyncSetupInstruction(platform, activeTargets)}
457
492
  ${SYNC_BLOCK_END}`;
458
493
  }
459
494
  function hasSyncBlock(content) {
460
- return content.includes(SYNC_BLOCK_START);
495
+ if (content.includes(SYNC_BLOCK_START)) return true;
496
+ const body = getSectionBody(content, SYNC_HEADING_RE);
497
+ if (body && /caliber-ai-org\/ai-setup/.test(body)) return true;
498
+ return false;
461
499
  }
462
- function appendSyncBlock(content, platform = "claude") {
500
+ function appendSyncBlock(content, platform = "claude", activeTargets) {
463
501
  if (hasSyncBlock(content)) return content;
464
502
  const trimmed = content.trimEnd();
465
- return trimmed + "\n\n" + getSyncBlock(platform) + "\n";
503
+ return trimmed + "\n\n" + getSyncBlock(platform, activeTargets) + "\n";
466
504
  }
467
- function appendManagedBlocks(content, platform = "claude") {
505
+ function appendManagedBlocks(content, platform = "claude", activeTargets) {
468
506
  return appendSyncBlock(
469
- appendModelBlock(appendLearningsBlock(appendPreCommitBlock(content, platform))),
470
- platform
507
+ appendModelBlock(appendLearningsBlock(appendPreCommitBlock(content, platform, activeTargets))),
508
+ platform,
509
+ activeTargets
471
510
  );
472
511
  }
473
512
  function getCursorSyncContent() {
@@ -513,7 +552,7 @@ function stripManagedBlocks(content) {
513
552
  }
514
553
  return result.replace(/\n{3,}/g, "\n\n").trim() + "\n";
515
554
  }
516
- var BLOCK_START, BLOCK_END, MANAGED_DOC_PATHS, CURSOR_RULE_FILENAME, LEARNINGS_BLOCK_START, LEARNINGS_BLOCK_END, LEARNINGS_BLOCK, CURSOR_LEARNINGS_FILENAME, CURSOR_LEARNINGS_CONTENT, MODEL_BLOCK_START, MODEL_BLOCK_END, SYNC_BLOCK_START, SYNC_BLOCK_END, CURSOR_SYNC_FILENAME, CURSOR_SETUP_FILENAME, MANAGED_BLOCK_PAIRS;
555
+ var BLOCK_START, BLOCK_END, CURSOR_RULE_FILENAME, PRECOMMIT_HEADING_RE, LEARNINGS_BLOCK_START, LEARNINGS_BLOCK_END, LEARNINGS_BLOCK, CURSOR_LEARNINGS_FILENAME, CURSOR_LEARNINGS_CONTENT, LEARNINGS_HEADING_RE, MODEL_BLOCK_START, MODEL_BLOCK_END, MODEL_HEADING_RE, SYNC_BLOCK_START, SYNC_BLOCK_END, SYNC_HEADING_RE, CURSOR_SYNC_FILENAME, CURSOR_SETUP_FILENAME, MANAGED_BLOCK_PAIRS;
517
556
  var init_pre_commit_block = __esm({
518
557
  "src/writers/pre-commit-block.ts"() {
519
558
  "use strict";
@@ -521,8 +560,8 @@ var init_pre_commit_block = __esm({
521
560
  init_config();
522
561
  BLOCK_START = "<!-- caliber:managed:pre-commit -->";
523
562
  BLOCK_END = "<!-- /caliber:managed:pre-commit -->";
524
- MANAGED_DOC_PATHS = "CLAUDE.md .claude/ .cursor/ .cursorrules .github/copilot-instructions.md .github/instructions/ AGENTS.md CALIBER_LEARNINGS.md .agents/ .opencode/";
525
563
  CURSOR_RULE_FILENAME = "caliber-pre-commit.mdc";
564
+ PRECOMMIT_HEADING_RE = /^##\s+Before Committing\s*$/m;
526
565
  LEARNINGS_BLOCK_START = "<!-- caliber:managed:learnings -->";
527
566
  LEARNINGS_BLOCK_END = "<!-- /caliber:managed:learnings -->";
528
567
  LEARNINGS_BLOCK = `${LEARNINGS_BLOCK_START}
@@ -539,10 +578,13 @@ alwaysApply: true
539
578
  Read \`CALIBER_LEARNINGS.md\` for patterns and anti-patterns learned from previous sessions.
540
579
  These are auto-extracted from real tool usage \u2014 treat them as project-specific rules.
541
580
  `;
581
+ LEARNINGS_HEADING_RE = /^##\s+Session Learnings\s*$/m;
542
582
  MODEL_BLOCK_START = "<!-- caliber:managed:model-config -->";
543
583
  MODEL_BLOCK_END = "<!-- /caliber:managed:model-config -->";
584
+ MODEL_HEADING_RE = /^##\s+Model Configuration\s*$/m;
544
585
  SYNC_BLOCK_START = "<!-- caliber:managed:sync -->";
545
586
  SYNC_BLOCK_END = "<!-- /caliber:managed:sync -->";
587
+ SYNC_HEADING_RE = /^##\s+Context Sync\s*$/m;
546
588
  CURSOR_SYNC_FILENAME = "caliber-sync.mdc";
547
589
  CURSOR_SETUP_FILENAME = "caliber-setup.mdc";
548
590
  MANAGED_BLOCK_PAIRS = [
@@ -2645,17 +2687,25 @@ function extractJson(text) {
2645
2687
  function stripMarkdownFences(text) {
2646
2688
  return text.replace(/^```(?:json)?\s*/im, "").replace(/```\s*$/m, "").trim();
2647
2689
  }
2690
+ function isJsonObject(value) {
2691
+ return value !== null && typeof value === "object";
2692
+ }
2648
2693
  function parseJsonResponse(raw) {
2649
2694
  const cleaned = stripMarkdownFences(raw);
2650
2695
  try {
2651
- return JSON.parse(cleaned);
2696
+ const parsed = JSON.parse(cleaned);
2697
+ if (isJsonObject(parsed)) return parsed;
2652
2698
  } catch {
2653
2699
  }
2654
2700
  const json = extractJson(cleaned);
2655
2701
  if (!json) {
2656
- throw new Error(`No JSON found in LLM response: ${raw.slice(0, 200)}`);
2702
+ throw new Error(`No valid JSON object in LLM response: ${raw.slice(0, 200)}`);
2657
2703
  }
2658
- return JSON.parse(json);
2704
+ const extracted = JSON.parse(json);
2705
+ if (!isJsonObject(extracted)) {
2706
+ throw new Error(`No valid JSON object in LLM response: ${raw.slice(0, 200)}`);
2707
+ }
2708
+ return extracted;
2659
2709
  }
2660
2710
  function estimateTokens(text) {
2661
2711
  return Math.ceil(text.length / 4);
@@ -2677,6 +2727,12 @@ function withCaliberSubprocessEnv(env) {
2677
2727
  [CALIBER_SUBPROCESS_LEGACY_ENV]: "1"
2678
2728
  };
2679
2729
  }
2730
+ function isHookCascadeFromUserClaudeSession() {
2731
+ const inClaudeSession = process.env.CLAUDECODE === "1";
2732
+ const isCaliberSpawned = process.env[CALIBER_SUBPROCESS_ENV] === "1";
2733
+ const isInteractiveTty = process.stdin.isTTY === true;
2734
+ return inClaudeSession && !isCaliberSpawned && !isInteractiveTty;
2735
+ }
2680
2736
 
2681
2737
  // src/llm/cursor-acp.ts
2682
2738
  var IS_WINDOWS = process.platform === "win32";
@@ -3001,9 +3057,10 @@ function isCursorLoggedIn() {
3001
3057
  const result = execFileSync(resolveAgentBin(), ["status"], {
3002
3058
  input: "",
3003
3059
  stdio: ["pipe", "pipe", "pipe"],
3004
- timeout: 5e3
3060
+ timeout: 5e3,
3061
+ env: withCaliberSubprocessEnv({ ...process.env })
3005
3062
  });
3006
- return !result.toString().includes("not logged in");
3063
+ return !result.toString().toLowerCase().includes("not logged in");
3007
3064
  } catch {
3008
3065
  return false;
3009
3066
  }
@@ -5600,7 +5657,8 @@ var CORE_MAX_TOKENS = 16e3;
5600
5657
  var GENERATION_MAX_TOKENS = 64e3;
5601
5658
  var MODEL_MAX_OUTPUT_TOKENS = 128e3;
5602
5659
  var MAX_RETRIES2 = 5;
5603
- var DEFAULT_INACTIVITY_TIMEOUT_MS = 12e4;
5660
+ var DEFAULT_INACTIVITY_TIMEOUT_MS = 3e5;
5661
+ var SOFT_INACTIVITY_WARN_MS = 6e4;
5604
5662
  var DEFAULT_TOTAL_TIMEOUT_MS = 6e5;
5605
5663
  function parseEnvTimeout(envVar, defaultMs, minMs = 5e3) {
5606
5664
  const val = process.env[envVar];
@@ -5853,14 +5911,30 @@ async function streamGeneration(config) {
5853
5911
  let charsReceived = 0;
5854
5912
  let settled = false;
5855
5913
  let inactivityTimer = null;
5914
+ let softWarnTimer = null;
5915
+ let softWarnFired = false;
5856
5916
  function clearInactivityTimer() {
5857
5917
  if (inactivityTimer) {
5858
5918
  clearTimeout(inactivityTimer);
5859
5919
  inactivityTimer = null;
5860
5920
  }
5921
+ if (softWarnTimer) {
5922
+ clearTimeout(softWarnTimer);
5923
+ softWarnTimer = null;
5924
+ }
5861
5925
  }
5862
5926
  function resetInactivityTimer() {
5863
5927
  if (inactivityTimer) clearTimeout(inactivityTimer);
5928
+ if (softWarnTimer) clearTimeout(softWarnTimer);
5929
+ if (config.callbacks && !softWarnFired && SOFT_INACTIVITY_WARN_MS < inactivityTimeoutMs) {
5930
+ softWarnTimer = setTimeout(() => {
5931
+ if (settled) return;
5932
+ softWarnFired = true;
5933
+ config.callbacks?.onStatus(
5934
+ "Model is taking longer than usual on this prompt \u2014 large repos may need more time. Set CALIBER_STREAM_INACTIVITY_TIMEOUT_MS to override."
5935
+ );
5936
+ }, SOFT_INACTIVITY_WARN_MS);
5937
+ }
5864
5938
  inactivityTimer = setTimeout(() => {
5865
5939
  if (settled) return;
5866
5940
  settled = true;
@@ -6333,7 +6407,7 @@ function writeClaudeConfig(config) {
6333
6407
  const written = [];
6334
6408
  fs13.writeFileSync(
6335
6409
  "CLAUDE.md",
6336
- appendManagedBlocks(config.claudeMd)
6410
+ appendManagedBlocks(config.claudeMd, "claude", config.activeTargets)
6337
6411
  );
6338
6412
  written.push("CLAUDE.md");
6339
6413
  if (config.rules?.length) {
@@ -6577,6 +6651,7 @@ function writeSetup(setup) {
6577
6651
  const backupDir = existingFiles.length > 0 ? createBackup(existingFiles) : void 0;
6578
6652
  const written = [];
6579
6653
  if (setup.targetAgent.includes("claude") && setup.claude) {
6654
+ setup.claude.activeTargets = setup.targetAgent;
6580
6655
  written.push(...writeClaudeConfig(setup.claude));
6581
6656
  }
6582
6657
  if (setup.targetAgent.includes("cursor") && setup.cursor) {
@@ -11469,7 +11544,7 @@ async function initCommand(options) {
11469
11544
  claudeContent = `# ${path29.basename(process.cwd())}
11470
11545
  `;
11471
11546
  }
11472
- const updatedClaude = appendManagedBlocks2(claudeContent, "claude");
11547
+ const updatedClaude = appendManagedBlocks2(claudeContent, "claude", targetAgent);
11473
11548
  if (updatedClaude !== claudeContent || !fs36.existsSync(claudeMdPath)) {
11474
11549
  fs36.writeFileSync(claudeMdPath, updatedClaude);
11475
11550
  console.log(` ${chalk14.green("\u2713")} CLAUDE.md \u2014 added Caliber sync instructions`);
@@ -11478,7 +11553,7 @@ async function initCommand(options) {
11478
11553
  const rulesDir = path29.join(".cursor", "rules");
11479
11554
  if (!fs36.existsSync(rulesDir)) fs36.mkdirSync(rulesDir, { recursive: true });
11480
11555
  for (const rule of [
11481
- getCursorPreCommitRule2(),
11556
+ getCursorPreCommitRule2(targetAgent),
11482
11557
  getCursorLearningsRule2(),
11483
11558
  getCursorSyncRule2(),
11484
11559
  getCursorSetupRule2()
@@ -11499,7 +11574,7 @@ async function initCommand(options) {
11499
11574
  copilotContent = `# ${path29.basename(process.cwd())}
11500
11575
  `;
11501
11576
  }
11502
- const updatedCopilot = appendManagedBlocks2(copilotContent, "copilot");
11577
+ const updatedCopilot = appendManagedBlocks2(copilotContent, "copilot", targetAgent);
11503
11578
  if (updatedCopilot !== copilotContent) {
11504
11579
  fs36.writeFileSync(copilotPath, updatedCopilot);
11505
11580
  console.log(` ${chalk14.green("\u2713")} Copilot instructions \u2014 added Caliber sync instructions`);
@@ -12508,6 +12583,14 @@ function scopeDiffToDir(diff, dir, allConfigDirs) {
12508
12583
  init_pre_commit_block();
12509
12584
  import fs39 from "fs";
12510
12585
  import path31 from "path";
12586
+ function inferActiveTargets(docs) {
12587
+ const targets = [];
12588
+ if (docs.claudeMd) targets.push("claude");
12589
+ if (docs.cursorrules || docs.cursorRules) targets.push("cursor");
12590
+ if (docs.copilotInstructions || docs.copilotInstructionFiles) targets.push("github-copilot");
12591
+ if (docs.agentsMd) targets.push("codex");
12592
+ return targets;
12593
+ }
12511
12594
  function writeFileGroup(groupDir, files) {
12512
12595
  fs39.mkdirSync(groupDir, { recursive: true });
12513
12596
  return files.map((file) => {
@@ -12518,6 +12601,7 @@ function writeFileGroup(groupDir, files) {
12518
12601
  }
12519
12602
  function writeRefreshDocs(docs, dir = ".") {
12520
12603
  const written = [];
12604
+ const targets = inferActiveTargets(docs);
12521
12605
  const p = (relPath) => (dir === "." ? relPath : path31.join(dir, relPath)).replace(/\\/g, "/");
12522
12606
  const ensureParent = (filePath) => {
12523
12607
  const parent = path31.dirname(filePath);
@@ -12526,13 +12610,13 @@ function writeRefreshDocs(docs, dir = ".") {
12526
12610
  if (docs.agentsMd) {
12527
12611
  const filePath = p("AGENTS.md");
12528
12612
  ensureParent(filePath);
12529
- fs39.writeFileSync(filePath, appendManagedBlocks(docs.agentsMd, "codex"));
12613
+ fs39.writeFileSync(filePath, appendManagedBlocks(docs.agentsMd, "codex", targets));
12530
12614
  written.push(filePath);
12531
12615
  }
12532
12616
  if (docs.claudeMd) {
12533
12617
  const filePath = p("CLAUDE.md");
12534
12618
  ensureParent(filePath);
12535
- fs39.writeFileSync(filePath, appendManagedBlocks(docs.claudeMd));
12619
+ fs39.writeFileSync(filePath, appendManagedBlocks(docs.claudeMd, "claude", targets));
12536
12620
  written.push(filePath);
12537
12621
  }
12538
12622
  if (docs.claudeRules) {
@@ -12556,7 +12640,7 @@ function writeRefreshDocs(docs, dir = ".") {
12556
12640
  if (docs.copilotInstructions) {
12557
12641
  const filePath = p(path31.join(".github", "copilot-instructions.md"));
12558
12642
  ensureParent(filePath);
12559
- fs39.writeFileSync(filePath, appendManagedBlocks(docs.copilotInstructions, "copilot"));
12643
+ fs39.writeFileSync(filePath, appendManagedBlocks(docs.copilotInstructions, "copilot", targets));
12560
12644
  written.push(filePath);
12561
12645
  }
12562
12646
  if (docs.copilotInstructionFiles) {
@@ -13300,6 +13384,7 @@ async function refreshSingleRepo(repoDir, options) {
13300
13384
  async function refreshCommand(options) {
13301
13385
  const quiet = !!options.quiet;
13302
13386
  if (quiet && isCaliberSubprocess()) return;
13387
+ if (quiet && isHookCascadeFromUserClaudeSession()) return;
13303
13388
  if (quiet) {
13304
13389
  const { isCaliberRunning: isCaliberRunning2 } = await Promise.resolve().then(() => (init_lock(), lock_exports));
13305
13390
  if (isCaliberRunning2()) return;
@@ -14351,6 +14436,7 @@ async function learnFinalizeCommand(options) {
14351
14436
  const isAuto = options?.auto === true;
14352
14437
  const isIncremental = options?.incremental === true;
14353
14438
  if (isAuto && isCaliberSubprocess()) return;
14439
+ if (isAuto && isHookCascadeFromUserClaudeSession()) return;
14354
14440
  if (!options?.force && !isAuto) {
14355
14441
  const { isCaliberRunning: isCaliberRunning2 } = await Promise.resolve().then(() => (init_lock(), lock_exports));
14356
14442
  if (isCaliberRunning2()) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rely-ai/caliber",
3
- "version": "1.49.1",
3
+ "version": "1.49.4",
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": {