@rely-ai/caliber 1.37.0 → 1.37.1
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 +319 -128
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -2352,6 +2352,55 @@ function isRateLimitError(stderr) {
|
|
|
2352
2352
|
return /rate limit|too many requests|429/i.test(stderr);
|
|
2353
2353
|
}
|
|
2354
2354
|
|
|
2355
|
+
// src/llm/utils.ts
|
|
2356
|
+
function extractJson(text) {
|
|
2357
|
+
const startIdx = text.search(/[[{]/);
|
|
2358
|
+
if (startIdx === -1) return null;
|
|
2359
|
+
let depth = 0;
|
|
2360
|
+
let inString = false;
|
|
2361
|
+
let escaped = false;
|
|
2362
|
+
for (let i = startIdx; i < text.length; i++) {
|
|
2363
|
+
const ch = text[i];
|
|
2364
|
+
if (escaped) {
|
|
2365
|
+
escaped = false;
|
|
2366
|
+
continue;
|
|
2367
|
+
}
|
|
2368
|
+
if (ch === "\\" && inString) {
|
|
2369
|
+
escaped = true;
|
|
2370
|
+
continue;
|
|
2371
|
+
}
|
|
2372
|
+
if (ch === '"') {
|
|
2373
|
+
inString = !inString;
|
|
2374
|
+
continue;
|
|
2375
|
+
}
|
|
2376
|
+
if (inString) continue;
|
|
2377
|
+
if (ch === "{" || ch === "[") depth++;
|
|
2378
|
+
if (ch === "}" || ch === "]") {
|
|
2379
|
+
depth--;
|
|
2380
|
+
if (depth === 0) return text.slice(startIdx, i + 1);
|
|
2381
|
+
}
|
|
2382
|
+
}
|
|
2383
|
+
return null;
|
|
2384
|
+
}
|
|
2385
|
+
function stripMarkdownFences(text) {
|
|
2386
|
+
return text.replace(/^```(?:json)?\s*/im, "").replace(/```\s*$/m, "").trim();
|
|
2387
|
+
}
|
|
2388
|
+
function parseJsonResponse(raw) {
|
|
2389
|
+
const cleaned = stripMarkdownFences(raw);
|
|
2390
|
+
try {
|
|
2391
|
+
return JSON.parse(cleaned);
|
|
2392
|
+
} catch {
|
|
2393
|
+
}
|
|
2394
|
+
const json = extractJson(cleaned);
|
|
2395
|
+
if (!json) {
|
|
2396
|
+
throw new Error(`No JSON found in LLM response: ${raw.slice(0, 200)}`);
|
|
2397
|
+
}
|
|
2398
|
+
return JSON.parse(json);
|
|
2399
|
+
}
|
|
2400
|
+
function estimateTokens(text) {
|
|
2401
|
+
return Math.ceil(text.length / 4);
|
|
2402
|
+
}
|
|
2403
|
+
|
|
2355
2404
|
// src/llm/cursor-acp.ts
|
|
2356
2405
|
var AGENT_BIN = "agent";
|
|
2357
2406
|
var IS_WINDOWS = process.platform === "win32";
|
|
@@ -2376,12 +2425,33 @@ var CursorAcpProvider = class {
|
|
|
2376
2425
|
async call(options) {
|
|
2377
2426
|
const prompt = this.buildPrompt(options);
|
|
2378
2427
|
const model = options.model || this.defaultModel;
|
|
2379
|
-
|
|
2428
|
+
const result = await this.runPrint(model, prompt);
|
|
2429
|
+
trackUsage(model, {
|
|
2430
|
+
inputTokens: estimateTokens(prompt),
|
|
2431
|
+
outputTokens: estimateTokens(result)
|
|
2432
|
+
});
|
|
2433
|
+
return result;
|
|
2380
2434
|
}
|
|
2381
2435
|
async stream(options, callbacks) {
|
|
2382
2436
|
const prompt = this.buildPrompt(options);
|
|
2383
2437
|
const model = options.model || this.defaultModel;
|
|
2384
|
-
|
|
2438
|
+
const inputEstimate = estimateTokens(prompt);
|
|
2439
|
+
let outputChars = 0;
|
|
2440
|
+
const wrappedCallbacks = {
|
|
2441
|
+
onText: (text) => {
|
|
2442
|
+
outputChars += text.length;
|
|
2443
|
+
callbacks.onText(text);
|
|
2444
|
+
},
|
|
2445
|
+
onEnd: (meta) => {
|
|
2446
|
+
trackUsage(model, {
|
|
2447
|
+
inputTokens: inputEstimate,
|
|
2448
|
+
outputTokens: Math.ceil(outputChars / 4)
|
|
2449
|
+
});
|
|
2450
|
+
callbacks.onEnd(meta);
|
|
2451
|
+
},
|
|
2452
|
+
onError: (err) => callbacks.onError(err)
|
|
2453
|
+
};
|
|
2454
|
+
return this.runPrintStream(model, prompt, wrappedCallbacks);
|
|
2385
2455
|
}
|
|
2386
2456
|
/**
|
|
2387
2457
|
* Pre-spawn an agent process so it's ready when the first call comes.
|
|
@@ -2473,7 +2543,11 @@ var CursorAcpProvider = class {
|
|
|
2473
2543
|
this.killWithEscalation(child);
|
|
2474
2544
|
if (!settled) {
|
|
2475
2545
|
settled = true;
|
|
2476
|
-
reject(
|
|
2546
|
+
reject(
|
|
2547
|
+
new Error(
|
|
2548
|
+
`Cursor agent timed out after ${this.timeoutMs / 1e3}s. Set CALIBER_CURSOR_TIMEOUT_MS to increase.`
|
|
2549
|
+
)
|
|
2550
|
+
);
|
|
2477
2551
|
}
|
|
2478
2552
|
}, this.timeoutMs);
|
|
2479
2553
|
timer.unref();
|
|
@@ -2509,7 +2583,9 @@ var CursorAcpProvider = class {
|
|
|
2509
2583
|
this.killWithEscalation(child);
|
|
2510
2584
|
if (!settled) {
|
|
2511
2585
|
settled = true;
|
|
2512
|
-
const err = new Error(
|
|
2586
|
+
const err = new Error(
|
|
2587
|
+
`Cursor agent timed out after ${this.timeoutMs / 1e3}s. Set CALIBER_CURSOR_TIMEOUT_MS to increase.`
|
|
2588
|
+
);
|
|
2513
2589
|
callbacks.onError(err);
|
|
2514
2590
|
reject(err);
|
|
2515
2591
|
}
|
|
@@ -2616,7 +2692,10 @@ function isCursorAgentAvailable() {
|
|
|
2616
2692
|
}
|
|
2617
2693
|
function isCursorLoggedIn() {
|
|
2618
2694
|
try {
|
|
2619
|
-
const result = execSync5(`${AGENT_BIN} status`, {
|
|
2695
|
+
const result = execSync5(`${AGENT_BIN} status`, {
|
|
2696
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
2697
|
+
timeout: 5e3
|
|
2698
|
+
});
|
|
2620
2699
|
return !result.toString().includes("not logged in");
|
|
2621
2700
|
} catch {
|
|
2622
2701
|
return false;
|
|
@@ -2653,20 +2732,29 @@ var ClaudeCliProvider = class {
|
|
|
2653
2732
|
}
|
|
2654
2733
|
async call(options) {
|
|
2655
2734
|
const combined = this.buildCombinedPrompt(options);
|
|
2656
|
-
|
|
2735
|
+
const result = await this.runClaudePrint(combined, options.model);
|
|
2736
|
+
trackUsage(options.model || this.defaultModel, {
|
|
2737
|
+
inputTokens: estimateTokens(combined),
|
|
2738
|
+
outputTokens: estimateTokens(result)
|
|
2739
|
+
});
|
|
2740
|
+
return result;
|
|
2657
2741
|
}
|
|
2658
2742
|
async stream(options, callbacks) {
|
|
2659
2743
|
const combined = this.buildCombinedPrompt(options);
|
|
2744
|
+
const inputEstimate = estimateTokens(combined);
|
|
2660
2745
|
const args = ["-p"];
|
|
2661
2746
|
if (options.model) args.push("--model", options.model);
|
|
2662
2747
|
const child = spawnClaude(args);
|
|
2663
2748
|
child.stdin.end(combined);
|
|
2664
2749
|
let settled = false;
|
|
2750
|
+
let outputChars = 0;
|
|
2665
2751
|
const chunks = [];
|
|
2666
2752
|
const stderrChunks = [];
|
|
2667
2753
|
child.stdout.on("data", (chunk) => {
|
|
2668
2754
|
chunks.push(chunk);
|
|
2669
|
-
|
|
2755
|
+
const text = chunk.toString("utf-8");
|
|
2756
|
+
outputChars += text.length;
|
|
2757
|
+
callbacks.onText(text);
|
|
2670
2758
|
});
|
|
2671
2759
|
child.stderr.on("data", (chunk) => stderrChunks.push(chunk));
|
|
2672
2760
|
const timer = setTimeout(() => {
|
|
@@ -2692,6 +2780,11 @@ var ClaudeCliProvider = class {
|
|
|
2692
2780
|
if (settled) return;
|
|
2693
2781
|
settled = true;
|
|
2694
2782
|
if (code === 0) {
|
|
2783
|
+
const model = options.model || this.defaultModel;
|
|
2784
|
+
trackUsage(model, {
|
|
2785
|
+
inputTokens: inputEstimate,
|
|
2786
|
+
outputTokens: Math.ceil(outputChars / 4)
|
|
2787
|
+
});
|
|
2695
2788
|
callbacks.onEnd({ stopReason: "end_turn" });
|
|
2696
2789
|
} else {
|
|
2697
2790
|
const stderr = Buffer.concat(stderrChunks).toString("utf-8").trim();
|
|
@@ -2766,55 +2859,6 @@ function isClaudeCliAvailable() {
|
|
|
2766
2859
|
}
|
|
2767
2860
|
}
|
|
2768
2861
|
|
|
2769
|
-
// src/llm/utils.ts
|
|
2770
|
-
function extractJson(text) {
|
|
2771
|
-
const startIdx = text.search(/[[{]/);
|
|
2772
|
-
if (startIdx === -1) return null;
|
|
2773
|
-
let depth = 0;
|
|
2774
|
-
let inString = false;
|
|
2775
|
-
let escaped = false;
|
|
2776
|
-
for (let i = startIdx; i < text.length; i++) {
|
|
2777
|
-
const ch = text[i];
|
|
2778
|
-
if (escaped) {
|
|
2779
|
-
escaped = false;
|
|
2780
|
-
continue;
|
|
2781
|
-
}
|
|
2782
|
-
if (ch === "\\" && inString) {
|
|
2783
|
-
escaped = true;
|
|
2784
|
-
continue;
|
|
2785
|
-
}
|
|
2786
|
-
if (ch === '"') {
|
|
2787
|
-
inString = !inString;
|
|
2788
|
-
continue;
|
|
2789
|
-
}
|
|
2790
|
-
if (inString) continue;
|
|
2791
|
-
if (ch === "{" || ch === "[") depth++;
|
|
2792
|
-
if (ch === "}" || ch === "]") {
|
|
2793
|
-
depth--;
|
|
2794
|
-
if (depth === 0) return text.slice(startIdx, i + 1);
|
|
2795
|
-
}
|
|
2796
|
-
}
|
|
2797
|
-
return null;
|
|
2798
|
-
}
|
|
2799
|
-
function stripMarkdownFences(text) {
|
|
2800
|
-
return text.replace(/^```(?:json)?\s*/im, "").replace(/```\s*$/m, "").trim();
|
|
2801
|
-
}
|
|
2802
|
-
function parseJsonResponse(raw) {
|
|
2803
|
-
const cleaned = stripMarkdownFences(raw);
|
|
2804
|
-
try {
|
|
2805
|
-
return JSON.parse(cleaned);
|
|
2806
|
-
} catch {
|
|
2807
|
-
}
|
|
2808
|
-
const json = extractJson(cleaned);
|
|
2809
|
-
if (!json) {
|
|
2810
|
-
throw new Error(`No JSON found in LLM response: ${raw.slice(0, 200)}`);
|
|
2811
|
-
}
|
|
2812
|
-
return JSON.parse(json);
|
|
2813
|
-
}
|
|
2814
|
-
function estimateTokens(text) {
|
|
2815
|
-
return Math.ceil(text.length / 4);
|
|
2816
|
-
}
|
|
2817
|
-
|
|
2818
2862
|
// src/llm/model-recovery.ts
|
|
2819
2863
|
init_config();
|
|
2820
2864
|
init_resolve_caliber();
|
|
@@ -4761,9 +4805,25 @@ function isTransientError2(error) {
|
|
|
4761
4805
|
async function generateSetup(fingerprint, targetAgent, prompt, callbacks, failingChecks, currentScore, passingChecks, options) {
|
|
4762
4806
|
const isTargetedFix = failingChecks && failingChecks.length > 0 && currentScore !== void 0 && currentScore >= 95 || options?.forceTargetedFix;
|
|
4763
4807
|
if (isTargetedFix) {
|
|
4764
|
-
return generateMonolithic(
|
|
4808
|
+
return generateMonolithic(
|
|
4809
|
+
fingerprint,
|
|
4810
|
+
targetAgent,
|
|
4811
|
+
prompt,
|
|
4812
|
+
callbacks,
|
|
4813
|
+
failingChecks,
|
|
4814
|
+
currentScore,
|
|
4815
|
+
passingChecks
|
|
4816
|
+
);
|
|
4765
4817
|
}
|
|
4766
|
-
const coreResult = await generateCore(
|
|
4818
|
+
const coreResult = await generateCore(
|
|
4819
|
+
fingerprint,
|
|
4820
|
+
targetAgent,
|
|
4821
|
+
prompt,
|
|
4822
|
+
callbacks,
|
|
4823
|
+
failingChecks,
|
|
4824
|
+
currentScore,
|
|
4825
|
+
passingChecks
|
|
4826
|
+
);
|
|
4767
4827
|
if (!coreResult.setup) {
|
|
4768
4828
|
return coreResult;
|
|
4769
4829
|
}
|
|
@@ -4812,6 +4872,7 @@ function mergeSkillResults(results, setup) {
|
|
|
4812
4872
|
}
|
|
4813
4873
|
return { succeeded, failed };
|
|
4814
4874
|
}
|
|
4875
|
+
var MAX_SKILL_TOPICS = 5;
|
|
4815
4876
|
function collectSkillTopics(setup, targetAgent, fingerprint) {
|
|
4816
4877
|
const topics = [];
|
|
4817
4878
|
for (const platform of ["claude", "codex", "opencode", "cursor"]) {
|
|
@@ -4832,12 +4893,18 @@ function collectSkillTopics(setup, targetAgent, fingerprint) {
|
|
|
4832
4893
|
delete platformObj.skillTopics;
|
|
4833
4894
|
}
|
|
4834
4895
|
}
|
|
4835
|
-
return topics;
|
|
4896
|
+
return topics.slice(0, MAX_SKILL_TOPICS);
|
|
4836
4897
|
}
|
|
4837
4898
|
function getDefaultSkillTopics(fingerprint) {
|
|
4838
4899
|
const topics = [
|
|
4839
|
-
{
|
|
4840
|
-
|
|
4900
|
+
{
|
|
4901
|
+
name: "development-workflow",
|
|
4902
|
+
description: "Development setup and common workflows. Use when starting development, running the project, or setting up the environment."
|
|
4903
|
+
},
|
|
4904
|
+
{
|
|
4905
|
+
name: "testing-guide",
|
|
4906
|
+
description: "Testing patterns and commands. Use when writing tests, running test suites, or debugging test failures."
|
|
4907
|
+
}
|
|
4841
4908
|
];
|
|
4842
4909
|
if (fingerprint.frameworks.length > 0) {
|
|
4843
4910
|
topics.push({
|
|
@@ -4855,8 +4922,10 @@ function getDefaultSkillTopics(fingerprint) {
|
|
|
4855
4922
|
function buildSkillContext(fingerprint, setup, allDeps) {
|
|
4856
4923
|
const parts = [];
|
|
4857
4924
|
if (fingerprint.packageName) parts.push(`Project: ${fingerprint.packageName}`);
|
|
4858
|
-
if (fingerprint.languages.length > 0)
|
|
4859
|
-
|
|
4925
|
+
if (fingerprint.languages.length > 0)
|
|
4926
|
+
parts.push(`Languages: ${fingerprint.languages.join(", ")}`);
|
|
4927
|
+
if (fingerprint.frameworks.length > 0)
|
|
4928
|
+
parts.push(`Frameworks: ${fingerprint.frameworks.join(", ")}`);
|
|
4860
4929
|
const claude = setup.claude;
|
|
4861
4930
|
const claudeMd = claude?.claudeMd;
|
|
4862
4931
|
if (claudeMd) {
|
|
@@ -4943,7 +5012,9 @@ async function streamGeneration(config) {
|
|
|
4943
5012
|
}
|
|
4944
5013
|
}
|
|
4945
5014
|
sentStatuses = completedLines.length;
|
|
4946
|
-
const jsonStartMatch = preJsonBuffer.match(
|
|
5015
|
+
const jsonStartMatch = preJsonBuffer.match(
|
|
5016
|
+
/(?:^|\n)\s*(?:```json\s*\n\s*)?\{(?=\s*")/
|
|
5017
|
+
);
|
|
4947
5018
|
if (jsonStartMatch) {
|
|
4948
5019
|
const matchIndex = preJsonBuffer.indexOf("{", jsonStartMatch.index);
|
|
4949
5020
|
inJson = true;
|
|
@@ -4958,7 +5029,9 @@ async function streamGeneration(config) {
|
|
|
4958
5029
|
let setup = null;
|
|
4959
5030
|
let jsonToParse = (jsonContent || preJsonBuffer).replace(/```\s*$/g, "").trim();
|
|
4960
5031
|
if (!jsonContent && preJsonBuffer) {
|
|
4961
|
-
const fallbackMatch = preJsonBuffer.match(
|
|
5032
|
+
const fallbackMatch = preJsonBuffer.match(
|
|
5033
|
+
/(?:^|\n)\s*(?:```json\s*\n\s*)?\{(?=\s*")/
|
|
5034
|
+
);
|
|
4962
5035
|
if (fallbackMatch) {
|
|
4963
5036
|
const matchIndex = preJsonBuffer.indexOf("{", fallbackMatch.index);
|
|
4964
5037
|
jsonToParse = preJsonBuffer.slice(matchIndex).replace(/```\s*$/g, "").trim();
|
|
@@ -4969,7 +5042,10 @@ async function streamGeneration(config) {
|
|
|
4969
5042
|
} catch {
|
|
4970
5043
|
}
|
|
4971
5044
|
if (!setup && stopReason === "max_tokens" && attempt < MAX_RETRIES2) {
|
|
4972
|
-
if (config.callbacks)
|
|
5045
|
+
if (config.callbacks)
|
|
5046
|
+
config.callbacks.onStatus(
|
|
5047
|
+
"Output was truncated, retrying with higher token limit..."
|
|
5048
|
+
);
|
|
4973
5049
|
setTimeout(() => attemptGeneration().then(resolve3), 1e3);
|
|
4974
5050
|
return;
|
|
4975
5051
|
}
|
|
@@ -4982,12 +5058,18 @@ async function streamGeneration(config) {
|
|
|
4982
5058
|
if (config.callbacks) config.callbacks.onComplete(setup, explanation);
|
|
4983
5059
|
resolve3({ setup, explanation, stopReason: stopReason ?? void 0 });
|
|
4984
5060
|
} else {
|
|
4985
|
-
resolve3({
|
|
5061
|
+
resolve3({
|
|
5062
|
+
setup: null,
|
|
5063
|
+
explanation,
|
|
5064
|
+
raw: preJsonBuffer,
|
|
5065
|
+
stopReason: stopReason ?? void 0
|
|
5066
|
+
});
|
|
4986
5067
|
}
|
|
4987
5068
|
},
|
|
4988
5069
|
onError: (error) => {
|
|
4989
5070
|
if (isTransientError2(error) && attempt < MAX_RETRIES2) {
|
|
4990
|
-
if (config.callbacks)
|
|
5071
|
+
if (config.callbacks)
|
|
5072
|
+
config.callbacks.onStatus("Connection interrupted, retrying...");
|
|
4991
5073
|
setTimeout(() => attemptGeneration().then(resolve3), 2e3);
|
|
4992
5074
|
return;
|
|
4993
5075
|
}
|
|
@@ -5004,7 +5086,14 @@ async function streamGeneration(config) {
|
|
|
5004
5086
|
return attemptGeneration();
|
|
5005
5087
|
}
|
|
5006
5088
|
async function generateCore(fingerprint, targetAgent, prompt, callbacks, failingChecks, currentScore, passingChecks) {
|
|
5007
|
-
const userMessage = buildGeneratePrompt(
|
|
5089
|
+
const userMessage = buildGeneratePrompt(
|
|
5090
|
+
fingerprint,
|
|
5091
|
+
targetAgent,
|
|
5092
|
+
prompt,
|
|
5093
|
+
failingChecks,
|
|
5094
|
+
currentScore,
|
|
5095
|
+
passingChecks
|
|
5096
|
+
);
|
|
5008
5097
|
return streamGeneration({
|
|
5009
5098
|
systemPrompt: CORE_GENERATION_PROMPT,
|
|
5010
5099
|
userMessage,
|
|
@@ -5015,7 +5104,14 @@ async function generateCore(fingerprint, targetAgent, prompt, callbacks, failing
|
|
|
5015
5104
|
});
|
|
5016
5105
|
}
|
|
5017
5106
|
async function generateMonolithic(fingerprint, targetAgent, prompt, callbacks, failingChecks, currentScore, passingChecks) {
|
|
5018
|
-
const userMessage = buildGeneratePrompt(
|
|
5107
|
+
const userMessage = buildGeneratePrompt(
|
|
5108
|
+
fingerprint,
|
|
5109
|
+
targetAgent,
|
|
5110
|
+
prompt,
|
|
5111
|
+
failingChecks,
|
|
5112
|
+
currentScore,
|
|
5113
|
+
passingChecks
|
|
5114
|
+
);
|
|
5019
5115
|
return streamGeneration({
|
|
5020
5116
|
systemPrompt: GENERATION_SYSTEM_PROMPT,
|
|
5021
5117
|
userMessage,
|
|
@@ -5096,9 +5192,11 @@ function buildGeneratePrompt(fingerprint, targetAgent, prompt, failingChecks, cu
|
|
|
5096
5192
|
const isTargetedFix = failingChecks && failingChecks.length > 0 && currentScore !== void 0 && currentScore >= 95;
|
|
5097
5193
|
if (isTargetedFix) {
|
|
5098
5194
|
parts.push(`TARGETED FIX MODE \u2014 current score: ${currentScore}/100, target: ${targetAgent}`);
|
|
5099
|
-
parts.push(
|
|
5195
|
+
parts.push(
|
|
5196
|
+
`
|
|
5100
5197
|
The existing config is already high quality. ONLY fix these specific failing checks:
|
|
5101
|
-
`
|
|
5198
|
+
`
|
|
5199
|
+
);
|
|
5102
5200
|
for (const check of failingChecks) {
|
|
5103
5201
|
if (check.fix) {
|
|
5104
5202
|
parts.push(`- **${check.name}**`);
|
|
@@ -5129,15 +5227,19 @@ IMPORTANT RULES FOR TARGETED FIX:
|
|
|
5129
5227
|
- For grounding issues: Add references to the listed project directories in the appropriate sections.
|
|
5130
5228
|
- Every path or name you reference MUST exist in the project \u2014 use the file tree provided below.`);
|
|
5131
5229
|
} else if (hasExistingConfigs) {
|
|
5132
|
-
parts.push(
|
|
5230
|
+
parts.push(
|
|
5231
|
+
`Audit and improve the existing coding agent configuration for target: ${targetAgent}`
|
|
5232
|
+
);
|
|
5133
5233
|
} else {
|
|
5134
5234
|
parts.push(`Generate an initial coding agent configuration for target: ${targetAgent}`);
|
|
5135
5235
|
}
|
|
5136
5236
|
if (fingerprint.gitRemoteUrl) parts.push(`
|
|
5137
5237
|
Git remote: ${fingerprint.gitRemoteUrl}`);
|
|
5138
5238
|
if (fingerprint.packageName) parts.push(`Package name: ${fingerprint.packageName}`);
|
|
5139
|
-
if (fingerprint.languages.length > 0)
|
|
5140
|
-
|
|
5239
|
+
if (fingerprint.languages.length > 0)
|
|
5240
|
+
parts.push(`Languages: ${fingerprint.languages.join(", ")}`);
|
|
5241
|
+
if (fingerprint.frameworks.length > 0)
|
|
5242
|
+
parts.push(`Frameworks: ${fingerprint.frameworks.join(", ")}`);
|
|
5141
5243
|
if (fingerprint.description) parts.push(`Project description: ${fingerprint.description}`);
|
|
5142
5244
|
if (fingerprint.fileTree.length > 0) {
|
|
5143
5245
|
const caPaths = fingerprint.codeAnalysis?.files.map((f) => f.path) ?? [];
|
|
@@ -5146,36 +5248,52 @@ Git remote: ${fingerprint.gitRemoteUrl}`);
|
|
|
5146
5248
|
File tree (${tree.length}/${fingerprint.fileTree.length}):
|
|
5147
5249
|
${tree.join("\n")}`);
|
|
5148
5250
|
}
|
|
5149
|
-
if (existing.claudeMd)
|
|
5251
|
+
if (existing.claudeMd)
|
|
5252
|
+
parts.push(
|
|
5253
|
+
`
|
|
5150
5254
|
Existing CLAUDE.md:
|
|
5151
|
-
${truncate(existing.claudeMd, LIMITS.EXISTING_CONFIG_CHARS)}`
|
|
5152
|
-
|
|
5255
|
+
${truncate(existing.claudeMd, LIMITS.EXISTING_CONFIG_CHARS)}`
|
|
5256
|
+
);
|
|
5257
|
+
if (existing.agentsMd)
|
|
5258
|
+
parts.push(
|
|
5259
|
+
`
|
|
5153
5260
|
Existing AGENTS.md:
|
|
5154
|
-
${truncate(existing.agentsMd, LIMITS.EXISTING_CONFIG_CHARS)}`
|
|
5155
|
-
|
|
5261
|
+
${truncate(existing.agentsMd, LIMITS.EXISTING_CONFIG_CHARS)}`
|
|
5262
|
+
);
|
|
5263
|
+
if (existing.readmeMd)
|
|
5264
|
+
parts.push(
|
|
5265
|
+
`
|
|
5156
5266
|
Existing README.md:
|
|
5157
|
-
${truncate(existing.readmeMd, LIMITS.EXISTING_CONFIG_CHARS)}`
|
|
5267
|
+
${truncate(existing.readmeMd, LIMITS.EXISTING_CONFIG_CHARS)}`
|
|
5268
|
+
);
|
|
5158
5269
|
if (existing.claudeSkills?.length) {
|
|
5159
5270
|
parts.push("\n--- Existing Claude Skills ---");
|
|
5160
5271
|
for (const skill of existing.claudeSkills.slice(0, LIMITS.SKILLS_MAX)) {
|
|
5161
|
-
parts.push(
|
|
5272
|
+
parts.push(
|
|
5273
|
+
`
|
|
5162
5274
|
[.claude/skills/${skill.filename}]
|
|
5163
|
-
${truncate(skill.content, LIMITS.SKILL_CHARS)}`
|
|
5275
|
+
${truncate(skill.content, LIMITS.SKILL_CHARS)}`
|
|
5276
|
+
);
|
|
5164
5277
|
}
|
|
5165
5278
|
if (existing.claudeSkills.length > LIMITS.SKILLS_MAX) {
|
|
5166
5279
|
parts.push(`
|
|
5167
5280
|
(${existing.claudeSkills.length - LIMITS.SKILLS_MAX} more skills omitted)`);
|
|
5168
5281
|
}
|
|
5169
5282
|
}
|
|
5170
|
-
if (existing.cursorrules)
|
|
5283
|
+
if (existing.cursorrules)
|
|
5284
|
+
parts.push(
|
|
5285
|
+
`
|
|
5171
5286
|
Existing .cursorrules:
|
|
5172
|
-
${truncate(existing.cursorrules, LIMITS.EXISTING_CONFIG_CHARS)}`
|
|
5287
|
+
${truncate(existing.cursorrules, LIMITS.EXISTING_CONFIG_CHARS)}`
|
|
5288
|
+
);
|
|
5173
5289
|
if (existing.cursorRules?.length) {
|
|
5174
5290
|
parts.push("\n--- Existing Cursor Rules ---");
|
|
5175
5291
|
for (const rule of existing.cursorRules.slice(0, LIMITS.RULES_MAX)) {
|
|
5176
|
-
parts.push(
|
|
5292
|
+
parts.push(
|
|
5293
|
+
`
|
|
5177
5294
|
[.cursor/rules/${rule.filename}]
|
|
5178
|
-
${truncate(rule.content, LIMITS.SKILL_CHARS)}`
|
|
5295
|
+
${truncate(rule.content, LIMITS.SKILL_CHARS)}`
|
|
5296
|
+
);
|
|
5179
5297
|
}
|
|
5180
5298
|
if (existing.cursorRules.length > LIMITS.RULES_MAX) {
|
|
5181
5299
|
parts.push(`
|
|
@@ -5185,9 +5303,11 @@ ${truncate(rule.content, LIMITS.SKILL_CHARS)}`);
|
|
|
5185
5303
|
if (existing.cursorSkills?.length) {
|
|
5186
5304
|
parts.push("\n--- Existing Cursor Skills ---");
|
|
5187
5305
|
for (const skill of existing.cursorSkills.slice(0, LIMITS.SKILLS_MAX)) {
|
|
5188
|
-
parts.push(
|
|
5306
|
+
parts.push(
|
|
5307
|
+
`
|
|
5189
5308
|
[.cursor/skills/${skill.name}/SKILL.md]
|
|
5190
|
-
${truncate(skill.content, LIMITS.SKILL_CHARS)}`
|
|
5309
|
+
${truncate(skill.content, LIMITS.SKILL_CHARS)}`
|
|
5310
|
+
);
|
|
5191
5311
|
}
|
|
5192
5312
|
if (existing.cursorSkills.length > LIMITS.SKILLS_MAX) {
|
|
5193
5313
|
parts.push(`
|
|
@@ -5195,9 +5315,11 @@ ${truncate(skill.content, LIMITS.SKILL_CHARS)}`);
|
|
|
5195
5315
|
}
|
|
5196
5316
|
}
|
|
5197
5317
|
if (existing.personalLearnings) {
|
|
5198
|
-
parts.push(
|
|
5318
|
+
parts.push(
|
|
5319
|
+
`
|
|
5199
5320
|
--- Personal Learnings (developer-specific, include in generated configs) ---
|
|
5200
|
-
${existing.personalLearnings}`
|
|
5321
|
+
${existing.personalLearnings}`
|
|
5322
|
+
);
|
|
5201
5323
|
}
|
|
5202
5324
|
const allDeps = extractAllDeps(process.cwd());
|
|
5203
5325
|
if (allDeps.length > 0) {
|
|
@@ -5263,7 +5385,10 @@ import fs12 from "fs";
|
|
|
5263
5385
|
import path12 from "path";
|
|
5264
5386
|
function writeClaudeConfig(config) {
|
|
5265
5387
|
const written = [];
|
|
5266
|
-
fs12.writeFileSync(
|
|
5388
|
+
fs12.writeFileSync(
|
|
5389
|
+
"CLAUDE.md",
|
|
5390
|
+
appendSyncBlock(appendLearningsBlock(appendPreCommitBlock(config.claudeMd)))
|
|
5391
|
+
);
|
|
5267
5392
|
written.push("CLAUDE.md");
|
|
5268
5393
|
if (config.skills?.length) {
|
|
5269
5394
|
for (const skill of config.skills) {
|
|
@@ -7864,10 +7989,13 @@ async function searchSkills(fingerprint, targetPlatforms, onStatus) {
|
|
|
7864
7989
|
if (!newCandidates.length) {
|
|
7865
7990
|
return { results: [], contentMap: /* @__PURE__ */ new Map() };
|
|
7866
7991
|
}
|
|
7867
|
-
onStatus?.(`Scoring ${newCandidates.length} candidates...`);
|
|
7868
7992
|
let results;
|
|
7869
7993
|
const config = loadConfig();
|
|
7870
|
-
if (
|
|
7994
|
+
if (newCandidates.length <= 5) {
|
|
7995
|
+
onStatus?.("Few candidates \u2014 skipping scoring");
|
|
7996
|
+
results = newCandidates.map((c) => ({ ...c, score: 70 }));
|
|
7997
|
+
} else if (config) {
|
|
7998
|
+
onStatus?.(`Scoring ${newCandidates.length} candidates...`);
|
|
7871
7999
|
try {
|
|
7872
8000
|
const projectContext = buildProjectContext(fingerprint, targetPlatforms);
|
|
7873
8001
|
results = await scoreWithLLM(newCandidates, projectContext, technologies);
|
|
@@ -8286,7 +8414,8 @@ function printSkills(recs) {
|
|
|
8286
8414
|
// src/ai/score-refine.ts
|
|
8287
8415
|
import { existsSync as existsSync9 } from "fs";
|
|
8288
8416
|
import ora2 from "ora";
|
|
8289
|
-
var MAX_REFINE_ITERATIONS =
|
|
8417
|
+
var MAX_REFINE_ITERATIONS = 1;
|
|
8418
|
+
var MIN_POINTS_TO_REFINE = 4;
|
|
8290
8419
|
function extractConfigContent(setup) {
|
|
8291
8420
|
const claude = setup.claude;
|
|
8292
8421
|
const codex = setup.codex;
|
|
@@ -8296,7 +8425,11 @@ function extractConfigContent(setup) {
|
|
|
8296
8425
|
cursorrules = cursor.cursorrules;
|
|
8297
8426
|
}
|
|
8298
8427
|
const skills = [];
|
|
8299
|
-
for (const [platform, obj] of [
|
|
8428
|
+
for (const [platform, obj] of [
|
|
8429
|
+
["claude", claude],
|
|
8430
|
+
["codex", codex],
|
|
8431
|
+
["cursor", cursor]
|
|
8432
|
+
]) {
|
|
8300
8433
|
const platformSkills = obj?.skills;
|
|
8301
8434
|
if (Array.isArray(platformSkills)) {
|
|
8302
8435
|
for (const skill of platformSkills) {
|
|
@@ -8315,8 +8448,12 @@ function extractConfigContent(setup) {
|
|
|
8315
8448
|
}
|
|
8316
8449
|
function buildGroundingFixInstruction(unmentionedTopDirs, projectStructure) {
|
|
8317
8450
|
const dirDescriptions = unmentionedTopDirs.slice(0, 8).map((dir) => {
|
|
8318
|
-
const subdirs = projectStructure.dirs.filter(
|
|
8319
|
-
|
|
8451
|
+
const subdirs = projectStructure.dirs.filter(
|
|
8452
|
+
(d) => d.startsWith(`${dir}/`) && !d.includes("/", dir.length + 1)
|
|
8453
|
+
);
|
|
8454
|
+
const files = projectStructure.files.filter(
|
|
8455
|
+
(f) => f.startsWith(`${dir}/`) && !f.includes("/", dir.length + 1)
|
|
8456
|
+
);
|
|
8320
8457
|
const children = [...subdirs.slice(0, 4), ...files.slice(0, 2)];
|
|
8321
8458
|
const childList = children.map((c) => c.split("/").pop()).join(", ");
|
|
8322
8459
|
return childList ? `- \`${dir}/\` (contains: ${childList})` : `- \`${dir}/\``;
|
|
@@ -8361,7 +8498,9 @@ function validateSetup(setup, dir, checkExists = existsSync9, projectStructure)
|
|
|
8361
8498
|
const content = claudeMd ?? agentsMd ?? "";
|
|
8362
8499
|
if (content) {
|
|
8363
8500
|
const structure2 = analyzeMarkdownStructure(content);
|
|
8364
|
-
const blockThreshold = CODE_BLOCK_THRESHOLDS.find(
|
|
8501
|
+
const blockThreshold = CODE_BLOCK_THRESHOLDS.find(
|
|
8502
|
+
(t) => structure2.codeBlockCount >= t.minBlocks
|
|
8503
|
+
);
|
|
8365
8504
|
const blockPoints = blockThreshold?.points ?? 0;
|
|
8366
8505
|
const maxBlockPoints = CODE_BLOCK_THRESHOLDS[0].points;
|
|
8367
8506
|
if (blockPoints < maxBlockPoints && structure2.codeBlockCount < CODE_BLOCK_THRESHOLDS[0].minBlocks) {
|
|
@@ -8486,7 +8625,9 @@ function buildFeedbackMessage(issues) {
|
|
|
8486
8625
|
];
|
|
8487
8626
|
for (let i = 0; i < issues.length; i++) {
|
|
8488
8627
|
const issue = issues[i];
|
|
8489
|
-
lines.push(
|
|
8628
|
+
lines.push(
|
|
8629
|
+
`${i + 1}. ${issue.check.toUpperCase()} (-${issue.pointsLost} pts): ${issue.detail}`
|
|
8630
|
+
);
|
|
8490
8631
|
lines.push(` Action: ${issue.fixInstruction}
|
|
8491
8632
|
`);
|
|
8492
8633
|
}
|
|
@@ -8495,7 +8636,9 @@ function buildFeedbackMessage(issues) {
|
|
|
8495
8636
|
function countIssuePoints(issues) {
|
|
8496
8637
|
return issues.reduce((sum, i) => sum + i.pointsLost, 0);
|
|
8497
8638
|
}
|
|
8498
|
-
async function scoreAndRefine(setup, dir, sessionHistory, callbacks) {
|
|
8639
|
+
async function scoreAndRefine(setup, dir, sessionHistory, callbacks, options) {
|
|
8640
|
+
const maxIterations = options?.thorough ? 3 : MAX_REFINE_ITERATIONS;
|
|
8641
|
+
const minPoints = options?.thorough ? 1 : MIN_POINTS_TO_REFINE;
|
|
8499
8642
|
const existsCache = /* @__PURE__ */ new Map();
|
|
8500
8643
|
const cachedExists = (path43) => {
|
|
8501
8644
|
const cached = existsCache.get(path43);
|
|
@@ -8508,7 +8651,7 @@ async function scoreAndRefine(setup, dir, sessionHistory, callbacks) {
|
|
|
8508
8651
|
let currentSetup = setup;
|
|
8509
8652
|
let bestSetup = setup;
|
|
8510
8653
|
let bestLostPoints = Infinity;
|
|
8511
|
-
for (let iteration = 0; iteration <
|
|
8654
|
+
for (let iteration = 0; iteration < maxIterations; iteration++) {
|
|
8512
8655
|
const issues = validateSetup(currentSetup, dir, cachedExists, projectStructure);
|
|
8513
8656
|
const lostPoints = countIssuePoints(issues);
|
|
8514
8657
|
if (lostPoints < bestLostPoints) {
|
|
@@ -8519,10 +8662,16 @@ async function scoreAndRefine(setup, dir, sessionHistory, callbacks) {
|
|
|
8519
8662
|
if (callbacks?.onStatus) callbacks.onStatus("Config passes all scoring checks");
|
|
8520
8663
|
return bestSetup;
|
|
8521
8664
|
}
|
|
8665
|
+
if (lostPoints < minPoints) {
|
|
8666
|
+
if (callbacks?.onStatus) callbacks.onStatus("Minor issues \u2014 skipping refinement");
|
|
8667
|
+
return bestSetup;
|
|
8668
|
+
}
|
|
8522
8669
|
const pointIssues = issues.filter((i) => i.pointsLost > 0);
|
|
8523
8670
|
const pointIssueNames = pointIssues.map((i) => i.check).join(", ");
|
|
8524
8671
|
if (callbacks?.onStatus) {
|
|
8525
|
-
callbacks.onStatus(
|
|
8672
|
+
callbacks.onStatus(
|
|
8673
|
+
`Fixing ${pointIssues.length} scoring issue${pointIssues.length === 1 ? "" : "s"}: ${pointIssueNames}...`
|
|
8674
|
+
);
|
|
8526
8675
|
}
|
|
8527
8676
|
const refined = await applyTargetedFixes(currentSetup, issues);
|
|
8528
8677
|
if (!refined) {
|
|
@@ -8557,17 +8706,19 @@ async function applyTargetedFixes(setup, issues) {
|
|
|
8557
8706
|
}
|
|
8558
8707
|
for (const skill of skills) {
|
|
8559
8708
|
if (failingChecks.has(`Skill quality: ${skill.name}`)) {
|
|
8560
|
-
targets.push({
|
|
8709
|
+
targets.push({
|
|
8710
|
+
key: `skill:${skill.name}`,
|
|
8711
|
+
label: `Skill: ${skill.name}`,
|
|
8712
|
+
content: skill.content
|
|
8713
|
+
});
|
|
8561
8714
|
}
|
|
8562
8715
|
}
|
|
8563
8716
|
if (targets.length === 0) return null;
|
|
8564
8717
|
const feedbackMessage = buildFeedbackMessage(issues);
|
|
8565
|
-
const contentBlock = targets.map(
|
|
8566
|
-
(t) => `### ${t.label}
|
|
8718
|
+
const contentBlock = targets.map((t) => `### ${t.label}
|
|
8567
8719
|
\`\`\`markdown
|
|
8568
8720
|
${t.content}
|
|
8569
|
-
\`\`\``
|
|
8570
|
-
).join("\n\n");
|
|
8721
|
+
\`\`\``).join("\n\n");
|
|
8571
8722
|
const prompt = [
|
|
8572
8723
|
"Here are the config files with scoring issues:\n",
|
|
8573
8724
|
contentBlock,
|
|
@@ -8618,14 +8769,20 @@ Return ONLY the fixed content as a JSON object with keys ${targets.map((t) => `"
|
|
|
8618
8769
|
return null;
|
|
8619
8770
|
}
|
|
8620
8771
|
}
|
|
8621
|
-
async function runScoreRefineWithSpinner(setup, dir, sessionHistory) {
|
|
8772
|
+
async function runScoreRefineWithSpinner(setup, dir, sessionHistory, options) {
|
|
8622
8773
|
const spinner = ora2("Validating config against scoring criteria...").start();
|
|
8623
8774
|
try {
|
|
8624
|
-
const refined = await scoreAndRefine(
|
|
8625
|
-
|
|
8626
|
-
|
|
8627
|
-
|
|
8628
|
-
|
|
8775
|
+
const refined = await scoreAndRefine(
|
|
8776
|
+
setup,
|
|
8777
|
+
dir,
|
|
8778
|
+
sessionHistory,
|
|
8779
|
+
{
|
|
8780
|
+
onStatus: (msg) => {
|
|
8781
|
+
spinner.text = msg;
|
|
8782
|
+
}
|
|
8783
|
+
},
|
|
8784
|
+
options
|
|
8785
|
+
);
|
|
8629
8786
|
if (refined !== setup) {
|
|
8630
8787
|
spinner.succeed("Config refined based on scoring feedback");
|
|
8631
8788
|
} else {
|
|
@@ -9365,6 +9522,7 @@ async function refineLoop(currentSetup, sessionHistory, summarizeSetup2, printSu
|
|
|
9365
9522
|
// src/commands/init-display.ts
|
|
9366
9523
|
import chalk12 from "chalk";
|
|
9367
9524
|
import fs31 from "fs";
|
|
9525
|
+
init_types();
|
|
9368
9526
|
function formatWhatChanged(setup) {
|
|
9369
9527
|
const lines = [];
|
|
9370
9528
|
const claude = setup.claude;
|
|
@@ -9534,7 +9692,11 @@ function displayTokenUsage() {
|
|
|
9534
9692
|
console.log(chalk12.dim(" Token tracking not available for this provider.\n"));
|
|
9535
9693
|
return;
|
|
9536
9694
|
}
|
|
9537
|
-
|
|
9695
|
+
const config = loadConfig();
|
|
9696
|
+
const isEstimated = config != null && isSeatBased(config.provider);
|
|
9697
|
+
const label = isEstimated ? "Estimated token usage:" : "Token usage:";
|
|
9698
|
+
console.log(chalk12.bold(` ${label}
|
|
9699
|
+
`));
|
|
9538
9700
|
let totalIn = 0;
|
|
9539
9701
|
let totalOut = 0;
|
|
9540
9702
|
for (const m of summary) {
|
|
@@ -9552,6 +9714,9 @@ function displayTokenUsage() {
|
|
|
9552
9714
|
` ${chalk12.dim("Total")}: ${totalIn.toLocaleString()} in / ${totalOut.toLocaleString()} out`
|
|
9553
9715
|
);
|
|
9554
9716
|
}
|
|
9717
|
+
if (isEstimated) {
|
|
9718
|
+
console.log(chalk12.dim(" (Estimated from character count)"));
|
|
9719
|
+
}
|
|
9555
9720
|
console.log("");
|
|
9556
9721
|
}
|
|
9557
9722
|
|
|
@@ -10233,9 +10398,15 @@ async function initCommand(options) {
|
|
|
10233
10398
|
content: summarizeSetup("Initial generation", generatedSetup)
|
|
10234
10399
|
});
|
|
10235
10400
|
try {
|
|
10236
|
-
const refined = await scoreAndRefine(
|
|
10237
|
-
|
|
10238
|
-
|
|
10401
|
+
const refined = await scoreAndRefine(
|
|
10402
|
+
generatedSetup,
|
|
10403
|
+
process.cwd(),
|
|
10404
|
+
sessionHistory,
|
|
10405
|
+
{
|
|
10406
|
+
onStatus: (msg) => display.update(TASK_SCORE_REFINE, "running", msg)
|
|
10407
|
+
},
|
|
10408
|
+
{ thorough: options.thorough }
|
|
10409
|
+
);
|
|
10239
10410
|
if (refined !== generatedSetup) {
|
|
10240
10411
|
display.update(TASK_SCORE_REFINE, "done", "Refined");
|
|
10241
10412
|
generatedSetup = refined;
|
|
@@ -11354,7 +11525,8 @@ function detectSyncedAgents(writtenFiles) {
|
|
|
11354
11525
|
const joined = writtenFiles.join(" ");
|
|
11355
11526
|
if (joined.includes("CLAUDE.md") || joined.includes(".claude/")) agents.push("Claude Code");
|
|
11356
11527
|
if (joined.includes(".cursor/") || joined.includes(".cursorrules")) agents.push("Cursor");
|
|
11357
|
-
if (joined.includes("copilot-instructions") || joined.includes(".github/instructions/"))
|
|
11528
|
+
if (joined.includes("copilot-instructions") || joined.includes(".github/instructions/"))
|
|
11529
|
+
agents.push("Copilot");
|
|
11358
11530
|
if (joined.includes("AGENTS.md") || joined.includes(".agents/")) agents.push("Codex");
|
|
11359
11531
|
return agents;
|
|
11360
11532
|
}
|
|
@@ -13426,9 +13598,7 @@ async function uninstallCommand(options) {
|
|
|
13426
13598
|
|
|
13427
13599
|
// src/cli.ts
|
|
13428
13600
|
var __dirname = path41.dirname(fileURLToPath(import.meta.url));
|
|
13429
|
-
var pkg = JSON.parse(
|
|
13430
|
-
fs50.readFileSync(path41.resolve(__dirname, "..", "package.json"), "utf-8")
|
|
13431
|
-
);
|
|
13601
|
+
var pkg = JSON.parse(fs50.readFileSync(path41.resolve(__dirname, "..", "package.json"), "utf-8"));
|
|
13432
13602
|
var program = new Command();
|
|
13433
13603
|
var displayVersion = process.env.CALIBER_LOCAL ? `${pkg.version}-local` : pkg.version;
|
|
13434
13604
|
program.name(process.env.CALIBER_LOCAL ? "caloc" : "caliber").description("AI context infrastructure for coding agents").version(displayVersion).option("--no-traces", "Disable anonymous telemetry for this run");
|
|
@@ -13483,22 +13653,38 @@ function parseAgentOption(value) {
|
|
|
13483
13653
|
if (value === "both") return ["claude", "cursor"];
|
|
13484
13654
|
if (value === "all") return ["claude", "cursor", "codex", "opencode", "github-copilot"];
|
|
13485
13655
|
const valid = ["claude", "cursor", "codex", "opencode", "github-copilot"];
|
|
13486
|
-
const agents = [
|
|
13656
|
+
const agents = [
|
|
13657
|
+
...new Set(
|
|
13658
|
+
value.split(",").map((s) => s.trim().toLowerCase()).filter((a) => valid.includes(a))
|
|
13659
|
+
)
|
|
13660
|
+
];
|
|
13487
13661
|
if (agents.length === 0) {
|
|
13488
|
-
console.error(
|
|
13662
|
+
console.error(
|
|
13663
|
+
`Invalid agent "${value}". Choose from: claude, cursor, codex, opencode, github-copilot (comma-separated for multiple)`
|
|
13664
|
+
);
|
|
13489
13665
|
process.exit(1);
|
|
13490
13666
|
}
|
|
13491
13667
|
return agents;
|
|
13492
13668
|
}
|
|
13493
|
-
program.command("init").description("Initialize your project for AI-assisted development").option(
|
|
13494
|
-
|
|
13669
|
+
program.command("init").description("Initialize your project for AI-assisted development").option(
|
|
13670
|
+
"--agent <type>",
|
|
13671
|
+
"Target agents (comma-separated): claude, cursor, codex, opencode, github-copilot",
|
|
13672
|
+
parseAgentOption
|
|
13673
|
+
).option("--source <paths...>", "Related source paths to include as context").option("--dry-run", "Preview changes without writing files").option("--force", "Overwrite existing config without prompting").option("--debug-report", void 0, false).option("--show-tokens", "Show token usage summary at the end").option("--auto-approve", "Run without interactive prompts (auto-accept all)").option("--verbose", "Show detailed logs of each step").option("--thorough", "Deep analysis \u2014 more refinement passes for maximum quality").action(tracked("init", initCommand));
|
|
13674
|
+
program.command("bootstrap").description(
|
|
13675
|
+
"Install agent skills (/setup-caliber, /find-skills, /save-learning) without running init"
|
|
13676
|
+
).action(tracked("bootstrap", bootstrapCommand));
|
|
13495
13677
|
program.command("undo").description("Revert all config changes made by Caliber").action(tracked("undo", undoCommand));
|
|
13496
13678
|
program.command("uninstall").description("Remove all Caliber resources from this project").option("--force", "Skip confirmation prompt").action(tracked("uninstall", (options) => uninstallCommand(options)));
|
|
13497
13679
|
program.command("status").description("Show current Caliber config status").option("--json", "Output as JSON").action(tracked("status", statusCommand));
|
|
13498
13680
|
program.command("regenerate").alias("regen").alias("re").description("Re-analyze project and regenerate config").option("--dry-run", "Preview changes without writing files").action(tracked("regenerate", regenerateCommand));
|
|
13499
13681
|
program.command("config").description("Configure LLM provider, API key, and model").action(tracked("config", configCommand));
|
|
13500
13682
|
program.command("skills").description("Discover and install community skills for your project").option("--query <terms>", 'Search for skills by topic (e.g. "react frontend")').option("--install <slugs>", "Install specific skills by slug (comma-separated)").action(tracked("skills", recommendCommand));
|
|
13501
|
-
program.command("score").description("Score your AI context configuration (deterministic, no network)").option("--json", "Output as JSON").option("--quiet", "One-line output for scripts/hooks").option(
|
|
13683
|
+
program.command("score").description("Score your AI context configuration (deterministic, no network)").option("--json", "Output as JSON").option("--quiet", "One-line output for scripts/hooks").option(
|
|
13684
|
+
"--agent <type>",
|
|
13685
|
+
"Target agents (comma-separated): claude, cursor, codex, opencode, github-copilot",
|
|
13686
|
+
parseAgentOption
|
|
13687
|
+
).option("--compare <ref>", "Compare score against a git ref (branch, tag, or SHA)").action(tracked("score", scoreCommand));
|
|
13502
13688
|
program.command("refresh").description("Update docs based on recent code changes").option("--quiet", "Suppress output (for use in hooks)").option("--dry-run", "Preview changes without writing files").action(tracked("refresh", refreshCommand));
|
|
13503
13689
|
program.command("hooks").description("Manage auto-refresh hooks (toggle interactively)").option("--install", "Enable all hooks non-interactively").option("--remove", "Disable all hooks non-interactively").action(tracked("hooks", hooksCommand));
|
|
13504
13690
|
program.command("insights").description("Show agent performance insights and learning impact").option("--json", "Output as JSON").action(tracked("insights", insightsCommand));
|
|
@@ -13509,7 +13695,12 @@ sources.command("remove").description("Remove a configured source").argument("<n
|
|
|
13509
13695
|
program.command("publish").description("Generate a machine-readable summary for other repos to consume").action(tracked("publish", publishCommand));
|
|
13510
13696
|
var learn = program.command("learn").description("Manage session learning \u2014 extract patterns from your AI coding sessions");
|
|
13511
13697
|
learn.command("observe").description("Record a tool event from stdin (called by hooks)").option("--failure", "Mark event as a tool failure").option("--prompt", "Record a user prompt event").action(tracked("learn:observe", learnObserveCommand));
|
|
13512
|
-
learn.command("finalize").description("Analyze session events and update CALIBER_LEARNINGS.md (called on SessionEnd)").option("--force", "Skip the running-process check (for manual invocation)").option("--auto", "Silent mode for hooks (lower threshold, no interactive output)").option("--incremental", "Extract learnings mid-session without clearing events").action(
|
|
13698
|
+
learn.command("finalize").description("Analyze session events and update CALIBER_LEARNINGS.md (called on SessionEnd)").option("--force", "Skip the running-process check (for manual invocation)").option("--auto", "Silent mode for hooks (lower threshold, no interactive output)").option("--incremental", "Extract learnings mid-session without clearing events").action(
|
|
13699
|
+
tracked(
|
|
13700
|
+
"learn:finalize",
|
|
13701
|
+
(opts) => learnFinalizeCommand(opts)
|
|
13702
|
+
)
|
|
13703
|
+
);
|
|
13513
13704
|
learn.command("install").description("Install learning hooks into .claude/settings.json").action(tracked("learn:install", learnInstallCommand));
|
|
13514
13705
|
learn.command("remove").description("Remove learning hooks from .claude/settings.json").action(tracked("learn:remove", learnRemoveCommand));
|
|
13515
13706
|
learn.command("status").description("Show learning system status").action(tracked("learn:status", learnStatusCommand));
|
package/package.json
CHANGED