@rely-ai/caliber 1.7.4 → 1.7.6
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 +369 -194
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -165,17 +165,18 @@ var init_constants = __esm({
|
|
|
165
165
|
|
|
166
166
|
// src/cli.ts
|
|
167
167
|
import { Command } from "commander";
|
|
168
|
-
import
|
|
169
|
-
import
|
|
168
|
+
import fs30 from "fs";
|
|
169
|
+
import path24 from "path";
|
|
170
170
|
import { fileURLToPath } from "url";
|
|
171
171
|
|
|
172
172
|
// src/commands/onboard.ts
|
|
173
|
+
import path19 from "path";
|
|
173
174
|
import chalk8 from "chalk";
|
|
174
175
|
import ora2 from "ora";
|
|
175
176
|
import readline3 from "readline";
|
|
176
177
|
import select5 from "@inquirer/select";
|
|
177
178
|
import checkbox from "@inquirer/checkbox";
|
|
178
|
-
import
|
|
179
|
+
import fs24 from "fs";
|
|
179
180
|
|
|
180
181
|
// src/fingerprint/index.ts
|
|
181
182
|
import fs6 from "fs";
|
|
@@ -2670,28 +2671,64 @@ ${agentRefs.join(" ")}
|
|
|
2670
2671
|
}
|
|
2671
2672
|
|
|
2672
2673
|
// src/lib/hooks.ts
|
|
2673
|
-
import
|
|
2674
|
+
import fs17 from "fs";
|
|
2674
2675
|
import path12 from "path";
|
|
2676
|
+
import { execSync as execSync6 } from "child_process";
|
|
2677
|
+
|
|
2678
|
+
// src/lib/resolve-caliber.ts
|
|
2679
|
+
import fs16 from "fs";
|
|
2675
2680
|
import { execSync as execSync5 } from "child_process";
|
|
2681
|
+
var _resolved = null;
|
|
2682
|
+
function resolveCaliber() {
|
|
2683
|
+
if (_resolved) return _resolved;
|
|
2684
|
+
try {
|
|
2685
|
+
const found = execSync5("which caliber", {
|
|
2686
|
+
encoding: "utf-8",
|
|
2687
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
2688
|
+
}).trim();
|
|
2689
|
+
if (found) {
|
|
2690
|
+
_resolved = found;
|
|
2691
|
+
return _resolved;
|
|
2692
|
+
}
|
|
2693
|
+
} catch {
|
|
2694
|
+
}
|
|
2695
|
+
const binPath = process.argv[1];
|
|
2696
|
+
if (binPath && fs16.existsSync(binPath)) {
|
|
2697
|
+
_resolved = binPath;
|
|
2698
|
+
return _resolved;
|
|
2699
|
+
}
|
|
2700
|
+
_resolved = "caliber";
|
|
2701
|
+
return _resolved;
|
|
2702
|
+
}
|
|
2703
|
+
function isCaliberCommand(command, subcommandTail) {
|
|
2704
|
+
if (command === `caliber ${subcommandTail}`) return true;
|
|
2705
|
+
if (command.endsWith(`/caliber ${subcommandTail}`)) return true;
|
|
2706
|
+
return false;
|
|
2707
|
+
}
|
|
2708
|
+
|
|
2709
|
+
// src/lib/hooks.ts
|
|
2676
2710
|
var SETTINGS_PATH = path12.join(".claude", "settings.json");
|
|
2677
|
-
var
|
|
2711
|
+
var REFRESH_TAIL = "refresh --quiet";
|
|
2678
2712
|
var HOOK_DESCRIPTION = "Caliber: auto-refreshing docs based on code changes";
|
|
2713
|
+
function getHookCommand() {
|
|
2714
|
+
return `${resolveCaliber()} ${REFRESH_TAIL}`;
|
|
2715
|
+
}
|
|
2679
2716
|
function readSettings() {
|
|
2680
|
-
if (!
|
|
2717
|
+
if (!fs17.existsSync(SETTINGS_PATH)) return {};
|
|
2681
2718
|
try {
|
|
2682
|
-
return JSON.parse(
|
|
2719
|
+
return JSON.parse(fs17.readFileSync(SETTINGS_PATH, "utf-8"));
|
|
2683
2720
|
} catch {
|
|
2684
2721
|
return {};
|
|
2685
2722
|
}
|
|
2686
2723
|
}
|
|
2687
2724
|
function writeSettings(settings) {
|
|
2688
2725
|
const dir = path12.dirname(SETTINGS_PATH);
|
|
2689
|
-
if (!
|
|
2690
|
-
|
|
2726
|
+
if (!fs17.existsSync(dir)) fs17.mkdirSync(dir, { recursive: true });
|
|
2727
|
+
fs17.writeFileSync(SETTINGS_PATH, JSON.stringify(settings, null, 2));
|
|
2691
2728
|
}
|
|
2692
2729
|
function findHookIndex(sessionEnd) {
|
|
2693
2730
|
return sessionEnd.findIndex(
|
|
2694
|
-
(entry) => entry.hooks?.some((h) => h.command
|
|
2731
|
+
(entry) => entry.hooks?.some((h) => isCaliberCommand(h.command, REFRESH_TAIL))
|
|
2695
2732
|
);
|
|
2696
2733
|
}
|
|
2697
2734
|
function isHookInstalled() {
|
|
@@ -2709,7 +2746,7 @@ function installHook() {
|
|
|
2709
2746
|
}
|
|
2710
2747
|
settings.hooks.SessionEnd.push({
|
|
2711
2748
|
matcher: "",
|
|
2712
|
-
hooks: [{ type: "command", command:
|
|
2749
|
+
hooks: [{ type: "command", command: getHookCommand(), description: HOOK_DESCRIPTION }]
|
|
2713
2750
|
});
|
|
2714
2751
|
writeSettings(settings);
|
|
2715
2752
|
return { installed: true, alreadyInstalled: false };
|
|
@@ -2736,16 +2773,19 @@ function removeHook() {
|
|
|
2736
2773
|
}
|
|
2737
2774
|
var PRECOMMIT_START = "# caliber:pre-commit:start";
|
|
2738
2775
|
var PRECOMMIT_END = "# caliber:pre-commit:end";
|
|
2739
|
-
|
|
2740
|
-
|
|
2776
|
+
function getPrecommitBlock() {
|
|
2777
|
+
const bin = resolveCaliber();
|
|
2778
|
+
return `${PRECOMMIT_START}
|
|
2779
|
+
if [ -x "${bin}" ] || command -v "${bin}" >/dev/null 2>&1; then
|
|
2741
2780
|
echo "\\033[2mcaliber: refreshing docs...\\033[0m"
|
|
2742
|
-
|
|
2781
|
+
"${bin}" refresh 2>/dev/null || true
|
|
2743
2782
|
git diff --name-only -- CLAUDE.md .claude/ .cursor/ AGENTS.md 2>/dev/null | xargs git add 2>/dev/null || true
|
|
2744
2783
|
fi
|
|
2745
2784
|
${PRECOMMIT_END}`;
|
|
2785
|
+
}
|
|
2746
2786
|
function getGitHooksDir() {
|
|
2747
2787
|
try {
|
|
2748
|
-
const gitDir =
|
|
2788
|
+
const gitDir = execSync6("git rev-parse --git-dir", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
2749
2789
|
return path12.join(gitDir, "hooks");
|
|
2750
2790
|
} catch {
|
|
2751
2791
|
return null;
|
|
@@ -2757,8 +2797,8 @@ function getPreCommitPath() {
|
|
|
2757
2797
|
}
|
|
2758
2798
|
function isPreCommitHookInstalled() {
|
|
2759
2799
|
const hookPath = getPreCommitPath();
|
|
2760
|
-
if (!hookPath || !
|
|
2761
|
-
const content =
|
|
2800
|
+
if (!hookPath || !fs17.existsSync(hookPath)) return false;
|
|
2801
|
+
const content = fs17.readFileSync(hookPath, "utf-8");
|
|
2762
2802
|
return content.includes(PRECOMMIT_START);
|
|
2763
2803
|
}
|
|
2764
2804
|
function installPreCommitHook() {
|
|
@@ -2768,81 +2808,78 @@ function installPreCommitHook() {
|
|
|
2768
2808
|
const hookPath = getPreCommitPath();
|
|
2769
2809
|
if (!hookPath) return { installed: false, alreadyInstalled: false };
|
|
2770
2810
|
const hooksDir = path12.dirname(hookPath);
|
|
2771
|
-
if (!
|
|
2811
|
+
if (!fs17.existsSync(hooksDir)) fs17.mkdirSync(hooksDir, { recursive: true });
|
|
2772
2812
|
let content = "";
|
|
2773
|
-
if (
|
|
2774
|
-
content =
|
|
2813
|
+
if (fs17.existsSync(hookPath)) {
|
|
2814
|
+
content = fs17.readFileSync(hookPath, "utf-8");
|
|
2775
2815
|
if (!content.endsWith("\n")) content += "\n";
|
|
2776
|
-
content += "\n" +
|
|
2816
|
+
content += "\n" + getPrecommitBlock() + "\n";
|
|
2777
2817
|
} else {
|
|
2778
|
-
content = "#!/bin/sh\n\n" +
|
|
2818
|
+
content = "#!/bin/sh\n\n" + getPrecommitBlock() + "\n";
|
|
2779
2819
|
}
|
|
2780
|
-
|
|
2781
|
-
|
|
2820
|
+
fs17.writeFileSync(hookPath, content);
|
|
2821
|
+
fs17.chmodSync(hookPath, 493);
|
|
2782
2822
|
return { installed: true, alreadyInstalled: false };
|
|
2783
2823
|
}
|
|
2784
2824
|
function removePreCommitHook() {
|
|
2785
2825
|
const hookPath = getPreCommitPath();
|
|
2786
|
-
if (!hookPath || !
|
|
2826
|
+
if (!hookPath || !fs17.existsSync(hookPath)) {
|
|
2787
2827
|
return { removed: false, notFound: true };
|
|
2788
2828
|
}
|
|
2789
|
-
let content =
|
|
2829
|
+
let content = fs17.readFileSync(hookPath, "utf-8");
|
|
2790
2830
|
if (!content.includes(PRECOMMIT_START)) {
|
|
2791
2831
|
return { removed: false, notFound: true };
|
|
2792
2832
|
}
|
|
2793
2833
|
const regex = new RegExp(`\\n?${PRECOMMIT_START}[\\s\\S]*?${PRECOMMIT_END}\\n?`);
|
|
2794
2834
|
content = content.replace(regex, "\n");
|
|
2795
2835
|
if (content.trim() === "#!/bin/sh" || content.trim() === "") {
|
|
2796
|
-
|
|
2836
|
+
fs17.unlinkSync(hookPath);
|
|
2797
2837
|
} else {
|
|
2798
|
-
|
|
2838
|
+
fs17.writeFileSync(hookPath, content);
|
|
2799
2839
|
}
|
|
2800
2840
|
return { removed: true, notFound: false };
|
|
2801
2841
|
}
|
|
2802
2842
|
|
|
2803
2843
|
// src/lib/learning-hooks.ts
|
|
2804
|
-
import
|
|
2844
|
+
import fs18 from "fs";
|
|
2805
2845
|
import path13 from "path";
|
|
2806
2846
|
var SETTINGS_PATH2 = path13.join(".claude", "settings.json");
|
|
2807
|
-
var
|
|
2808
|
-
{
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
description: "Caliber: recording tool usage for session learning"
|
|
2812
|
-
},
|
|
2813
|
-
{
|
|
2814
|
-
event: "PostToolUseFailure",
|
|
2815
|
-
command: "caliber learn observe --failure",
|
|
2816
|
-
description: "Caliber: recording tool failure for session learning"
|
|
2817
|
-
},
|
|
2818
|
-
{
|
|
2819
|
-
event: "SessionEnd",
|
|
2820
|
-
command: "caliber learn finalize",
|
|
2821
|
-
description: "Caliber: finalizing session learnings"
|
|
2822
|
-
}
|
|
2847
|
+
var HOOK_TAILS = [
|
|
2848
|
+
{ event: "PostToolUse", tail: "learn observe", description: "Caliber: recording tool usage for session learning" },
|
|
2849
|
+
{ event: "PostToolUseFailure", tail: "learn observe --failure", description: "Caliber: recording tool failure for session learning" },
|
|
2850
|
+
{ event: "SessionEnd", tail: "learn finalize", description: "Caliber: finalizing session learnings" }
|
|
2823
2851
|
];
|
|
2852
|
+
function getHookConfigs() {
|
|
2853
|
+
const bin = resolveCaliber();
|
|
2854
|
+
return HOOK_TAILS.map(({ event, tail, description }) => ({
|
|
2855
|
+
event,
|
|
2856
|
+
command: `${bin} ${tail}`,
|
|
2857
|
+
tail,
|
|
2858
|
+
description
|
|
2859
|
+
}));
|
|
2860
|
+
}
|
|
2824
2861
|
function readSettings2() {
|
|
2825
|
-
if (!
|
|
2862
|
+
if (!fs18.existsSync(SETTINGS_PATH2)) return {};
|
|
2826
2863
|
try {
|
|
2827
|
-
return JSON.parse(
|
|
2864
|
+
return JSON.parse(fs18.readFileSync(SETTINGS_PATH2, "utf-8"));
|
|
2828
2865
|
} catch {
|
|
2829
2866
|
return {};
|
|
2830
2867
|
}
|
|
2831
2868
|
}
|
|
2832
2869
|
function writeSettings2(settings) {
|
|
2833
2870
|
const dir = path13.dirname(SETTINGS_PATH2);
|
|
2834
|
-
if (!
|
|
2835
|
-
|
|
2871
|
+
if (!fs18.existsSync(dir)) fs18.mkdirSync(dir, { recursive: true });
|
|
2872
|
+
fs18.writeFileSync(SETTINGS_PATH2, JSON.stringify(settings, null, 2));
|
|
2836
2873
|
}
|
|
2837
|
-
function hasLearningHook(matchers,
|
|
2838
|
-
return matchers.some((entry) => entry.hooks?.some((h) => h.command
|
|
2874
|
+
function hasLearningHook(matchers, tail) {
|
|
2875
|
+
return matchers.some((entry) => entry.hooks?.some((h) => isCaliberCommand(h.command, tail)));
|
|
2839
2876
|
}
|
|
2840
2877
|
function areLearningHooksInstalled() {
|
|
2841
2878
|
const settings = readSettings2();
|
|
2842
2879
|
if (!settings.hooks) return false;
|
|
2843
|
-
return
|
|
2880
|
+
return HOOK_TAILS.every((cfg) => {
|
|
2844
2881
|
const matchers = settings.hooks[cfg.event];
|
|
2845
|
-
return Array.isArray(matchers) && hasLearningHook(matchers, cfg.
|
|
2882
|
+
return Array.isArray(matchers) && hasLearningHook(matchers, cfg.tail);
|
|
2846
2883
|
});
|
|
2847
2884
|
}
|
|
2848
2885
|
function installLearningHooks() {
|
|
@@ -2851,11 +2888,12 @@ function installLearningHooks() {
|
|
|
2851
2888
|
}
|
|
2852
2889
|
const settings = readSettings2();
|
|
2853
2890
|
if (!settings.hooks) settings.hooks = {};
|
|
2854
|
-
|
|
2891
|
+
const configs = getHookConfigs();
|
|
2892
|
+
for (const cfg of configs) {
|
|
2855
2893
|
if (!Array.isArray(settings.hooks[cfg.event])) {
|
|
2856
2894
|
settings.hooks[cfg.event] = [];
|
|
2857
2895
|
}
|
|
2858
|
-
if (!hasLearningHook(settings.hooks[cfg.event], cfg.
|
|
2896
|
+
if (!hasLearningHook(settings.hooks[cfg.event], cfg.tail)) {
|
|
2859
2897
|
settings.hooks[cfg.event].push({
|
|
2860
2898
|
matcher: "",
|
|
2861
2899
|
hooks: [{ type: "command", command: cfg.command, description: cfg.description }]
|
|
@@ -2869,10 +2907,10 @@ function removeLearningHooks() {
|
|
|
2869
2907
|
const settings = readSettings2();
|
|
2870
2908
|
if (!settings.hooks) return { removed: false, notFound: true };
|
|
2871
2909
|
let removedAny = false;
|
|
2872
|
-
for (const cfg of
|
|
2910
|
+
for (const cfg of HOOK_TAILS) {
|
|
2873
2911
|
const matchers = settings.hooks[cfg.event];
|
|
2874
2912
|
if (!Array.isArray(matchers)) continue;
|
|
2875
|
-
const idx = matchers.findIndex((entry) => entry.hooks?.some((h) => h.command
|
|
2913
|
+
const idx = matchers.findIndex((entry) => entry.hooks?.some((h) => isCaliberCommand(h.command, cfg.tail)));
|
|
2876
2914
|
if (idx !== -1) {
|
|
2877
2915
|
matchers.splice(idx, 1);
|
|
2878
2916
|
removedAny = true;
|
|
@@ -2889,9 +2927,9 @@ function removeLearningHooks() {
|
|
|
2889
2927
|
|
|
2890
2928
|
// src/lib/state.ts
|
|
2891
2929
|
init_constants();
|
|
2892
|
-
import
|
|
2930
|
+
import fs19 from "fs";
|
|
2893
2931
|
import path14 from "path";
|
|
2894
|
-
import { execSync as
|
|
2932
|
+
import { execSync as execSync7 } from "child_process";
|
|
2895
2933
|
var STATE_FILE = path14.join(CALIBER_DIR, ".caliber-state.json");
|
|
2896
2934
|
function normalizeTargetAgent(value) {
|
|
2897
2935
|
if (Array.isArray(value)) return value;
|
|
@@ -2903,8 +2941,8 @@ function normalizeTargetAgent(value) {
|
|
|
2903
2941
|
}
|
|
2904
2942
|
function readState() {
|
|
2905
2943
|
try {
|
|
2906
|
-
if (!
|
|
2907
|
-
const raw = JSON.parse(
|
|
2944
|
+
if (!fs19.existsSync(STATE_FILE)) return null;
|
|
2945
|
+
const raw = JSON.parse(fs19.readFileSync(STATE_FILE, "utf-8"));
|
|
2908
2946
|
if (raw.targetAgent) raw.targetAgent = normalizeTargetAgent(raw.targetAgent);
|
|
2909
2947
|
return raw;
|
|
2910
2948
|
} catch {
|
|
@@ -2912,14 +2950,14 @@ function readState() {
|
|
|
2912
2950
|
}
|
|
2913
2951
|
}
|
|
2914
2952
|
function writeState(state) {
|
|
2915
|
-
if (!
|
|
2916
|
-
|
|
2953
|
+
if (!fs19.existsSync(CALIBER_DIR)) {
|
|
2954
|
+
fs19.mkdirSync(CALIBER_DIR, { recursive: true });
|
|
2917
2955
|
}
|
|
2918
|
-
|
|
2956
|
+
fs19.writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));
|
|
2919
2957
|
}
|
|
2920
2958
|
function getCurrentHeadSha() {
|
|
2921
2959
|
try {
|
|
2922
|
-
return
|
|
2960
|
+
return execSync7("git rev-parse HEAD", {
|
|
2923
2961
|
encoding: "utf-8",
|
|
2924
2962
|
stdio: ["pipe", "pipe", "pipe"]
|
|
2925
2963
|
}).trim();
|
|
@@ -3205,15 +3243,15 @@ function computeGrade(score) {
|
|
|
3205
3243
|
// src/scoring/checks/coverage.ts
|
|
3206
3244
|
import { readFileSync, readdirSync } from "fs";
|
|
3207
3245
|
import { join } from "path";
|
|
3208
|
-
function readFileOrNull(
|
|
3246
|
+
function readFileOrNull(path26) {
|
|
3209
3247
|
try {
|
|
3210
|
-
return readFileSync(
|
|
3248
|
+
return readFileSync(path26, "utf-8");
|
|
3211
3249
|
} catch {
|
|
3212
3250
|
return null;
|
|
3213
3251
|
}
|
|
3214
3252
|
}
|
|
3215
|
-
function readJsonOrNull(
|
|
3216
|
-
const content = readFileOrNull(
|
|
3253
|
+
function readJsonOrNull(path26) {
|
|
3254
|
+
const content = readFileOrNull(path26);
|
|
3217
3255
|
if (!content) return null;
|
|
3218
3256
|
try {
|
|
3219
3257
|
return JSON.parse(content);
|
|
@@ -3581,9 +3619,9 @@ function checkExistence(dir) {
|
|
|
3581
3619
|
// src/scoring/checks/quality.ts
|
|
3582
3620
|
import { readFileSync as readFileSync3 } from "fs";
|
|
3583
3621
|
import { join as join3 } from "path";
|
|
3584
|
-
function readFileOrNull2(
|
|
3622
|
+
function readFileOrNull2(path26) {
|
|
3585
3623
|
try {
|
|
3586
|
-
return readFileSync3(
|
|
3624
|
+
return readFileSync3(path26, "utf-8");
|
|
3587
3625
|
} catch {
|
|
3588
3626
|
return null;
|
|
3589
3627
|
}
|
|
@@ -3736,15 +3774,15 @@ function checkQuality(dir) {
|
|
|
3736
3774
|
// src/scoring/checks/accuracy.ts
|
|
3737
3775
|
import { existsSync as existsSync5, readFileSync as readFileSync4, readdirSync as readdirSync3, statSync } from "fs";
|
|
3738
3776
|
import { join as join4 } from "path";
|
|
3739
|
-
function readFileOrNull3(
|
|
3777
|
+
function readFileOrNull3(path26) {
|
|
3740
3778
|
try {
|
|
3741
|
-
return readFileSync4(
|
|
3779
|
+
return readFileSync4(path26, "utf-8");
|
|
3742
3780
|
} catch {
|
|
3743
3781
|
return null;
|
|
3744
3782
|
}
|
|
3745
3783
|
}
|
|
3746
|
-
function readJsonOrNull2(
|
|
3747
|
-
const content = readFileOrNull3(
|
|
3784
|
+
function readJsonOrNull2(path26) {
|
|
3785
|
+
const content = readFileOrNull3(path26);
|
|
3748
3786
|
if (!content) return null;
|
|
3749
3787
|
try {
|
|
3750
3788
|
return JSON.parse(content);
|
|
@@ -3927,9 +3965,9 @@ function checkAccuracy(dir) {
|
|
|
3927
3965
|
// src/scoring/checks/freshness.ts
|
|
3928
3966
|
import { existsSync as existsSync6, readFileSync as readFileSync5, statSync as statSync2 } from "fs";
|
|
3929
3967
|
import { join as join5 } from "path";
|
|
3930
|
-
function readFileOrNull4(
|
|
3968
|
+
function readFileOrNull4(path26) {
|
|
3931
3969
|
try {
|
|
3932
|
-
return readFileSync5(
|
|
3970
|
+
return readFileSync5(path26, "utf-8");
|
|
3933
3971
|
} catch {
|
|
3934
3972
|
return null;
|
|
3935
3973
|
}
|
|
@@ -4041,18 +4079,18 @@ function checkFreshness(dir) {
|
|
|
4041
4079
|
|
|
4042
4080
|
// src/scoring/checks/bonus.ts
|
|
4043
4081
|
import { existsSync as existsSync7, readFileSync as readFileSync6, readdirSync as readdirSync4 } from "fs";
|
|
4044
|
-
import { execSync as
|
|
4082
|
+
import { execSync as execSync8 } from "child_process";
|
|
4045
4083
|
import { join as join6 } from "path";
|
|
4046
|
-
function readFileOrNull5(
|
|
4084
|
+
function readFileOrNull5(path26) {
|
|
4047
4085
|
try {
|
|
4048
|
-
return readFileSync6(
|
|
4086
|
+
return readFileSync6(path26, "utf-8");
|
|
4049
4087
|
} catch {
|
|
4050
4088
|
return null;
|
|
4051
4089
|
}
|
|
4052
4090
|
}
|
|
4053
4091
|
function hasPreCommitHook(dir) {
|
|
4054
4092
|
try {
|
|
4055
|
-
const gitDir =
|
|
4093
|
+
const gitDir = execSync8("git rev-parse --git-dir", { cwd: dir, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
4056
4094
|
const hookPath = join6(gitDir, "hooks", "pre-commit");
|
|
4057
4095
|
const content = readFileOrNull5(hookPath);
|
|
4058
4096
|
return content ? content.includes("caliber") : false;
|
|
@@ -4140,22 +4178,22 @@ function checkBonus(dir) {
|
|
|
4140
4178
|
|
|
4141
4179
|
// src/scoring/dismissed.ts
|
|
4142
4180
|
init_constants();
|
|
4143
|
-
import
|
|
4181
|
+
import fs20 from "fs";
|
|
4144
4182
|
import path15 from "path";
|
|
4145
4183
|
var DISMISSED_FILE = path15.join(CALIBER_DIR, "dismissed-checks.json");
|
|
4146
4184
|
function readDismissedChecks() {
|
|
4147
4185
|
try {
|
|
4148
|
-
if (!
|
|
4149
|
-
return JSON.parse(
|
|
4186
|
+
if (!fs20.existsSync(DISMISSED_FILE)) return [];
|
|
4187
|
+
return JSON.parse(fs20.readFileSync(DISMISSED_FILE, "utf-8"));
|
|
4150
4188
|
} catch {
|
|
4151
4189
|
return [];
|
|
4152
4190
|
}
|
|
4153
4191
|
}
|
|
4154
4192
|
function writeDismissedChecks(checks) {
|
|
4155
|
-
if (!
|
|
4156
|
-
|
|
4193
|
+
if (!fs20.existsSync(CALIBER_DIR)) {
|
|
4194
|
+
fs20.mkdirSync(CALIBER_DIR, { recursive: true });
|
|
4157
4195
|
}
|
|
4158
|
-
|
|
4196
|
+
fs20.writeFileSync(DISMISSED_FILE, JSON.stringify(checks, null, 2) + "\n");
|
|
4159
4197
|
}
|
|
4160
4198
|
function getDismissedIds() {
|
|
4161
4199
|
return new Set(readDismissedChecks().map((c) => c.id));
|
|
@@ -4350,13 +4388,13 @@ import { mkdirSync, readFileSync as readFileSync7, readdirSync as readdirSync5,
|
|
|
4350
4388
|
import { join as join8, dirname as dirname2 } from "path";
|
|
4351
4389
|
|
|
4352
4390
|
// src/scanner/index.ts
|
|
4353
|
-
import
|
|
4391
|
+
import fs21 from "fs";
|
|
4354
4392
|
import path16 from "path";
|
|
4355
4393
|
import crypto2 from "crypto";
|
|
4356
4394
|
function scanLocalState(dir) {
|
|
4357
4395
|
const items = [];
|
|
4358
4396
|
const claudeMdPath = path16.join(dir, "CLAUDE.md");
|
|
4359
|
-
if (
|
|
4397
|
+
if (fs21.existsSync(claudeMdPath)) {
|
|
4360
4398
|
items.push({
|
|
4361
4399
|
type: "rule",
|
|
4362
4400
|
platform: "claude",
|
|
@@ -4366,8 +4404,8 @@ function scanLocalState(dir) {
|
|
|
4366
4404
|
});
|
|
4367
4405
|
}
|
|
4368
4406
|
const skillsDir = path16.join(dir, ".claude", "skills");
|
|
4369
|
-
if (
|
|
4370
|
-
for (const file of
|
|
4407
|
+
if (fs21.existsSync(skillsDir)) {
|
|
4408
|
+
for (const file of fs21.readdirSync(skillsDir).filter((f) => f.endsWith(".md"))) {
|
|
4371
4409
|
const filePath = path16.join(skillsDir, file);
|
|
4372
4410
|
items.push({
|
|
4373
4411
|
type: "skill",
|
|
@@ -4379,9 +4417,9 @@ function scanLocalState(dir) {
|
|
|
4379
4417
|
}
|
|
4380
4418
|
}
|
|
4381
4419
|
const mcpJsonPath = path16.join(dir, ".mcp.json");
|
|
4382
|
-
if (
|
|
4420
|
+
if (fs21.existsSync(mcpJsonPath)) {
|
|
4383
4421
|
try {
|
|
4384
|
-
const mcpJson = JSON.parse(
|
|
4422
|
+
const mcpJson = JSON.parse(fs21.readFileSync(mcpJsonPath, "utf-8"));
|
|
4385
4423
|
if (mcpJson.mcpServers) {
|
|
4386
4424
|
for (const name of Object.keys(mcpJson.mcpServers)) {
|
|
4387
4425
|
items.push({
|
|
@@ -4397,7 +4435,7 @@ function scanLocalState(dir) {
|
|
|
4397
4435
|
}
|
|
4398
4436
|
}
|
|
4399
4437
|
const agentsMdPath = path16.join(dir, "AGENTS.md");
|
|
4400
|
-
if (
|
|
4438
|
+
if (fs21.existsSync(agentsMdPath)) {
|
|
4401
4439
|
items.push({
|
|
4402
4440
|
type: "rule",
|
|
4403
4441
|
platform: "codex",
|
|
@@ -4407,11 +4445,11 @@ function scanLocalState(dir) {
|
|
|
4407
4445
|
});
|
|
4408
4446
|
}
|
|
4409
4447
|
const codexSkillsDir = path16.join(dir, ".agents", "skills");
|
|
4410
|
-
if (
|
|
4448
|
+
if (fs21.existsSync(codexSkillsDir)) {
|
|
4411
4449
|
try {
|
|
4412
|
-
for (const name of
|
|
4450
|
+
for (const name of fs21.readdirSync(codexSkillsDir)) {
|
|
4413
4451
|
const skillFile = path16.join(codexSkillsDir, name, "SKILL.md");
|
|
4414
|
-
if (
|
|
4452
|
+
if (fs21.existsSync(skillFile)) {
|
|
4415
4453
|
items.push({
|
|
4416
4454
|
type: "skill",
|
|
4417
4455
|
platform: "codex",
|
|
@@ -4425,7 +4463,7 @@ function scanLocalState(dir) {
|
|
|
4425
4463
|
}
|
|
4426
4464
|
}
|
|
4427
4465
|
const cursorrulesPath = path16.join(dir, ".cursorrules");
|
|
4428
|
-
if (
|
|
4466
|
+
if (fs21.existsSync(cursorrulesPath)) {
|
|
4429
4467
|
items.push({
|
|
4430
4468
|
type: "rule",
|
|
4431
4469
|
platform: "cursor",
|
|
@@ -4435,8 +4473,8 @@ function scanLocalState(dir) {
|
|
|
4435
4473
|
});
|
|
4436
4474
|
}
|
|
4437
4475
|
const cursorRulesDir = path16.join(dir, ".cursor", "rules");
|
|
4438
|
-
if (
|
|
4439
|
-
for (const file of
|
|
4476
|
+
if (fs21.existsSync(cursorRulesDir)) {
|
|
4477
|
+
for (const file of fs21.readdirSync(cursorRulesDir).filter((f) => f.endsWith(".mdc"))) {
|
|
4440
4478
|
const filePath = path16.join(cursorRulesDir, file);
|
|
4441
4479
|
items.push({
|
|
4442
4480
|
type: "rule",
|
|
@@ -4448,11 +4486,11 @@ function scanLocalState(dir) {
|
|
|
4448
4486
|
}
|
|
4449
4487
|
}
|
|
4450
4488
|
const cursorSkillsDir = path16.join(dir, ".cursor", "skills");
|
|
4451
|
-
if (
|
|
4489
|
+
if (fs21.existsSync(cursorSkillsDir)) {
|
|
4452
4490
|
try {
|
|
4453
|
-
for (const name of
|
|
4491
|
+
for (const name of fs21.readdirSync(cursorSkillsDir)) {
|
|
4454
4492
|
const skillFile = path16.join(cursorSkillsDir, name, "SKILL.md");
|
|
4455
|
-
if (
|
|
4493
|
+
if (fs21.existsSync(skillFile)) {
|
|
4456
4494
|
items.push({
|
|
4457
4495
|
type: "skill",
|
|
4458
4496
|
platform: "cursor",
|
|
@@ -4466,9 +4504,9 @@ function scanLocalState(dir) {
|
|
|
4466
4504
|
}
|
|
4467
4505
|
}
|
|
4468
4506
|
const cursorMcpPath = path16.join(dir, ".cursor", "mcp.json");
|
|
4469
|
-
if (
|
|
4507
|
+
if (fs21.existsSync(cursorMcpPath)) {
|
|
4470
4508
|
try {
|
|
4471
|
-
const mcpJson = JSON.parse(
|
|
4509
|
+
const mcpJson = JSON.parse(fs21.readFileSync(cursorMcpPath, "utf-8"));
|
|
4472
4510
|
if (mcpJson.mcpServers) {
|
|
4473
4511
|
for (const name of Object.keys(mcpJson.mcpServers)) {
|
|
4474
4512
|
items.push({
|
|
@@ -4486,7 +4524,7 @@ function scanLocalState(dir) {
|
|
|
4486
4524
|
return items;
|
|
4487
4525
|
}
|
|
4488
4526
|
function hashFile(filePath) {
|
|
4489
|
-
const text =
|
|
4527
|
+
const text = fs21.readFileSync(filePath, "utf-8");
|
|
4490
4528
|
return crypto2.createHash("sha256").update(JSON.stringify({ text })).digest("hex");
|
|
4491
4529
|
}
|
|
4492
4530
|
function hashJson(obj) {
|
|
@@ -4501,27 +4539,27 @@ import { PostHog } from "posthog-node";
|
|
|
4501
4539
|
import chalk6 from "chalk";
|
|
4502
4540
|
|
|
4503
4541
|
// src/telemetry/config.ts
|
|
4504
|
-
import
|
|
4542
|
+
import fs22 from "fs";
|
|
4505
4543
|
import path17 from "path";
|
|
4506
4544
|
import os3 from "os";
|
|
4507
4545
|
import crypto3 from "crypto";
|
|
4508
|
-
import { execSync as
|
|
4546
|
+
import { execSync as execSync9 } from "child_process";
|
|
4509
4547
|
var CONFIG_DIR2 = path17.join(os3.homedir(), ".caliber");
|
|
4510
4548
|
var CONFIG_FILE2 = path17.join(CONFIG_DIR2, "config.json");
|
|
4511
4549
|
var runtimeDisabled = false;
|
|
4512
4550
|
function readConfig() {
|
|
4513
4551
|
try {
|
|
4514
|
-
if (!
|
|
4515
|
-
return JSON.parse(
|
|
4552
|
+
if (!fs22.existsSync(CONFIG_FILE2)) return {};
|
|
4553
|
+
return JSON.parse(fs22.readFileSync(CONFIG_FILE2, "utf-8"));
|
|
4516
4554
|
} catch {
|
|
4517
4555
|
return {};
|
|
4518
4556
|
}
|
|
4519
4557
|
}
|
|
4520
4558
|
function writeConfig(config) {
|
|
4521
|
-
if (!
|
|
4522
|
-
|
|
4559
|
+
if (!fs22.existsSync(CONFIG_DIR2)) {
|
|
4560
|
+
fs22.mkdirSync(CONFIG_DIR2, { recursive: true });
|
|
4523
4561
|
}
|
|
4524
|
-
|
|
4562
|
+
fs22.writeFileSync(CONFIG_FILE2, JSON.stringify(config, null, 2) + "\n", { mode: 384 });
|
|
4525
4563
|
}
|
|
4526
4564
|
function getMachineId() {
|
|
4527
4565
|
const config = readConfig();
|
|
@@ -4532,7 +4570,7 @@ function getMachineId() {
|
|
|
4532
4570
|
}
|
|
4533
4571
|
function getGitEmailHash() {
|
|
4534
4572
|
try {
|
|
4535
|
-
const email =
|
|
4573
|
+
const email = execSync9("git config user.email", { encoding: "utf-8" }).trim();
|
|
4536
4574
|
if (!email) return void 0;
|
|
4537
4575
|
return crypto3.createHash("sha256").update(email).digest("hex");
|
|
4538
4576
|
} catch {
|
|
@@ -5229,6 +5267,93 @@ function printSkills(recs) {
|
|
|
5229
5267
|
console.log("");
|
|
5230
5268
|
}
|
|
5231
5269
|
|
|
5270
|
+
// src/lib/debug-report.ts
|
|
5271
|
+
import fs23 from "fs";
|
|
5272
|
+
import path18 from "path";
|
|
5273
|
+
var DebugReport = class {
|
|
5274
|
+
sections = [];
|
|
5275
|
+
startTime;
|
|
5276
|
+
stepTimings = [];
|
|
5277
|
+
lastStepStart;
|
|
5278
|
+
lastStepName = null;
|
|
5279
|
+
constructor() {
|
|
5280
|
+
this.startTime = Date.now();
|
|
5281
|
+
this.lastStepStart = this.startTime;
|
|
5282
|
+
}
|
|
5283
|
+
markStep(name) {
|
|
5284
|
+
if (this.lastStepName) {
|
|
5285
|
+
this.stepTimings.push({
|
|
5286
|
+
step: this.lastStepName,
|
|
5287
|
+
durationMs: Date.now() - this.lastStepStart
|
|
5288
|
+
});
|
|
5289
|
+
}
|
|
5290
|
+
this.lastStepName = name;
|
|
5291
|
+
this.lastStepStart = Date.now();
|
|
5292
|
+
}
|
|
5293
|
+
addSection(title, content) {
|
|
5294
|
+
this.sections.push({ title, content });
|
|
5295
|
+
}
|
|
5296
|
+
addJson(title, data) {
|
|
5297
|
+
this.sections.push({
|
|
5298
|
+
title,
|
|
5299
|
+
content: "```json\n" + JSON.stringify(data, null, 2) + "\n```"
|
|
5300
|
+
});
|
|
5301
|
+
}
|
|
5302
|
+
addCodeBlock(title, code, lang = "text") {
|
|
5303
|
+
this.sections.push({
|
|
5304
|
+
title,
|
|
5305
|
+
content: "```" + lang + "\n" + code + "\n```"
|
|
5306
|
+
});
|
|
5307
|
+
}
|
|
5308
|
+
write(outputPath) {
|
|
5309
|
+
if (this.lastStepName) {
|
|
5310
|
+
this.stepTimings.push({
|
|
5311
|
+
step: this.lastStepName,
|
|
5312
|
+
durationMs: Date.now() - this.lastStepStart
|
|
5313
|
+
});
|
|
5314
|
+
}
|
|
5315
|
+
const totalMs = Date.now() - this.startTime;
|
|
5316
|
+
const lines = [];
|
|
5317
|
+
lines.push("# Caliber Debug Report");
|
|
5318
|
+
lines.push("");
|
|
5319
|
+
lines.push(`- **Generated**: ${(/* @__PURE__ */ new Date()).toISOString()}`);
|
|
5320
|
+
lines.push(`- **CWD**: ${process.cwd()}`);
|
|
5321
|
+
lines.push(`- **Node**: ${process.version}`);
|
|
5322
|
+
lines.push(`- **Total elapsed**: ${formatMs(totalMs)}`);
|
|
5323
|
+
lines.push("");
|
|
5324
|
+
for (const section of this.sections) {
|
|
5325
|
+
lines.push(`## ${section.title}`);
|
|
5326
|
+
lines.push("");
|
|
5327
|
+
lines.push(section.content);
|
|
5328
|
+
lines.push("");
|
|
5329
|
+
}
|
|
5330
|
+
if (this.stepTimings.length > 0) {
|
|
5331
|
+
lines.push("## Timing");
|
|
5332
|
+
lines.push("");
|
|
5333
|
+
lines.push("| Step | Duration |");
|
|
5334
|
+
lines.push("|------|----------|");
|
|
5335
|
+
for (const t of this.stepTimings) {
|
|
5336
|
+
lines.push(`| ${t.step} | ${formatMs(t.durationMs)} |`);
|
|
5337
|
+
}
|
|
5338
|
+
lines.push(`| **Total** | **${formatMs(totalMs)}** |`);
|
|
5339
|
+
lines.push("");
|
|
5340
|
+
}
|
|
5341
|
+
const dir = path18.dirname(outputPath);
|
|
5342
|
+
if (!fs23.existsSync(dir)) {
|
|
5343
|
+
fs23.mkdirSync(dir, { recursive: true });
|
|
5344
|
+
}
|
|
5345
|
+
fs23.writeFileSync(outputPath, lines.join("\n"));
|
|
5346
|
+
}
|
|
5347
|
+
};
|
|
5348
|
+
function formatMs(ms) {
|
|
5349
|
+
if (ms < 1e3) return `${ms}ms`;
|
|
5350
|
+
const secs = Math.floor(ms / 1e3);
|
|
5351
|
+
const mins = Math.floor(secs / 60);
|
|
5352
|
+
const remSecs = secs % 60;
|
|
5353
|
+
if (mins > 0) return `${mins}m ${remSecs}s`;
|
|
5354
|
+
return `${secs}s`;
|
|
5355
|
+
}
|
|
5356
|
+
|
|
5232
5357
|
// src/commands/onboard.ts
|
|
5233
5358
|
async function initCommand(options) {
|
|
5234
5359
|
const brand = chalk8.hex("#EB9D83");
|
|
@@ -5245,6 +5370,7 @@ async function initCommand(options) {
|
|
|
5245
5370
|
console.log(title.bold(" Welcome to Caliber\n"));
|
|
5246
5371
|
console.log(chalk8.dim(" Caliber analyzes your codebase and creates tailored config files"));
|
|
5247
5372
|
console.log(chalk8.dim(" so your AI coding agents understand your project from day one.\n"));
|
|
5373
|
+
const report = options.debugReport ? new DebugReport() : null;
|
|
5248
5374
|
console.log(title.bold(" How onboarding works:\n"));
|
|
5249
5375
|
console.log(chalk8.dim(" 1. Connect Set up your LLM provider"));
|
|
5250
5376
|
console.log(chalk8.dim(" 2. Discover Analyze your code, dependencies, and structure"));
|
|
@@ -5276,6 +5402,12 @@ async function initCommand(options) {
|
|
|
5276
5402
|
const fastModel = getFastModel();
|
|
5277
5403
|
const modelLine = fastModel ? ` Provider: ${config.provider} | Model: ${displayModel} | Scan: ${fastModel}` : ` Provider: ${config.provider} | Model: ${displayModel}`;
|
|
5278
5404
|
console.log(chalk8.dim(modelLine + "\n"));
|
|
5405
|
+
if (report) {
|
|
5406
|
+
report.markStep("Provider setup");
|
|
5407
|
+
report.addSection("LLM Provider", `- **Provider**: ${config.provider}
|
|
5408
|
+
- **Model**: ${displayModel}
|
|
5409
|
+
- **Fast model**: ${fastModel || "none"}`);
|
|
5410
|
+
}
|
|
5279
5411
|
await validateModel({ fast: true });
|
|
5280
5412
|
console.log(title.bold(" Step 2/6 \u2014 Discover your project\n"));
|
|
5281
5413
|
console.log(chalk8.dim(" Learning about your languages, dependencies, structure, and existing configs.\n"));
|
|
@@ -5286,6 +5418,16 @@ async function initCommand(options) {
|
|
|
5286
5418
|
console.log(chalk8.dim(` Languages: ${fingerprint.languages.join(", ") || "none detected"}`));
|
|
5287
5419
|
console.log(chalk8.dim(` Files: ${fingerprint.fileTree.length} found
|
|
5288
5420
|
`));
|
|
5421
|
+
if (report) {
|
|
5422
|
+
report.markStep("Fingerprint");
|
|
5423
|
+
report.addJson("Fingerprint: Git", { remote: fingerprint.remote, packageName: fingerprint.packageName });
|
|
5424
|
+
report.addCodeBlock("Fingerprint: File Tree", fingerprint.fileTree.join("\n"));
|
|
5425
|
+
report.addJson("Fingerprint: Detected Stack", { languages: fingerprint.languages, frameworks: fingerprint.frameworks, tools: fingerprint.tools });
|
|
5426
|
+
report.addJson("Fingerprint: Existing Configs", fingerprint.existingConfigs);
|
|
5427
|
+
if (fingerprint.codeAnalysis) {
|
|
5428
|
+
report.addJson("Fingerprint: Code Analysis", fingerprint.codeAnalysis);
|
|
5429
|
+
}
|
|
5430
|
+
}
|
|
5289
5431
|
const targetAgent = options.agent || await promptAgent();
|
|
5290
5432
|
trackInitAgentSelected(targetAgent);
|
|
5291
5433
|
const preScore = computeLocalScore(process.cwd(), targetAgent);
|
|
@@ -5303,6 +5445,15 @@ async function initCommand(options) {
|
|
|
5303
5445
|
displayScoreSummary(baselineScore);
|
|
5304
5446
|
const passingCount = baselineScore.checks.filter((c) => c.passed).length;
|
|
5305
5447
|
const failingCount = baselineScore.checks.filter((c) => !c.passed).length;
|
|
5448
|
+
if (report) {
|
|
5449
|
+
report.markStep("Baseline scoring");
|
|
5450
|
+
report.addSection("Scoring: Baseline", `**Score**: ${baselineScore.score}/100
|
|
5451
|
+
|
|
5452
|
+
| Check | Passed | Points | Max |
|
|
5453
|
+
|-------|--------|--------|-----|
|
|
5454
|
+
` + baselineScore.checks.map((c) => `| ${c.name} | ${c.passed ? "Yes" : "No"} | ${c.points} | ${c.maxPoints} |`).join("\n"));
|
|
5455
|
+
report.addSection("Generation: Target Agents", targetAgent.join(", "));
|
|
5456
|
+
}
|
|
5306
5457
|
const hasExistingConfig = !!(fingerprint.existingConfigs.claudeMd || fingerprint.existingConfigs.claudeSettings || fingerprint.existingConfigs.claudeSkills?.length || fingerprint.existingConfigs.cursorrules || fingerprint.existingConfigs.cursorRules?.length || fingerprint.existingConfigs.agentsMd);
|
|
5307
5458
|
const NON_LLM_CHECKS = /* @__PURE__ */ new Set(["hooks_configured", "agents_md_exists", "permissions_configured", "mcp_servers"]);
|
|
5308
5459
|
if (hasExistingConfig && baselineScore.score === 100) {
|
|
@@ -5356,6 +5507,11 @@ async function initCommand(options) {
|
|
|
5356
5507
|
console.log(chalk8.dim(" Creating config files tailored to your project.\n"));
|
|
5357
5508
|
}
|
|
5358
5509
|
console.log(chalk8.dim(" This can take a couple of minutes depending on your model and provider.\n"));
|
|
5510
|
+
if (report) {
|
|
5511
|
+
report.markStep("Generation");
|
|
5512
|
+
const fullPrompt = buildGeneratePrompt(fingerprint, targetAgent, fingerprint.description, failingChecks, currentScore, passingChecks);
|
|
5513
|
+
report.addCodeBlock("Generation: Full LLM Prompt", fullPrompt);
|
|
5514
|
+
}
|
|
5359
5515
|
trackInitGenerationStarted(!!failingChecks);
|
|
5360
5516
|
const genStartTime = Date.now();
|
|
5361
5517
|
const genSpinner = ora2("Generating setup...").start();
|
|
@@ -5403,6 +5559,10 @@ async function initCommand(options) {
|
|
|
5403
5559
|
}
|
|
5404
5560
|
throw new Error("__exit__");
|
|
5405
5561
|
}
|
|
5562
|
+
if (report) {
|
|
5563
|
+
if (rawOutput) report.addCodeBlock("Generation: Raw LLM Response", rawOutput);
|
|
5564
|
+
report.addJson("Generation: Parsed Setup", generatedSetup);
|
|
5565
|
+
}
|
|
5406
5566
|
const elapsedMs = Date.now() - genStartTime;
|
|
5407
5567
|
trackInitGenerationCompleted(elapsedMs, 0);
|
|
5408
5568
|
const mins = Math.floor(elapsedMs / 6e4);
|
|
@@ -5550,6 +5710,14 @@ async function initCommand(options) {
|
|
|
5550
5710
|
console.log(chalk8.dim(" Run ") + chalk8.hex("#83D1EB")("caliber onboard --force") + chalk8.dim(" to override.\n"));
|
|
5551
5711
|
return;
|
|
5552
5712
|
}
|
|
5713
|
+
if (report) {
|
|
5714
|
+
report.markStep("Post-write scoring");
|
|
5715
|
+
report.addSection("Scoring: Post-Write", `**Score**: ${afterScore.score}/100 (delta: ${afterScore.score - baselineScore.score >= 0 ? "+" : ""}${afterScore.score - baselineScore.score})
|
|
5716
|
+
|
|
5717
|
+
| Check | Passed | Points | Max |
|
|
5718
|
+
|-------|--------|--------|-----|
|
|
5719
|
+
` + afterScore.checks.map((c) => `| ${c.name} | ${c.passed ? "Yes" : "No"} | ${c.points} | ${c.maxPoints} |`).join("\n"));
|
|
5720
|
+
}
|
|
5553
5721
|
displayScoreDelta(baselineScore, afterScore);
|
|
5554
5722
|
console.log(title.bold("\n Step 6/6 \u2014 Community skills\n"));
|
|
5555
5723
|
console.log(chalk8.dim(" Search public skill registries for skills that match your tech stack.\n"));
|
|
@@ -5581,6 +5749,13 @@ async function initCommand(options) {
|
|
|
5581
5749
|
console.log(` ${title("caliber skills")} Discover community skills for your stack`);
|
|
5582
5750
|
console.log(` ${title("caliber undo")} Revert all changes from this run`);
|
|
5583
5751
|
console.log("");
|
|
5752
|
+
if (report) {
|
|
5753
|
+
report.markStep("Finished");
|
|
5754
|
+
const reportPath = path19.join(process.cwd(), ".caliber", "debug-report.md");
|
|
5755
|
+
report.write(reportPath);
|
|
5756
|
+
console.log(chalk8.dim(` Debug report written to ${path19.relative(process.cwd(), reportPath)}
|
|
5757
|
+
`));
|
|
5758
|
+
}
|
|
5584
5759
|
}
|
|
5585
5760
|
async function refineLoop(currentSetup, _targetAgent, sessionHistory) {
|
|
5586
5761
|
while (true) {
|
|
@@ -5625,7 +5800,7 @@ async function refineLoop(currentSetup, _targetAgent, sessionHistory) {
|
|
|
5625
5800
|
}
|
|
5626
5801
|
function summarizeSetup(action, setup) {
|
|
5627
5802
|
const descriptions = setup.fileDescriptions;
|
|
5628
|
-
const files = descriptions ? Object.entries(descriptions).map(([
|
|
5803
|
+
const files = descriptions ? Object.entries(descriptions).map(([path26, desc]) => ` ${path26}: ${desc}`).join("\n") : Object.keys(setup).filter((k) => k !== "targetAgent" && k !== "fileDescriptions").join(", ");
|
|
5629
5804
|
return `${action}. Files:
|
|
5630
5805
|
${files}`;
|
|
5631
5806
|
}
|
|
@@ -5738,7 +5913,7 @@ function printSetupSummary(setup) {
|
|
|
5738
5913
|
};
|
|
5739
5914
|
if (claude) {
|
|
5740
5915
|
if (claude.claudeMd) {
|
|
5741
|
-
const icon =
|
|
5916
|
+
const icon = fs24.existsSync("CLAUDE.md") ? chalk8.yellow("~") : chalk8.green("+");
|
|
5742
5917
|
const desc = getDescription("CLAUDE.md");
|
|
5743
5918
|
console.log(` ${icon} ${chalk8.bold("CLAUDE.md")}`);
|
|
5744
5919
|
if (desc) console.log(chalk8.dim(` ${desc}`));
|
|
@@ -5748,7 +5923,7 @@ function printSetupSummary(setup) {
|
|
|
5748
5923
|
if (Array.isArray(skills) && skills.length > 0) {
|
|
5749
5924
|
for (const skill of skills) {
|
|
5750
5925
|
const skillPath = `.claude/skills/${skill.name}/SKILL.md`;
|
|
5751
|
-
const icon =
|
|
5926
|
+
const icon = fs24.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
|
|
5752
5927
|
const desc = getDescription(skillPath);
|
|
5753
5928
|
console.log(` ${icon} ${chalk8.bold(skillPath)}`);
|
|
5754
5929
|
console.log(chalk8.dim(` ${desc || skill.description || skill.name}`));
|
|
@@ -5759,7 +5934,7 @@ function printSetupSummary(setup) {
|
|
|
5759
5934
|
const codex = setup.codex;
|
|
5760
5935
|
if (codex) {
|
|
5761
5936
|
if (codex.agentsMd) {
|
|
5762
|
-
const icon =
|
|
5937
|
+
const icon = fs24.existsSync("AGENTS.md") ? chalk8.yellow("~") : chalk8.green("+");
|
|
5763
5938
|
const desc = getDescription("AGENTS.md");
|
|
5764
5939
|
console.log(` ${icon} ${chalk8.bold("AGENTS.md")}`);
|
|
5765
5940
|
if (desc) console.log(chalk8.dim(` ${desc}`));
|
|
@@ -5769,7 +5944,7 @@ function printSetupSummary(setup) {
|
|
|
5769
5944
|
if (Array.isArray(codexSkills) && codexSkills.length > 0) {
|
|
5770
5945
|
for (const skill of codexSkills) {
|
|
5771
5946
|
const skillPath = `.agents/skills/${skill.name}/SKILL.md`;
|
|
5772
|
-
const icon =
|
|
5947
|
+
const icon = fs24.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
|
|
5773
5948
|
const desc = getDescription(skillPath);
|
|
5774
5949
|
console.log(` ${icon} ${chalk8.bold(skillPath)}`);
|
|
5775
5950
|
console.log(chalk8.dim(` ${desc || skill.description || skill.name}`));
|
|
@@ -5779,7 +5954,7 @@ function printSetupSummary(setup) {
|
|
|
5779
5954
|
}
|
|
5780
5955
|
if (cursor) {
|
|
5781
5956
|
if (cursor.cursorrules) {
|
|
5782
|
-
const icon =
|
|
5957
|
+
const icon = fs24.existsSync(".cursorrules") ? chalk8.yellow("~") : chalk8.green("+");
|
|
5783
5958
|
const desc = getDescription(".cursorrules");
|
|
5784
5959
|
console.log(` ${icon} ${chalk8.bold(".cursorrules")}`);
|
|
5785
5960
|
if (desc) console.log(chalk8.dim(` ${desc}`));
|
|
@@ -5789,7 +5964,7 @@ function printSetupSummary(setup) {
|
|
|
5789
5964
|
if (Array.isArray(cursorSkills) && cursorSkills.length > 0) {
|
|
5790
5965
|
for (const skill of cursorSkills) {
|
|
5791
5966
|
const skillPath = `.cursor/skills/${skill.name}/SKILL.md`;
|
|
5792
|
-
const icon =
|
|
5967
|
+
const icon = fs24.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
|
|
5793
5968
|
const desc = getDescription(skillPath);
|
|
5794
5969
|
console.log(` ${icon} ${chalk8.bold(skillPath)}`);
|
|
5795
5970
|
console.log(chalk8.dim(` ${desc || skill.description || skill.name}`));
|
|
@@ -5800,7 +5975,7 @@ function printSetupSummary(setup) {
|
|
|
5800
5975
|
if (Array.isArray(rules) && rules.length > 0) {
|
|
5801
5976
|
for (const rule of rules) {
|
|
5802
5977
|
const rulePath = `.cursor/rules/${rule.filename}`;
|
|
5803
|
-
const icon =
|
|
5978
|
+
const icon = fs24.existsSync(rulePath) ? chalk8.yellow("~") : chalk8.green("+");
|
|
5804
5979
|
const desc = getDescription(rulePath);
|
|
5805
5980
|
console.log(` ${icon} ${chalk8.bold(rulePath)}`);
|
|
5806
5981
|
if (desc) {
|
|
@@ -5813,7 +5988,7 @@ function printSetupSummary(setup) {
|
|
|
5813
5988
|
}
|
|
5814
5989
|
}
|
|
5815
5990
|
}
|
|
5816
|
-
if (!codex && !
|
|
5991
|
+
if (!codex && !fs24.existsSync("AGENTS.md")) {
|
|
5817
5992
|
console.log(` ${chalk8.green("+")} ${chalk8.bold("AGENTS.md")}`);
|
|
5818
5993
|
console.log(chalk8.dim(" Cross-agent coordination file"));
|
|
5819
5994
|
console.log("");
|
|
@@ -5832,8 +6007,8 @@ function ensurePermissions() {
|
|
|
5832
6007
|
const settingsPath = ".claude/settings.json";
|
|
5833
6008
|
let settings = {};
|
|
5834
6009
|
try {
|
|
5835
|
-
if (
|
|
5836
|
-
settings = JSON.parse(
|
|
6010
|
+
if (fs24.existsSync(settingsPath)) {
|
|
6011
|
+
settings = JSON.parse(fs24.readFileSync(settingsPath, "utf-8"));
|
|
5837
6012
|
}
|
|
5838
6013
|
} catch {
|
|
5839
6014
|
}
|
|
@@ -5847,8 +6022,8 @@ function ensurePermissions() {
|
|
|
5847
6022
|
"Bash(git *)"
|
|
5848
6023
|
];
|
|
5849
6024
|
settings.permissions = permissions;
|
|
5850
|
-
if (!
|
|
5851
|
-
|
|
6025
|
+
if (!fs24.existsSync(".claude")) fs24.mkdirSync(".claude", { recursive: true });
|
|
6026
|
+
fs24.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
5852
6027
|
}
|
|
5853
6028
|
|
|
5854
6029
|
// src/commands/undo.ts
|
|
@@ -5885,7 +6060,7 @@ function undoCommand() {
|
|
|
5885
6060
|
|
|
5886
6061
|
// src/commands/status.ts
|
|
5887
6062
|
import chalk10 from "chalk";
|
|
5888
|
-
import
|
|
6063
|
+
import fs25 from "fs";
|
|
5889
6064
|
init_config();
|
|
5890
6065
|
async function statusCommand(options) {
|
|
5891
6066
|
const config = loadConfig();
|
|
@@ -5912,7 +6087,7 @@ async function statusCommand(options) {
|
|
|
5912
6087
|
}
|
|
5913
6088
|
console.log(` Files managed: ${chalk10.cyan(manifest.entries.length.toString())}`);
|
|
5914
6089
|
for (const entry of manifest.entries) {
|
|
5915
|
-
const exists =
|
|
6090
|
+
const exists = fs25.existsSync(entry.path);
|
|
5916
6091
|
const icon = exists ? chalk10.green("\u2713") : chalk10.red("\u2717");
|
|
5917
6092
|
console.log(` ${icon} ${entry.path} (${entry.action})`);
|
|
5918
6093
|
}
|
|
@@ -6093,13 +6268,13 @@ async function scoreCommand(options) {
|
|
|
6093
6268
|
}
|
|
6094
6269
|
|
|
6095
6270
|
// src/commands/refresh.ts
|
|
6096
|
-
import
|
|
6097
|
-
import
|
|
6271
|
+
import fs27 from "fs";
|
|
6272
|
+
import path21 from "path";
|
|
6098
6273
|
import chalk13 from "chalk";
|
|
6099
6274
|
import ora5 from "ora";
|
|
6100
6275
|
|
|
6101
6276
|
// src/lib/git-diff.ts
|
|
6102
|
-
import { execSync as
|
|
6277
|
+
import { execSync as execSync10 } from "child_process";
|
|
6103
6278
|
var MAX_DIFF_BYTES = 1e5;
|
|
6104
6279
|
var DOC_PATTERNS = [
|
|
6105
6280
|
"CLAUDE.md",
|
|
@@ -6113,7 +6288,7 @@ function excludeArgs() {
|
|
|
6113
6288
|
}
|
|
6114
6289
|
function safeExec(cmd) {
|
|
6115
6290
|
try {
|
|
6116
|
-
return
|
|
6291
|
+
return execSync10(cmd, {
|
|
6117
6292
|
encoding: "utf-8",
|
|
6118
6293
|
stdio: ["pipe", "pipe", "pipe"],
|
|
6119
6294
|
maxBuffer: 10 * 1024 * 1024
|
|
@@ -6171,37 +6346,37 @@ function collectDiff(lastSha) {
|
|
|
6171
6346
|
}
|
|
6172
6347
|
|
|
6173
6348
|
// src/writers/refresh.ts
|
|
6174
|
-
import
|
|
6175
|
-
import
|
|
6349
|
+
import fs26 from "fs";
|
|
6350
|
+
import path20 from "path";
|
|
6176
6351
|
function writeRefreshDocs(docs) {
|
|
6177
6352
|
const written = [];
|
|
6178
6353
|
if (docs.claudeMd) {
|
|
6179
|
-
|
|
6354
|
+
fs26.writeFileSync("CLAUDE.md", docs.claudeMd);
|
|
6180
6355
|
written.push("CLAUDE.md");
|
|
6181
6356
|
}
|
|
6182
6357
|
if (docs.readmeMd) {
|
|
6183
|
-
|
|
6358
|
+
fs26.writeFileSync("README.md", docs.readmeMd);
|
|
6184
6359
|
written.push("README.md");
|
|
6185
6360
|
}
|
|
6186
6361
|
if (docs.cursorrules) {
|
|
6187
|
-
|
|
6362
|
+
fs26.writeFileSync(".cursorrules", docs.cursorrules);
|
|
6188
6363
|
written.push(".cursorrules");
|
|
6189
6364
|
}
|
|
6190
6365
|
if (docs.cursorRules) {
|
|
6191
|
-
const rulesDir =
|
|
6192
|
-
if (!
|
|
6366
|
+
const rulesDir = path20.join(".cursor", "rules");
|
|
6367
|
+
if (!fs26.existsSync(rulesDir)) fs26.mkdirSync(rulesDir, { recursive: true });
|
|
6193
6368
|
for (const rule of docs.cursorRules) {
|
|
6194
|
-
const filePath =
|
|
6195
|
-
|
|
6369
|
+
const filePath = path20.join(rulesDir, rule.filename);
|
|
6370
|
+
fs26.writeFileSync(filePath, rule.content);
|
|
6196
6371
|
written.push(filePath);
|
|
6197
6372
|
}
|
|
6198
6373
|
}
|
|
6199
6374
|
if (docs.claudeSkills) {
|
|
6200
|
-
const skillsDir =
|
|
6201
|
-
if (!
|
|
6375
|
+
const skillsDir = path20.join(".claude", "skills");
|
|
6376
|
+
if (!fs26.existsSync(skillsDir)) fs26.mkdirSync(skillsDir, { recursive: true });
|
|
6202
6377
|
for (const skill of docs.claudeSkills) {
|
|
6203
|
-
const filePath =
|
|
6204
|
-
|
|
6378
|
+
const filePath = path20.join(skillsDir, skill.filename);
|
|
6379
|
+
fs26.writeFileSync(filePath, skill.content);
|
|
6205
6380
|
written.push(filePath);
|
|
6206
6381
|
}
|
|
6207
6382
|
}
|
|
@@ -6280,11 +6455,11 @@ function log(quiet, ...args) {
|
|
|
6280
6455
|
function discoverGitRepos(parentDir) {
|
|
6281
6456
|
const repos = [];
|
|
6282
6457
|
try {
|
|
6283
|
-
const entries =
|
|
6458
|
+
const entries = fs27.readdirSync(parentDir, { withFileTypes: true });
|
|
6284
6459
|
for (const entry of entries) {
|
|
6285
6460
|
if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
|
|
6286
|
-
const childPath =
|
|
6287
|
-
if (
|
|
6461
|
+
const childPath = path21.join(parentDir, entry.name);
|
|
6462
|
+
if (fs27.existsSync(path21.join(childPath, ".git"))) {
|
|
6288
6463
|
repos.push(childPath);
|
|
6289
6464
|
}
|
|
6290
6465
|
}
|
|
@@ -6381,7 +6556,7 @@ async function refreshCommand(options) {
|
|
|
6381
6556
|
`));
|
|
6382
6557
|
const originalDir = process.cwd();
|
|
6383
6558
|
for (const repo of repos) {
|
|
6384
|
-
const repoName =
|
|
6559
|
+
const repoName = path21.basename(repo);
|
|
6385
6560
|
try {
|
|
6386
6561
|
process.chdir(repo);
|
|
6387
6562
|
await refreshSingleRepo(repo, { ...options, label: repoName });
|
|
@@ -6636,8 +6811,8 @@ function readStdin() {
|
|
|
6636
6811
|
|
|
6637
6812
|
// src/learner/storage.ts
|
|
6638
6813
|
init_constants();
|
|
6639
|
-
import
|
|
6640
|
-
import
|
|
6814
|
+
import fs28 from "fs";
|
|
6815
|
+
import path22 from "path";
|
|
6641
6816
|
var MAX_RESPONSE_LENGTH = 2e3;
|
|
6642
6817
|
var DEFAULT_STATE = {
|
|
6643
6818
|
sessionId: null,
|
|
@@ -6645,15 +6820,15 @@ var DEFAULT_STATE = {
|
|
|
6645
6820
|
lastAnalysisTimestamp: null
|
|
6646
6821
|
};
|
|
6647
6822
|
function ensureLearningDir() {
|
|
6648
|
-
if (!
|
|
6649
|
-
|
|
6823
|
+
if (!fs28.existsSync(LEARNING_DIR)) {
|
|
6824
|
+
fs28.mkdirSync(LEARNING_DIR, { recursive: true });
|
|
6650
6825
|
}
|
|
6651
6826
|
}
|
|
6652
6827
|
function sessionFilePath() {
|
|
6653
|
-
return
|
|
6828
|
+
return path22.join(LEARNING_DIR, LEARNING_SESSION_FILE);
|
|
6654
6829
|
}
|
|
6655
6830
|
function stateFilePath() {
|
|
6656
|
-
return
|
|
6831
|
+
return path22.join(LEARNING_DIR, LEARNING_STATE_FILE);
|
|
6657
6832
|
}
|
|
6658
6833
|
function truncateResponse(response) {
|
|
6659
6834
|
const str = JSON.stringify(response);
|
|
@@ -6664,50 +6839,50 @@ function appendEvent(event) {
|
|
|
6664
6839
|
ensureLearningDir();
|
|
6665
6840
|
const truncated = { ...event, tool_response: truncateResponse(event.tool_response) };
|
|
6666
6841
|
const filePath = sessionFilePath();
|
|
6667
|
-
|
|
6842
|
+
fs28.appendFileSync(filePath, JSON.stringify(truncated) + "\n");
|
|
6668
6843
|
const count = getEventCount();
|
|
6669
6844
|
if (count > LEARNING_MAX_EVENTS) {
|
|
6670
|
-
const lines =
|
|
6845
|
+
const lines = fs28.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
|
|
6671
6846
|
const kept = lines.slice(lines.length - LEARNING_MAX_EVENTS);
|
|
6672
|
-
|
|
6847
|
+
fs28.writeFileSync(filePath, kept.join("\n") + "\n");
|
|
6673
6848
|
}
|
|
6674
6849
|
}
|
|
6675
6850
|
function readAllEvents() {
|
|
6676
6851
|
const filePath = sessionFilePath();
|
|
6677
|
-
if (!
|
|
6678
|
-
const lines =
|
|
6852
|
+
if (!fs28.existsSync(filePath)) return [];
|
|
6853
|
+
const lines = fs28.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
|
|
6679
6854
|
return lines.map((line) => JSON.parse(line));
|
|
6680
6855
|
}
|
|
6681
6856
|
function getEventCount() {
|
|
6682
6857
|
const filePath = sessionFilePath();
|
|
6683
|
-
if (!
|
|
6684
|
-
const content =
|
|
6858
|
+
if (!fs28.existsSync(filePath)) return 0;
|
|
6859
|
+
const content = fs28.readFileSync(filePath, "utf-8");
|
|
6685
6860
|
return content.split("\n").filter(Boolean).length;
|
|
6686
6861
|
}
|
|
6687
6862
|
function clearSession() {
|
|
6688
6863
|
const filePath = sessionFilePath();
|
|
6689
|
-
if (
|
|
6864
|
+
if (fs28.existsSync(filePath)) fs28.unlinkSync(filePath);
|
|
6690
6865
|
}
|
|
6691
6866
|
function readState2() {
|
|
6692
6867
|
const filePath = stateFilePath();
|
|
6693
|
-
if (!
|
|
6868
|
+
if (!fs28.existsSync(filePath)) return { ...DEFAULT_STATE };
|
|
6694
6869
|
try {
|
|
6695
|
-
return JSON.parse(
|
|
6870
|
+
return JSON.parse(fs28.readFileSync(filePath, "utf-8"));
|
|
6696
6871
|
} catch {
|
|
6697
6872
|
return { ...DEFAULT_STATE };
|
|
6698
6873
|
}
|
|
6699
6874
|
}
|
|
6700
6875
|
function writeState2(state) {
|
|
6701
6876
|
ensureLearningDir();
|
|
6702
|
-
|
|
6877
|
+
fs28.writeFileSync(stateFilePath(), JSON.stringify(state, null, 2));
|
|
6703
6878
|
}
|
|
6704
6879
|
function resetState() {
|
|
6705
6880
|
writeState2({ ...DEFAULT_STATE });
|
|
6706
6881
|
}
|
|
6707
6882
|
|
|
6708
6883
|
// src/learner/writer.ts
|
|
6709
|
-
import
|
|
6710
|
-
import
|
|
6884
|
+
import fs29 from "fs";
|
|
6885
|
+
import path23 from "path";
|
|
6711
6886
|
var LEARNED_START = "<!-- caliber:learned -->";
|
|
6712
6887
|
var LEARNED_END = "<!-- /caliber:learned -->";
|
|
6713
6888
|
function writeLearnedContent(update) {
|
|
@@ -6727,8 +6902,8 @@ function writeLearnedContent(update) {
|
|
|
6727
6902
|
function writeLearnedSection(content) {
|
|
6728
6903
|
const claudeMdPath = "CLAUDE.md";
|
|
6729
6904
|
let existing = "";
|
|
6730
|
-
if (
|
|
6731
|
-
existing =
|
|
6905
|
+
if (fs29.existsSync(claudeMdPath)) {
|
|
6906
|
+
existing = fs29.readFileSync(claudeMdPath, "utf-8");
|
|
6732
6907
|
}
|
|
6733
6908
|
const section = `${LEARNED_START}
|
|
6734
6909
|
${content}
|
|
@@ -6742,15 +6917,15 @@ ${LEARNED_END}`;
|
|
|
6742
6917
|
const separator = existing.endsWith("\n") || existing === "" ? "" : "\n";
|
|
6743
6918
|
updated = existing + separator + "\n" + section + "\n";
|
|
6744
6919
|
}
|
|
6745
|
-
|
|
6920
|
+
fs29.writeFileSync(claudeMdPath, updated);
|
|
6746
6921
|
}
|
|
6747
6922
|
function writeLearnedSkill(skill) {
|
|
6748
|
-
const skillDir =
|
|
6749
|
-
if (!
|
|
6750
|
-
const skillPath =
|
|
6751
|
-
if (!skill.isNew &&
|
|
6752
|
-
const existing =
|
|
6753
|
-
|
|
6923
|
+
const skillDir = path23.join(".claude", "skills", skill.name);
|
|
6924
|
+
if (!fs29.existsSync(skillDir)) fs29.mkdirSync(skillDir, { recursive: true });
|
|
6925
|
+
const skillPath = path23.join(skillDir, "SKILL.md");
|
|
6926
|
+
if (!skill.isNew && fs29.existsSync(skillPath)) {
|
|
6927
|
+
const existing = fs29.readFileSync(skillPath, "utf-8");
|
|
6928
|
+
fs29.writeFileSync(skillPath, existing.trimEnd() + "\n\n" + skill.content);
|
|
6754
6929
|
} else {
|
|
6755
6930
|
const frontmatter = [
|
|
6756
6931
|
"---",
|
|
@@ -6759,14 +6934,14 @@ function writeLearnedSkill(skill) {
|
|
|
6759
6934
|
"---",
|
|
6760
6935
|
""
|
|
6761
6936
|
].join("\n");
|
|
6762
|
-
|
|
6937
|
+
fs29.writeFileSync(skillPath, frontmatter + skill.content);
|
|
6763
6938
|
}
|
|
6764
6939
|
return skillPath;
|
|
6765
6940
|
}
|
|
6766
6941
|
function readLearnedSection() {
|
|
6767
6942
|
const claudeMdPath = "CLAUDE.md";
|
|
6768
|
-
if (!
|
|
6769
|
-
const content =
|
|
6943
|
+
if (!fs29.existsSync(claudeMdPath)) return null;
|
|
6944
|
+
const content = fs29.readFileSync(claudeMdPath, "utf-8");
|
|
6770
6945
|
const startIdx = content.indexOf(LEARNED_START);
|
|
6771
6946
|
const endIdx = content.indexOf(LEARNED_END);
|
|
6772
6947
|
if (startIdx === -1 || endIdx === -1) return null;
|
|
@@ -6955,9 +7130,9 @@ Learned items in CLAUDE.md: ${chalk16.cyan(String(lineCount))}`);
|
|
|
6955
7130
|
}
|
|
6956
7131
|
|
|
6957
7132
|
// src/cli.ts
|
|
6958
|
-
var __dirname =
|
|
7133
|
+
var __dirname = path24.dirname(fileURLToPath(import.meta.url));
|
|
6959
7134
|
var pkg = JSON.parse(
|
|
6960
|
-
|
|
7135
|
+
fs30.readFileSync(path24.resolve(__dirname, "..", "package.json"), "utf-8")
|
|
6961
7136
|
);
|
|
6962
7137
|
var program = new Command();
|
|
6963
7138
|
var displayVersion = process.env.CALIBER_LOCAL ? `${pkg.version}-local` : pkg.version;
|
|
@@ -7014,7 +7189,7 @@ function parseAgentOption(value) {
|
|
|
7014
7189
|
}
|
|
7015
7190
|
return agents;
|
|
7016
7191
|
}
|
|
7017
|
-
program.command("onboard").alias("init").description("Onboard your project for AI-assisted development").option("--agent <type>", "Target agents (comma-separated): claude, cursor, codex", parseAgentOption).option("--dry-run", "Preview changes without writing files").option("--force", "Overwrite existing setup without prompting").action(tracked("onboard", initCommand));
|
|
7192
|
+
program.command("onboard").alias("init").description("Onboard your project for AI-assisted development").option("--agent <type>", "Target agents (comma-separated): claude, cursor, codex", parseAgentOption).option("--dry-run", "Preview changes without writing files").option("--force", "Overwrite existing setup without prompting").option("--debug-report", void 0, false).action(tracked("onboard", initCommand));
|
|
7018
7193
|
program.command("undo").description("Revert all config changes made by Caliber").action(tracked("undo", undoCommand));
|
|
7019
7194
|
program.command("status").description("Show current Caliber setup status").option("--json", "Output as JSON").action(tracked("status", statusCommand));
|
|
7020
7195
|
program.command("regenerate").alias("regen").alias("re").description("Re-analyze project and regenerate setup").option("--dry-run", "Preview changes without writing files").action(tracked("regenerate", regenerateCommand));
|
|
@@ -7031,22 +7206,22 @@ learn.command("remove").description("Remove learning hooks from .claude/settings
|
|
|
7031
7206
|
learn.command("status").description("Show learning system status").action(tracked("learn:status", learnStatusCommand));
|
|
7032
7207
|
|
|
7033
7208
|
// src/utils/version-check.ts
|
|
7034
|
-
import
|
|
7035
|
-
import
|
|
7209
|
+
import fs31 from "fs";
|
|
7210
|
+
import path25 from "path";
|
|
7036
7211
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
7037
|
-
import { execSync as
|
|
7212
|
+
import { execSync as execSync11 } from "child_process";
|
|
7038
7213
|
import chalk17 from "chalk";
|
|
7039
7214
|
import ora6 from "ora";
|
|
7040
7215
|
import confirm from "@inquirer/confirm";
|
|
7041
|
-
var __dirname_vc =
|
|
7216
|
+
var __dirname_vc = path25.dirname(fileURLToPath2(import.meta.url));
|
|
7042
7217
|
var pkg2 = JSON.parse(
|
|
7043
|
-
|
|
7218
|
+
fs31.readFileSync(path25.resolve(__dirname_vc, "..", "package.json"), "utf-8")
|
|
7044
7219
|
);
|
|
7045
7220
|
function getInstalledVersion() {
|
|
7046
7221
|
try {
|
|
7047
|
-
const globalRoot =
|
|
7048
|
-
const pkgPath =
|
|
7049
|
-
return JSON.parse(
|
|
7222
|
+
const globalRoot = execSync11("npm root -g", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
7223
|
+
const pkgPath = path25.join(globalRoot, "@rely-ai", "caliber", "package.json");
|
|
7224
|
+
return JSON.parse(fs31.readFileSync(pkgPath, "utf-8")).version;
|
|
7050
7225
|
} catch {
|
|
7051
7226
|
return null;
|
|
7052
7227
|
}
|
|
@@ -7089,7 +7264,7 @@ Update available: ${current} -> ${latest}`)
|
|
|
7089
7264
|
}
|
|
7090
7265
|
const spinner = ora6("Updating caliber...").start();
|
|
7091
7266
|
try {
|
|
7092
|
-
|
|
7267
|
+
execSync11(`npm install -g @rely-ai/caliber@${latest}`, {
|
|
7093
7268
|
stdio: "pipe",
|
|
7094
7269
|
timeout: 12e4,
|
|
7095
7270
|
env: { ...process.env, npm_config_fund: "false", npm_config_audit: "false" }
|
|
@@ -7106,7 +7281,7 @@ Update available: ${current} -> ${latest}`)
|
|
|
7106
7281
|
console.log(chalk17.dim(`
|
|
7107
7282
|
Restarting: caliber ${args.join(" ")}
|
|
7108
7283
|
`));
|
|
7109
|
-
|
|
7284
|
+
execSync11(`caliber ${args.map((a) => JSON.stringify(a)).join(" ")}`, {
|
|
7110
7285
|
stdio: "inherit",
|
|
7111
7286
|
env: { ...process.env, CALIBER_SKIP_UPDATE_CHECK: "1" }
|
|
7112
7287
|
});
|
package/package.json
CHANGED