@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.
- package/dist/bin.js +68 -32
- 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 ${
|
|
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 ${
|
|
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 ${
|
|
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,
|
|
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
|
-
|
|
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
|
|
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
|
|
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