@rely-ai/caliber 1.49.3 → 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 +68 -32
  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\`.
@@ -405,13 +420,13 @@ function hasPreCommitBlock(content) {
405
420
  if (body && /caliber/i.test(body)) return true;
406
421
  return false;
407
422
  }
408
- function appendPreCommitBlock(content, platform = "claude") {
423
+ function appendPreCommitBlock(content, platform = "claude", activeTargets) {
409
424
  if (hasPreCommitBlock(content)) return content;
410
425
  const trimmed = content.trimEnd();
411
- return trimmed + "\n\n" + getPreCommitBlock(platform) + "\n";
426
+ return trimmed + "\n\n" + getPreCommitBlock(platform, activeTargets) + "\n";
412
427
  }
413
- function getCursorPreCommitRule() {
414
- return { filename: CURSOR_RULE_FILENAME, content: getCursorRuleContent() };
428
+ function getCursorPreCommitRule(activeTargets) {
429
+ return { filename: CURSOR_RULE_FILENAME, content: getCursorRuleContent(activeTargets) };
415
430
  }
416
431
  function hasLearningsBlock(content) {
417
432
  if (content.includes(LEARNINGS_BLOCK_START)) return true;
@@ -449,29 +464,31 @@ function appendModelBlock(content) {
449
464
  const trimmed = content.trimEnd();
450
465
  return trimmed + "\n\n" + buildManagedModelBlock() + "\n";
451
466
  }
452
- function getSyncSetupInstruction(platform) {
467
+ function getSyncSetupInstruction(platform, activeTargets) {
453
468
  switch (platform) {
454
469
  case "claude":
455
470
  return `If the pre-commit hook is not set up, run \`/setup-caliber\` to configure everything automatically.`;
456
471
  case "codex":
457
472
  return `If the pre-commit hook is not set up, read \`.agents/skills/setup-caliber/SKILL.md\` and follow the setup instructions.`;
458
- case "copilot":
473
+ case "copilot": {
474
+ const docPaths = getManagedDocPaths(activeTargets);
459
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:
460
476
  \`\`\`bash
461
477
  npx @rely-ai/caliber hooks --install
462
478
  npx @rely-ai/caliber refresh
463
- git add ${MANAGED_DOC_PATHS} 2>/dev/null
479
+ git add ${docPaths} 2>/dev/null
464
480
  \`\`\``;
481
+ }
465
482
  }
466
483
  }
467
- function getSyncBlock(platform = "claude") {
484
+ function getSyncBlock(platform = "claude", activeTargets) {
468
485
  const bin = displayCaliberName();
469
486
  return `${SYNC_BLOCK_START}
470
487
  ## Context Sync
471
488
 
472
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.
473
490
  Configs update automatically before each commit via \`${bin} refresh\`.
474
- ${getSyncSetupInstruction(platform)}
491
+ ${getSyncSetupInstruction(platform, activeTargets)}
475
492
  ${SYNC_BLOCK_END}`;
476
493
  }
477
494
  function hasSyncBlock(content) {
@@ -480,15 +497,16 @@ function hasSyncBlock(content) {
480
497
  if (body && /caliber-ai-org\/ai-setup/.test(body)) return true;
481
498
  return false;
482
499
  }
483
- function appendSyncBlock(content, platform = "claude") {
500
+ function appendSyncBlock(content, platform = "claude", activeTargets) {
484
501
  if (hasSyncBlock(content)) return content;
485
502
  const trimmed = content.trimEnd();
486
- return trimmed + "\n\n" + getSyncBlock(platform) + "\n";
503
+ return trimmed + "\n\n" + getSyncBlock(platform, activeTargets) + "\n";
487
504
  }
488
- function appendManagedBlocks(content, platform = "claude") {
505
+ function appendManagedBlocks(content, platform = "claude", activeTargets) {
489
506
  return appendSyncBlock(
490
- appendModelBlock(appendLearningsBlock(appendPreCommitBlock(content, platform))),
491
- platform
507
+ appendModelBlock(appendLearningsBlock(appendPreCommitBlock(content, platform, activeTargets))),
508
+ platform,
509
+ activeTargets
492
510
  );
493
511
  }
494
512
  function getCursorSyncContent() {
@@ -534,7 +552,7 @@ function stripManagedBlocks(content) {
534
552
  }
535
553
  return result.replace(/\n{3,}/g, "\n\n").trim() + "\n";
536
554
  }
537
- var BLOCK_START, BLOCK_END, MANAGED_DOC_PATHS, 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;
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;
538
556
  var init_pre_commit_block = __esm({
539
557
  "src/writers/pre-commit-block.ts"() {
540
558
  "use strict";
@@ -542,7 +560,6 @@ var init_pre_commit_block = __esm({
542
560
  init_config();
543
561
  BLOCK_START = "<!-- caliber:managed:pre-commit -->";
544
562
  BLOCK_END = "<!-- /caliber:managed:pre-commit -->";
545
- MANAGED_DOC_PATHS = "CLAUDE.md .claude/ .cursor/ .cursorrules .github/copilot-instructions.md .github/instructions/ AGENTS.md CALIBER_LEARNINGS.md .agents/ .opencode/";
546
563
  CURSOR_RULE_FILENAME = "caliber-pre-commit.mdc";
547
564
  PRECOMMIT_HEADING_RE = /^##\s+Before Committing\s*$/m;
548
565
  LEARNINGS_BLOCK_START = "<!-- caliber:managed:learnings -->";
@@ -2670,17 +2687,25 @@ function extractJson(text) {
2670
2687
  function stripMarkdownFences(text) {
2671
2688
  return text.replace(/^```(?:json)?\s*/im, "").replace(/```\s*$/m, "").trim();
2672
2689
  }
2690
+ function isJsonObject(value) {
2691
+ return value !== null && typeof value === "object";
2692
+ }
2673
2693
  function parseJsonResponse(raw) {
2674
2694
  const cleaned = stripMarkdownFences(raw);
2675
2695
  try {
2676
- return JSON.parse(cleaned);
2696
+ const parsed = JSON.parse(cleaned);
2697
+ if (isJsonObject(parsed)) return parsed;
2677
2698
  } catch {
2678
2699
  }
2679
2700
  const json = extractJson(cleaned);
2680
2701
  if (!json) {
2681
- 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)}`);
2703
+ }
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)}`);
2682
2707
  }
2683
- return JSON.parse(json);
2708
+ return extracted;
2684
2709
  }
2685
2710
  function estimateTokens(text) {
2686
2711
  return Math.ceil(text.length / 4);
@@ -3032,9 +3057,10 @@ function isCursorLoggedIn() {
3032
3057
  const result = execFileSync(resolveAgentBin(), ["status"], {
3033
3058
  input: "",
3034
3059
  stdio: ["pipe", "pipe", "pipe"],
3035
- timeout: 5e3
3060
+ timeout: 5e3,
3061
+ env: withCaliberSubprocessEnv({ ...process.env })
3036
3062
  });
3037
- return !result.toString().includes("not logged in");
3063
+ return !result.toString().toLowerCase().includes("not logged in");
3038
3064
  } catch {
3039
3065
  return false;
3040
3066
  }
@@ -6381,7 +6407,7 @@ function writeClaudeConfig(config) {
6381
6407
  const written = [];
6382
6408
  fs13.writeFileSync(
6383
6409
  "CLAUDE.md",
6384
- appendManagedBlocks(config.claudeMd)
6410
+ appendManagedBlocks(config.claudeMd, "claude", config.activeTargets)
6385
6411
  );
6386
6412
  written.push("CLAUDE.md");
6387
6413
  if (config.rules?.length) {
@@ -6625,6 +6651,7 @@ function writeSetup(setup) {
6625
6651
  const backupDir = existingFiles.length > 0 ? createBackup(existingFiles) : void 0;
6626
6652
  const written = [];
6627
6653
  if (setup.targetAgent.includes("claude") && setup.claude) {
6654
+ setup.claude.activeTargets = setup.targetAgent;
6628
6655
  written.push(...writeClaudeConfig(setup.claude));
6629
6656
  }
6630
6657
  if (setup.targetAgent.includes("cursor") && setup.cursor) {
@@ -11517,7 +11544,7 @@ async function initCommand(options) {
11517
11544
  claudeContent = `# ${path29.basename(process.cwd())}
11518
11545
  `;
11519
11546
  }
11520
- const updatedClaude = appendManagedBlocks2(claudeContent, "claude");
11547
+ const updatedClaude = appendManagedBlocks2(claudeContent, "claude", targetAgent);
11521
11548
  if (updatedClaude !== claudeContent || !fs36.existsSync(claudeMdPath)) {
11522
11549
  fs36.writeFileSync(claudeMdPath, updatedClaude);
11523
11550
  console.log(` ${chalk14.green("\u2713")} CLAUDE.md \u2014 added Caliber sync instructions`);
@@ -11526,7 +11553,7 @@ async function initCommand(options) {
11526
11553
  const rulesDir = path29.join(".cursor", "rules");
11527
11554
  if (!fs36.existsSync(rulesDir)) fs36.mkdirSync(rulesDir, { recursive: true });
11528
11555
  for (const rule of [
11529
- getCursorPreCommitRule2(),
11556
+ getCursorPreCommitRule2(targetAgent),
11530
11557
  getCursorLearningsRule2(),
11531
11558
  getCursorSyncRule2(),
11532
11559
  getCursorSetupRule2()
@@ -11547,7 +11574,7 @@ async function initCommand(options) {
11547
11574
  copilotContent = `# ${path29.basename(process.cwd())}
11548
11575
  `;
11549
11576
  }
11550
- const updatedCopilot = appendManagedBlocks2(copilotContent, "copilot");
11577
+ const updatedCopilot = appendManagedBlocks2(copilotContent, "copilot", targetAgent);
11551
11578
  if (updatedCopilot !== copilotContent) {
11552
11579
  fs36.writeFileSync(copilotPath, updatedCopilot);
11553
11580
  console.log(` ${chalk14.green("\u2713")} Copilot instructions \u2014 added Caliber sync instructions`);
@@ -12556,6 +12583,14 @@ function scopeDiffToDir(diff, dir, allConfigDirs) {
12556
12583
  init_pre_commit_block();
12557
12584
  import fs39 from "fs";
12558
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
+ }
12559
12594
  function writeFileGroup(groupDir, files) {
12560
12595
  fs39.mkdirSync(groupDir, { recursive: true });
12561
12596
  return files.map((file) => {
@@ -12566,6 +12601,7 @@ function writeFileGroup(groupDir, files) {
12566
12601
  }
12567
12602
  function writeRefreshDocs(docs, dir = ".") {
12568
12603
  const written = [];
12604
+ const targets = inferActiveTargets(docs);
12569
12605
  const p = (relPath) => (dir === "." ? relPath : path31.join(dir, relPath)).replace(/\\/g, "/");
12570
12606
  const ensureParent = (filePath) => {
12571
12607
  const parent = path31.dirname(filePath);
@@ -12574,13 +12610,13 @@ function writeRefreshDocs(docs, dir = ".") {
12574
12610
  if (docs.agentsMd) {
12575
12611
  const filePath = p("AGENTS.md");
12576
12612
  ensureParent(filePath);
12577
- fs39.writeFileSync(filePath, appendManagedBlocks(docs.agentsMd, "codex"));
12613
+ fs39.writeFileSync(filePath, appendManagedBlocks(docs.agentsMd, "codex", targets));
12578
12614
  written.push(filePath);
12579
12615
  }
12580
12616
  if (docs.claudeMd) {
12581
12617
  const filePath = p("CLAUDE.md");
12582
12618
  ensureParent(filePath);
12583
- fs39.writeFileSync(filePath, appendManagedBlocks(docs.claudeMd));
12619
+ fs39.writeFileSync(filePath, appendManagedBlocks(docs.claudeMd, "claude", targets));
12584
12620
  written.push(filePath);
12585
12621
  }
12586
12622
  if (docs.claudeRules) {
@@ -12604,7 +12640,7 @@ function writeRefreshDocs(docs, dir = ".") {
12604
12640
  if (docs.copilotInstructions) {
12605
12641
  const filePath = p(path31.join(".github", "copilot-instructions.md"));
12606
12642
  ensureParent(filePath);
12607
- fs39.writeFileSync(filePath, appendManagedBlocks(docs.copilotInstructions, "copilot"));
12643
+ fs39.writeFileSync(filePath, appendManagedBlocks(docs.copilotInstructions, "copilot", targets));
12608
12644
  written.push(filePath);
12609
12645
  }
12610
12646
  if (docs.copilotInstructionFiles) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rely-ai/caliber",
3
- "version": "1.49.3",
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": {