@rely-ai/caliber 1.42.0 → 1.43.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.
- package/dist/bin.js +102 -12
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -262,6 +262,7 @@ var pre_commit_block_exports = {};
|
|
|
262
262
|
__export(pre_commit_block_exports, {
|
|
263
263
|
appendLearningsBlock: () => appendLearningsBlock,
|
|
264
264
|
appendManagedBlocks: () => appendManagedBlocks,
|
|
265
|
+
appendModelBlock: () => appendModelBlock,
|
|
265
266
|
appendPreCommitBlock: () => appendPreCommitBlock,
|
|
266
267
|
appendSyncBlock: () => appendSyncBlock,
|
|
267
268
|
getCursorLearningsRule: () => getCursorLearningsRule,
|
|
@@ -269,6 +270,7 @@ __export(pre_commit_block_exports, {
|
|
|
269
270
|
getCursorSetupRule: () => getCursorSetupRule,
|
|
270
271
|
getCursorSyncRule: () => getCursorSyncRule,
|
|
271
272
|
hasLearningsBlock: () => hasLearningsBlock,
|
|
273
|
+
hasModelBlock: () => hasModelBlock,
|
|
272
274
|
hasPreCommitBlock: () => hasPreCommitBlock,
|
|
273
275
|
hasSyncBlock: () => hasSyncBlock,
|
|
274
276
|
stripManagedBlocks: () => stripManagedBlocks
|
|
@@ -345,6 +347,25 @@ function appendLearningsBlock(content) {
|
|
|
345
347
|
function getCursorLearningsRule() {
|
|
346
348
|
return { filename: CURSOR_LEARNINGS_FILENAME, content: CURSOR_LEARNINGS_CONTENT };
|
|
347
349
|
}
|
|
350
|
+
function buildManagedModelBlock() {
|
|
351
|
+
const m = DEFAULT_MODELS.anthropic;
|
|
352
|
+
return `${MODEL_BLOCK_START}
|
|
353
|
+
## Model Configuration
|
|
354
|
+
|
|
355
|
+
Recommended default: \`${m}\` with high effort (stronger reasoning; higher cost and latency than smaller models).
|
|
356
|
+
Smaller/faster models trade quality for speed and cost \u2014 pick what fits the task.
|
|
357
|
+
Pin your choice (\`/model\` in Claude Code, or \`CALIBER_MODEL\` when using Caliber with an API provider) so upstream default changes do not silently change behavior.
|
|
358
|
+
|
|
359
|
+
${MODEL_BLOCK_END}`;
|
|
360
|
+
}
|
|
361
|
+
function hasModelBlock(content) {
|
|
362
|
+
return content.includes(MODEL_BLOCK_START);
|
|
363
|
+
}
|
|
364
|
+
function appendModelBlock(content) {
|
|
365
|
+
if (hasModelBlock(content)) return content;
|
|
366
|
+
const trimmed = content.trimEnd();
|
|
367
|
+
return trimmed + "\n\n" + buildManagedModelBlock() + "\n";
|
|
368
|
+
}
|
|
348
369
|
function getSyncSetupInstruction(platform) {
|
|
349
370
|
switch (platform) {
|
|
350
371
|
case "claude":
|
|
@@ -379,7 +400,10 @@ function appendSyncBlock(content, platform = "claude") {
|
|
|
379
400
|
return trimmed + "\n\n" + getSyncBlock(platform) + "\n";
|
|
380
401
|
}
|
|
381
402
|
function appendManagedBlocks(content, platform = "claude") {
|
|
382
|
-
return appendSyncBlock(
|
|
403
|
+
return appendSyncBlock(
|
|
404
|
+
appendModelBlock(appendLearningsBlock(appendPreCommitBlock(content, platform))),
|
|
405
|
+
platform
|
|
406
|
+
);
|
|
383
407
|
}
|
|
384
408
|
function getCursorSyncContent() {
|
|
385
409
|
const bin = resolveCaliber();
|
|
@@ -407,7 +431,7 @@ grep -q "caliber" .git/hooks/pre-commit 2>/dev/null && echo "SYNCED" || echo "NO
|
|
|
407
431
|
\`\`\`
|
|
408
432
|
|
|
409
433
|
If SYNCED: proceed normally.
|
|
410
|
-
If NOT_SYNCED: Tell the user: "This project uses Caliber to keep agent configs in sync
|
|
434
|
+
If NOT_SYNCED: Tell the user: "This project uses Caliber to keep agent configs in sync \u2014 it is not set up yet. Want me to run /setup-caliber? (~30 seconds)". If they agree, read \`.cursor/skills/setup-caliber/SKILL.md\` and follow its instructions.
|
|
411
435
|
`;
|
|
412
436
|
}
|
|
413
437
|
function getCursorSetupRule() {
|
|
@@ -424,11 +448,12 @@ function stripManagedBlocks(content) {
|
|
|
424
448
|
}
|
|
425
449
|
return result.replace(/\n{3,}/g, "\n\n").trim() + "\n";
|
|
426
450
|
}
|
|
427
|
-
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, SYNC_BLOCK_START, SYNC_BLOCK_END, CURSOR_SYNC_FILENAME, CURSOR_SETUP_FILENAME, MANAGED_BLOCK_PAIRS;
|
|
451
|
+
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;
|
|
428
452
|
var init_pre_commit_block = __esm({
|
|
429
453
|
"src/writers/pre-commit-block.ts"() {
|
|
430
454
|
"use strict";
|
|
431
455
|
init_resolve_caliber();
|
|
456
|
+
init_config();
|
|
432
457
|
BLOCK_START = "<!-- caliber:managed:pre-commit -->";
|
|
433
458
|
BLOCK_END = "<!-- /caliber:managed:pre-commit -->";
|
|
434
459
|
MANAGED_DOC_PATHS = "CLAUDE.md .claude/ .cursor/ .cursorrules .github/copilot-instructions.md .github/instructions/ AGENTS.md CALIBER_LEARNINGS.md .agents/ .opencode/";
|
|
@@ -449,6 +474,8 @@ alwaysApply: true
|
|
|
449
474
|
Read \`CALIBER_LEARNINGS.md\` for patterns and anti-patterns learned from previous sessions.
|
|
450
475
|
These are auto-extracted from real tool usage \u2014 treat them as project-specific rules.
|
|
451
476
|
`;
|
|
477
|
+
MODEL_BLOCK_START = "<!-- caliber:managed:model-config -->";
|
|
478
|
+
MODEL_BLOCK_END = "<!-- /caliber:managed:model-config -->";
|
|
452
479
|
SYNC_BLOCK_START = "<!-- caliber:managed:sync -->";
|
|
453
480
|
SYNC_BLOCK_END = "<!-- /caliber:managed:sync -->";
|
|
454
481
|
CURSOR_SYNC_FILENAME = "caliber-sync.mdc";
|
|
@@ -456,6 +483,7 @@ These are auto-extracted from real tool usage \u2014 treat them as project-speci
|
|
|
456
483
|
MANAGED_BLOCK_PAIRS = [
|
|
457
484
|
[BLOCK_START, BLOCK_END],
|
|
458
485
|
[LEARNINGS_BLOCK_START, LEARNINGS_BLOCK_END],
|
|
486
|
+
[MODEL_BLOCK_START, MODEL_BLOCK_END],
|
|
459
487
|
[SYNC_BLOCK_START, SYNC_BLOCK_END]
|
|
460
488
|
];
|
|
461
489
|
}
|
|
@@ -5504,6 +5532,13 @@ var LIMITS = {
|
|
|
5504
5532
|
SKILL_CHARS: 3e3,
|
|
5505
5533
|
RULES_MAX: 10
|
|
5506
5534
|
};
|
|
5535
|
+
var BUILD_GENERATE_PROMPT_MAX_TOKENS = 12e4;
|
|
5536
|
+
var PROJECT_FILES_HEADER_RESERVE_TOKENS = 160;
|
|
5537
|
+
function maxCharsForCodeFileContent(runningJoinedLen, pathLine, budgetTokens) {
|
|
5538
|
+
const maxTotalChars = budgetTokens * 4;
|
|
5539
|
+
const overhead = runningJoinedLen + 1 + pathLine.length + 1;
|
|
5540
|
+
return Math.max(0, maxTotalChars - overhead);
|
|
5541
|
+
}
|
|
5507
5542
|
function truncate(text, maxChars) {
|
|
5508
5543
|
if (text.length <= maxChars) return text;
|
|
5509
5544
|
return text.slice(0, maxChars) + `
|
|
@@ -5709,9 +5744,12 @@ User instructions: ${prompt}`);
|
|
|
5709
5744
|
if (fingerprint.codeAnalysis) {
|
|
5710
5745
|
const ca = fingerprint.codeAnalysis;
|
|
5711
5746
|
const basePrompt = parts.join("\n");
|
|
5712
|
-
const
|
|
5747
|
+
const effectiveMaxTokens = Math.min(getMaxPromptTokens(), BUILD_GENERATE_PROMPT_MAX_TOKENS);
|
|
5713
5748
|
const baseTokens = estimateTokens(basePrompt);
|
|
5714
|
-
const tokenBudgetForCode = Math.max(
|
|
5749
|
+
const tokenBudgetForCode = Math.max(
|
|
5750
|
+
0,
|
|
5751
|
+
effectiveMaxTokens - baseTokens - PROJECT_FILES_HEADER_RESERVE_TOKENS
|
|
5752
|
+
);
|
|
5715
5753
|
const codeLines = [];
|
|
5716
5754
|
let codeChars = 0;
|
|
5717
5755
|
const introLine = "Study these files to extract patterns for skills. Use the exact code patterns you see here.\n";
|
|
@@ -5720,13 +5758,24 @@ User instructions: ${prompt}`);
|
|
|
5720
5758
|
const sortedFiles = [...ca.files].sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
5721
5759
|
let includedFiles = 0;
|
|
5722
5760
|
for (const f of sortedFiles) {
|
|
5723
|
-
const
|
|
5724
|
-
|
|
5761
|
+
const pathLine = `[${f.path}]
|
|
5762
|
+
`;
|
|
5763
|
+
const maxContent = maxCharsForCodeFileContent(runningCodeLen, pathLine, tokenBudgetForCode);
|
|
5764
|
+
if (maxContent < 1) {
|
|
5765
|
+
if (includedFiles > 0) break;
|
|
5766
|
+
continue;
|
|
5767
|
+
}
|
|
5768
|
+
const content = f.content.slice(0, Math.min(f.content.length, maxContent));
|
|
5769
|
+
const entry = `${pathLine}${content}
|
|
5725
5770
|
`;
|
|
5726
5771
|
const projectedLen = runningCodeLen + 1 + entry.length;
|
|
5727
|
-
|
|
5772
|
+
const projectedTokens = Math.ceil(projectedLen / 4);
|
|
5773
|
+
if (projectedTokens > tokenBudgetForCode) {
|
|
5774
|
+
if (includedFiles > 0) break;
|
|
5775
|
+
continue;
|
|
5776
|
+
}
|
|
5728
5777
|
codeLines.push(entry);
|
|
5729
|
-
codeChars +=
|
|
5778
|
+
codeChars += content.length;
|
|
5730
5779
|
runningCodeLen = projectedLen;
|
|
5731
5780
|
includedFiles++;
|
|
5732
5781
|
}
|
|
@@ -5764,7 +5813,7 @@ function writeClaudeConfig(config) {
|
|
|
5764
5813
|
const written = [];
|
|
5765
5814
|
fs13.writeFileSync(
|
|
5766
5815
|
"CLAUDE.md",
|
|
5767
|
-
|
|
5816
|
+
appendManagedBlocks(config.claudeMd)
|
|
5768
5817
|
);
|
|
5769
5818
|
written.push("CLAUDE.md");
|
|
5770
5819
|
if (config.rules?.length) {
|
|
@@ -5874,7 +5923,7 @@ function writeCodexConfig(config) {
|
|
|
5874
5923
|
const written = [];
|
|
5875
5924
|
fs15.writeFileSync(
|
|
5876
5925
|
"AGENTS.md",
|
|
5877
|
-
|
|
5926
|
+
appendManagedBlocks(config.agentsMd, "codex")
|
|
5878
5927
|
);
|
|
5879
5928
|
written.push("AGENTS.md");
|
|
5880
5929
|
if (config.skills?.length) {
|
|
@@ -5906,7 +5955,7 @@ function writeGithubCopilotConfig(config) {
|
|
|
5906
5955
|
fs16.mkdirSync(".github", { recursive: true });
|
|
5907
5956
|
fs16.writeFileSync(
|
|
5908
5957
|
path15.join(".github", "copilot-instructions.md"),
|
|
5909
|
-
|
|
5958
|
+
appendManagedBlocks(config.instructions, "copilot")
|
|
5910
5959
|
);
|
|
5911
5960
|
written.push(".github/copilot-instructions.md");
|
|
5912
5961
|
}
|
|
@@ -6649,6 +6698,7 @@ var POINTS_FRESHNESS = 4;
|
|
|
6649
6698
|
var POINTS_NO_SECRETS = 4;
|
|
6650
6699
|
var POINTS_PERMISSIONS = 2;
|
|
6651
6700
|
var POINTS_HOOKS = 2;
|
|
6701
|
+
var POINTS_MODEL_PINNED = 2;
|
|
6652
6702
|
var POINTS_AGENTS_MD = 1;
|
|
6653
6703
|
var POINTS_OPEN_SKILLS_FORMAT = 2;
|
|
6654
6704
|
var POINTS_LEARNED_CONTENT = 2;
|
|
@@ -7433,6 +7483,19 @@ import { execSync as execSync12 } from "child_process";
|
|
|
7433
7483
|
import { join as join7 } from "path";
|
|
7434
7484
|
init_resolve_caliber();
|
|
7435
7485
|
init_pre_commit_block();
|
|
7486
|
+
|
|
7487
|
+
// src/scoring/model-pinning.ts
|
|
7488
|
+
function configContentSuggestsPinnedModel(lower) {
|
|
7489
|
+
if (/\bcaliber_model\b/.test(lower) || /\bcaliber_fast_model\b/.test(lower)) return true;
|
|
7490
|
+
if (/(?:^|[\s`'"\n])\/model(?:[\s`'"\n]|$)/.test(lower)) return true;
|
|
7491
|
+
if (/claude-(sonnet|opus|haiku)([-.@\d]|\b)/.test(lower)) return true;
|
|
7492
|
+
if (/\bgpt-[45]([-._\d]|\b)/.test(lower)) return true;
|
|
7493
|
+
if (/\bsonnet-4\.[\d.]+\b/.test(lower)) return true;
|
|
7494
|
+
if (/\b(high|medium|low)\s+effort\b/.test(lower)) return true;
|
|
7495
|
+
return false;
|
|
7496
|
+
}
|
|
7497
|
+
|
|
7498
|
+
// src/scoring/checks/bonus.ts
|
|
7436
7499
|
function hasPreCommitHook(dir) {
|
|
7437
7500
|
try {
|
|
7438
7501
|
const gitDir = execSync12("git rev-parse --git-dir", {
|
|
@@ -7553,6 +7616,33 @@ function checkBonus(dir) {
|
|
|
7553
7616
|
detail: hasLearned ? "Session learnings found in CALIBER_LEARNINGS.md" : "No learned content",
|
|
7554
7617
|
suggestion: hasLearned ? void 0 : `Session learnings capture patterns from your coding sessions so the agent improves over time. Run \`${resolveCaliber()} learn install\``
|
|
7555
7618
|
});
|
|
7619
|
+
const configContent = (() => {
|
|
7620
|
+
const parts = [];
|
|
7621
|
+
for (const rel of ["CLAUDE.md", "AGENTS.md"]) {
|
|
7622
|
+
const c = readFileOrNull(join7(dir, rel));
|
|
7623
|
+
if (c) parts.push(c);
|
|
7624
|
+
}
|
|
7625
|
+
try {
|
|
7626
|
+
const rulesDir = join7(dir, ".cursor", "rules");
|
|
7627
|
+
for (const f of readdirSync3(rulesDir).filter((x) => x.endsWith(".mdc"))) {
|
|
7628
|
+
const content = readFileOrNull(join7(rulesDir, f));
|
|
7629
|
+
if (content) parts.push(content);
|
|
7630
|
+
}
|
|
7631
|
+
} catch {
|
|
7632
|
+
}
|
|
7633
|
+
return parts.join("\n").toLowerCase();
|
|
7634
|
+
})();
|
|
7635
|
+
const hasModelRef = configContentSuggestsPinnedModel(configContent);
|
|
7636
|
+
checks.push({
|
|
7637
|
+
id: "model_pinned",
|
|
7638
|
+
name: "Model & effort pinned",
|
|
7639
|
+
category: "bonus",
|
|
7640
|
+
maxPoints: POINTS_MODEL_PINNED,
|
|
7641
|
+
earnedPoints: hasModelRef ? POINTS_MODEL_PINNED : 0,
|
|
7642
|
+
passed: hasModelRef,
|
|
7643
|
+
detail: hasModelRef ? "Model or effort level explicitly set in config" : "Config doesn't pin model or effort level \u2014 behavior may change when defaults are updated",
|
|
7644
|
+
suggestion: hasModelRef ? void 0 : "Add model/effort to config: CALIBER_MODEL env var, or /model in Claude Code, or a Model Configuration section in CLAUDE.md"
|
|
7645
|
+
});
|
|
7556
7646
|
return checks;
|
|
7557
7647
|
}
|
|
7558
7648
|
|
package/package.json
CHANGED