@rely-ai/caliber 1.20.0-dev.1773686790 → 1.20.0-dev.1773690306
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 +244 -26
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -149,13 +149,14 @@ __export(constants_exports, {
|
|
|
149
149
|
CALIBER_DIR: () => CALIBER_DIR,
|
|
150
150
|
LEARNING_DIR: () => LEARNING_DIR,
|
|
151
151
|
LEARNING_MAX_EVENTS: () => LEARNING_MAX_EVENTS,
|
|
152
|
+
LEARNING_ROI_FILE: () => LEARNING_ROI_FILE,
|
|
152
153
|
LEARNING_SESSION_FILE: () => LEARNING_SESSION_FILE,
|
|
153
154
|
LEARNING_STATE_FILE: () => LEARNING_STATE_FILE,
|
|
154
155
|
MANIFEST_FILE: () => MANIFEST_FILE
|
|
155
156
|
});
|
|
156
157
|
import path9 from "path";
|
|
157
158
|
import os2 from "os";
|
|
158
|
-
var AUTH_DIR, CALIBER_DIR, MANIFEST_FILE, BACKUPS_DIR, LEARNING_DIR, LEARNING_SESSION_FILE, LEARNING_STATE_FILE, LEARNING_MAX_EVENTS;
|
|
159
|
+
var AUTH_DIR, CALIBER_DIR, MANIFEST_FILE, BACKUPS_DIR, LEARNING_DIR, LEARNING_SESSION_FILE, LEARNING_STATE_FILE, LEARNING_MAX_EVENTS, LEARNING_ROI_FILE;
|
|
159
160
|
var init_constants = __esm({
|
|
160
161
|
"src/constants.ts"() {
|
|
161
162
|
"use strict";
|
|
@@ -167,6 +168,7 @@ var init_constants = __esm({
|
|
|
167
168
|
LEARNING_SESSION_FILE = "current-session.jsonl";
|
|
168
169
|
LEARNING_STATE_FILE = "state.json";
|
|
169
170
|
LEARNING_MAX_EVENTS = 500;
|
|
171
|
+
LEARNING_ROI_FILE = "roi-stats.json";
|
|
170
172
|
}
|
|
171
173
|
});
|
|
172
174
|
|
|
@@ -219,8 +221,8 @@ var init_lock = __esm({
|
|
|
219
221
|
|
|
220
222
|
// src/cli.ts
|
|
221
223
|
import { Command } from "commander";
|
|
222
|
-
import
|
|
223
|
-
import
|
|
224
|
+
import fs34 from "fs";
|
|
225
|
+
import path27 from "path";
|
|
224
226
|
import { fileURLToPath } from "url";
|
|
225
227
|
|
|
226
228
|
// src/commands/init.ts
|
|
@@ -2240,15 +2242,15 @@ init_config();
|
|
|
2240
2242
|
// src/utils/dependencies.ts
|
|
2241
2243
|
import { readFileSync } from "fs";
|
|
2242
2244
|
import { join } from "path";
|
|
2243
|
-
function readFileOrNull(
|
|
2245
|
+
function readFileOrNull(path29) {
|
|
2244
2246
|
try {
|
|
2245
|
-
return readFileSync(
|
|
2247
|
+
return readFileSync(path29, "utf-8");
|
|
2246
2248
|
} catch {
|
|
2247
2249
|
return null;
|
|
2248
2250
|
}
|
|
2249
2251
|
}
|
|
2250
|
-
function readJsonOrNull(
|
|
2251
|
-
const content = readFileOrNull(
|
|
2252
|
+
function readJsonOrNull(path29) {
|
|
2253
|
+
const content = readFileOrNull(path29);
|
|
2252
2254
|
if (!content) return null;
|
|
2253
2255
|
try {
|
|
2254
2256
|
return JSON.parse(content);
|
|
@@ -5757,6 +5759,36 @@ function trackSkillsInstalled(count) {
|
|
|
5757
5759
|
function trackUndoExecuted() {
|
|
5758
5760
|
trackEvent("undo_executed");
|
|
5759
5761
|
}
|
|
5762
|
+
function trackLearnSessionAnalyzed(props) {
|
|
5763
|
+
trackEvent("learn_session_analyzed", {
|
|
5764
|
+
event_count: props.eventCount,
|
|
5765
|
+
failure_count: props.failureCount,
|
|
5766
|
+
correction_count: props.correctionCount,
|
|
5767
|
+
had_learnings_available: props.hadLearningsAvailable,
|
|
5768
|
+
learnings_available_count: props.learningsAvailableCount,
|
|
5769
|
+
new_learnings_produced: props.newLearningsProduced,
|
|
5770
|
+
waste_tokens: props.wasteTokens
|
|
5771
|
+
});
|
|
5772
|
+
}
|
|
5773
|
+
function trackLearnROISnapshot(props) {
|
|
5774
|
+
trackEvent("learn_roi_snapshot", {
|
|
5775
|
+
total_waste_tokens: props.totalWasteTokens,
|
|
5776
|
+
total_sessions: props.totalSessions,
|
|
5777
|
+
sessions_with_learnings: props.sessionsWithLearnings,
|
|
5778
|
+
sessions_without_learnings: props.sessionsWithoutLearnings,
|
|
5779
|
+
failure_rate_with_learnings: props.failureRateWithLearnings,
|
|
5780
|
+
failure_rate_without_learnings: props.failureRateWithoutLearnings,
|
|
5781
|
+
estimated_savings_tokens: props.estimatedSavingsTokens,
|
|
5782
|
+
learning_count: props.learningCount
|
|
5783
|
+
});
|
|
5784
|
+
}
|
|
5785
|
+
function trackLearnNewLearning(props) {
|
|
5786
|
+
trackEvent("learn_new_learning", {
|
|
5787
|
+
observation_type: props.observationType,
|
|
5788
|
+
waste_tokens: props.wasteTokens,
|
|
5789
|
+
source_event_count: props.sourceEventCount
|
|
5790
|
+
});
|
|
5791
|
+
}
|
|
5760
5792
|
|
|
5761
5793
|
// src/commands/recommend.ts
|
|
5762
5794
|
function detectLocalPlatforms() {
|
|
@@ -7084,7 +7116,7 @@ async function refineLoop(currentSetup, _targetAgent, sessionHistory) {
|
|
|
7084
7116
|
}
|
|
7085
7117
|
function summarizeSetup(action, setup) {
|
|
7086
7118
|
const descriptions = setup.fileDescriptions;
|
|
7087
|
-
const files = descriptions ? Object.entries(descriptions).map(([
|
|
7119
|
+
const files = descriptions ? Object.entries(descriptions).map(([path29, desc]) => ` ${path29}: ${desc}`).join("\n") : Object.keys(setup).filter((k) => k !== "targetAgent" && k !== "fileDescriptions").join(", ");
|
|
7088
7120
|
return `${action}. Files:
|
|
7089
7121
|
${files}`;
|
|
7090
7122
|
}
|
|
@@ -7165,12 +7197,10 @@ async function promptAgent() {
|
|
|
7165
7197
|
async function promptHookType(targetAgent) {
|
|
7166
7198
|
const choices = [];
|
|
7167
7199
|
const hasClaude = targetAgent.includes("claude");
|
|
7200
|
+
choices.push({ name: "Git pre-commit hook \u2014 refresh before each commit (recommended)", value: "precommit" });
|
|
7168
7201
|
if (hasClaude) {
|
|
7169
|
-
choices.push({ name: "Claude Code hook
|
|
7170
|
-
|
|
7171
|
-
choices.push({ name: "Git pre-commit hook (refresh before each commit)", value: "precommit" });
|
|
7172
|
-
if (hasClaude) {
|
|
7173
|
-
choices.push({ name: "Both (Claude Code + pre-commit)", value: "both" });
|
|
7202
|
+
choices.push({ name: "Claude Code hook \u2014 auto-refresh on session end", value: "claude" });
|
|
7203
|
+
choices.push({ name: "Both (pre-commit + Claude Code)", value: "both" });
|
|
7174
7204
|
}
|
|
7175
7205
|
choices.push({ name: "Skip for now", value: "skip" });
|
|
7176
7206
|
return select5({
|
|
@@ -8287,7 +8317,7 @@ async function configCommand() {
|
|
|
8287
8317
|
}
|
|
8288
8318
|
|
|
8289
8319
|
// src/commands/learn.ts
|
|
8290
|
-
import
|
|
8320
|
+
import fs33 from "fs";
|
|
8291
8321
|
import chalk18 from "chalk";
|
|
8292
8322
|
|
|
8293
8323
|
// src/learner/stdin.ts
|
|
@@ -8557,9 +8587,124 @@ ${eventsText}`;
|
|
|
8557
8587
|
});
|
|
8558
8588
|
return parseAnalysisResponse(raw);
|
|
8559
8589
|
}
|
|
8590
|
+
function calculateSessionWaste(events) {
|
|
8591
|
+
let totalWasteTokens = 0;
|
|
8592
|
+
let failureCount = 0;
|
|
8593
|
+
let promptCount = 0;
|
|
8594
|
+
for (const event of events) {
|
|
8595
|
+
if (event.hook_event_name === "PostToolUseFailure") {
|
|
8596
|
+
const te = event;
|
|
8597
|
+
const inputStr = JSON.stringify(te.tool_input);
|
|
8598
|
+
const responseStr = typeof te.tool_response === "object" && "_truncated" in te.tool_response ? String(te.tool_response._truncated) : JSON.stringify(te.tool_response);
|
|
8599
|
+
totalWasteTokens += estimateTokens(inputStr + responseStr);
|
|
8600
|
+
failureCount++;
|
|
8601
|
+
} else if (event.hook_event_name === "UserPromptSubmit") {
|
|
8602
|
+
promptCount++;
|
|
8603
|
+
}
|
|
8604
|
+
}
|
|
8605
|
+
return { totalWasteTokens, failureCount, promptCount };
|
|
8606
|
+
}
|
|
8560
8607
|
|
|
8561
8608
|
// src/commands/learn.ts
|
|
8562
8609
|
init_config();
|
|
8610
|
+
|
|
8611
|
+
// src/learner/roi.ts
|
|
8612
|
+
init_constants();
|
|
8613
|
+
import fs32 from "fs";
|
|
8614
|
+
import path26 from "path";
|
|
8615
|
+
var DEFAULT_TOTALS = {
|
|
8616
|
+
totalWasteTokens: 0,
|
|
8617
|
+
totalSessionsWithLearnings: 0,
|
|
8618
|
+
totalSessionsWithoutLearnings: 0,
|
|
8619
|
+
totalFailuresWithLearnings: 0,
|
|
8620
|
+
totalFailuresWithoutLearnings: 0,
|
|
8621
|
+
estimatedSavingsTokens: 0,
|
|
8622
|
+
firstSessionTimestamp: "",
|
|
8623
|
+
lastSessionTimestamp: ""
|
|
8624
|
+
};
|
|
8625
|
+
function roiFilePath() {
|
|
8626
|
+
return path26.join(LEARNING_DIR, LEARNING_ROI_FILE);
|
|
8627
|
+
}
|
|
8628
|
+
function readROIStats() {
|
|
8629
|
+
const filePath = roiFilePath();
|
|
8630
|
+
if (!fs32.existsSync(filePath)) {
|
|
8631
|
+
return { learnings: [], sessions: [], totals: { ...DEFAULT_TOTALS } };
|
|
8632
|
+
}
|
|
8633
|
+
try {
|
|
8634
|
+
return JSON.parse(fs32.readFileSync(filePath, "utf-8"));
|
|
8635
|
+
} catch {
|
|
8636
|
+
return { learnings: [], sessions: [], totals: { ...DEFAULT_TOTALS } };
|
|
8637
|
+
}
|
|
8638
|
+
}
|
|
8639
|
+
function writeROIStats(stats) {
|
|
8640
|
+
ensureLearningDir();
|
|
8641
|
+
fs32.writeFileSync(roiFilePath(), JSON.stringify(stats, null, 2));
|
|
8642
|
+
}
|
|
8643
|
+
function recalculateTotals(stats) {
|
|
8644
|
+
const totals = stats.totals;
|
|
8645
|
+
totals.totalWasteTokens = stats.learnings.reduce((sum, l) => sum + l.wasteTokens, 0);
|
|
8646
|
+
totals.totalSessionsWithLearnings = 0;
|
|
8647
|
+
totals.totalSessionsWithoutLearnings = 0;
|
|
8648
|
+
totals.totalFailuresWithLearnings = 0;
|
|
8649
|
+
totals.totalFailuresWithoutLearnings = 0;
|
|
8650
|
+
for (const s of stats.sessions) {
|
|
8651
|
+
if (s.hadLearningsAvailable) {
|
|
8652
|
+
totals.totalSessionsWithLearnings++;
|
|
8653
|
+
totals.totalFailuresWithLearnings += s.failureCount;
|
|
8654
|
+
} else {
|
|
8655
|
+
totals.totalSessionsWithoutLearnings++;
|
|
8656
|
+
totals.totalFailuresWithoutLearnings += s.failureCount;
|
|
8657
|
+
}
|
|
8658
|
+
}
|
|
8659
|
+
totals.estimatedSavingsTokens = totals.totalWasteTokens * totals.totalSessionsWithLearnings;
|
|
8660
|
+
if (stats.sessions.length > 0) {
|
|
8661
|
+
totals.firstSessionTimestamp = stats.sessions[0].timestamp;
|
|
8662
|
+
totals.lastSessionTimestamp = stats.sessions[stats.sessions.length - 1].timestamp;
|
|
8663
|
+
}
|
|
8664
|
+
}
|
|
8665
|
+
var MAX_SESSIONS = 500;
|
|
8666
|
+
var MAX_LEARNINGS = 1e3;
|
|
8667
|
+
function recordSession(summary, learnings) {
|
|
8668
|
+
const stats = readROIStats();
|
|
8669
|
+
stats.sessions.push(summary);
|
|
8670
|
+
if (learnings?.length) {
|
|
8671
|
+
stats.learnings.push(...learnings);
|
|
8672
|
+
}
|
|
8673
|
+
if (stats.sessions.length > MAX_SESSIONS) {
|
|
8674
|
+
stats.sessions = stats.sessions.slice(-MAX_SESSIONS);
|
|
8675
|
+
}
|
|
8676
|
+
if (stats.learnings.length > MAX_LEARNINGS) {
|
|
8677
|
+
stats.learnings = stats.learnings.slice(-MAX_LEARNINGS);
|
|
8678
|
+
}
|
|
8679
|
+
recalculateTotals(stats);
|
|
8680
|
+
writeROIStats(stats);
|
|
8681
|
+
return stats;
|
|
8682
|
+
}
|
|
8683
|
+
function formatROISummary(stats) {
|
|
8684
|
+
const t = stats.totals;
|
|
8685
|
+
const totalSessions = t.totalSessionsWithLearnings + t.totalSessionsWithoutLearnings;
|
|
8686
|
+
if (totalSessions === 0) return "";
|
|
8687
|
+
const lines = ["ROI Summary"];
|
|
8688
|
+
lines.push(` Sessions tracked: ${totalSessions}`);
|
|
8689
|
+
lines.push(` Sessions with learnings: ${t.totalSessionsWithLearnings}`);
|
|
8690
|
+
if (t.totalSessionsWithoutLearnings > 0) {
|
|
8691
|
+
const rateWithout = t.totalSessionsWithoutLearnings > 0 ? (t.totalFailuresWithoutLearnings / t.totalSessionsWithoutLearnings).toFixed(1) : "0.0";
|
|
8692
|
+
lines.push(` Failure rate (no learnings): ${rateWithout}/session`);
|
|
8693
|
+
}
|
|
8694
|
+
if (t.totalSessionsWithLearnings > 0) {
|
|
8695
|
+
const rateWith = (t.totalFailuresWithLearnings / t.totalSessionsWithLearnings).toFixed(1);
|
|
8696
|
+
lines.push(` Failure rate (with learnings): ${rateWith}/session`);
|
|
8697
|
+
}
|
|
8698
|
+
if (t.totalWasteTokens > 0) {
|
|
8699
|
+
lines.push(` Total waste captured: ${t.totalWasteTokens.toLocaleString()} tokens`);
|
|
8700
|
+
}
|
|
8701
|
+
if (t.estimatedSavingsTokens > 0) {
|
|
8702
|
+
lines.push(` Estimated savings: ~${t.estimatedSavingsTokens.toLocaleString()} tokens`);
|
|
8703
|
+
}
|
|
8704
|
+
return lines.join("\n");
|
|
8705
|
+
}
|
|
8706
|
+
|
|
8707
|
+
// src/commands/learn.ts
|
|
8563
8708
|
var MIN_EVENTS_FOR_ANALYSIS = 25;
|
|
8564
8709
|
async function learnObserveCommand(options) {
|
|
8565
8710
|
try {
|
|
@@ -8638,18 +8783,82 @@ async function learnFinalizeCommand(options) {
|
|
|
8638
8783
|
existingSkills
|
|
8639
8784
|
);
|
|
8640
8785
|
analyzed = true;
|
|
8786
|
+
const waste = calculateSessionWaste(events);
|
|
8787
|
+
const existingLearnedItems = existingLearnedSection ? existingLearnedSection.split("\n").filter((l) => l.startsWith("- ")).length : 0;
|
|
8788
|
+
const hadLearnings = existingLearnedItems > 0;
|
|
8789
|
+
let newLearningsProduced = 0;
|
|
8790
|
+
let roiLearningEntries = [];
|
|
8641
8791
|
if (response.claudeMdLearnedSection || response.skills?.length) {
|
|
8642
8792
|
const result = writeLearnedContent({
|
|
8643
8793
|
claudeMdLearnedSection: response.claudeMdLearnedSection,
|
|
8644
8794
|
skills: response.skills
|
|
8645
8795
|
});
|
|
8796
|
+
newLearningsProduced = result.newItemCount;
|
|
8646
8797
|
if (result.newItemCount > 0) {
|
|
8647
|
-
|
|
8798
|
+
const wasteLabel = waste.totalWasteTokens > 0 ? ` (~${waste.totalWasteTokens.toLocaleString()} wasted tokens captured)` : "";
|
|
8799
|
+
console.log(chalk18.dim(`caliber: learned ${result.newItemCount} new pattern${result.newItemCount === 1 ? "" : "s"}${wasteLabel}`));
|
|
8648
8800
|
for (const item of result.newItems) {
|
|
8649
8801
|
console.log(chalk18.dim(` + ${item.replace(/^- /, "").slice(0, 80)}`));
|
|
8650
8802
|
}
|
|
8803
|
+
const wastePerLearning = Math.round(waste.totalWasteTokens / result.newItemCount);
|
|
8804
|
+
const TYPE_RE = /^\*\*\[([^\]]+)\]\*\*/;
|
|
8805
|
+
const learningEntries = result.newItems.map((item) => {
|
|
8806
|
+
const clean = item.replace(/^- /, "");
|
|
8807
|
+
const typeMatch = clean.match(TYPE_RE);
|
|
8808
|
+
return {
|
|
8809
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8810
|
+
observationType: typeMatch ? typeMatch[1] : "unknown",
|
|
8811
|
+
summary: clean.replace(TYPE_RE, "").trim().slice(0, 80),
|
|
8812
|
+
wasteTokens: wastePerLearning,
|
|
8813
|
+
sourceEventCount: events.length
|
|
8814
|
+
};
|
|
8815
|
+
});
|
|
8816
|
+
for (const entry of learningEntries) {
|
|
8817
|
+
trackLearnNewLearning({
|
|
8818
|
+
observationType: entry.observationType,
|
|
8819
|
+
wasteTokens: entry.wasteTokens,
|
|
8820
|
+
sourceEventCount: entry.sourceEventCount
|
|
8821
|
+
});
|
|
8822
|
+
}
|
|
8823
|
+
roiLearningEntries = learningEntries;
|
|
8651
8824
|
}
|
|
8652
8825
|
}
|
|
8826
|
+
const sessionSummary = {
|
|
8827
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8828
|
+
sessionId: readState2().sessionId || "unknown",
|
|
8829
|
+
eventCount: events.length,
|
|
8830
|
+
failureCount: waste.failureCount,
|
|
8831
|
+
promptCount: waste.promptCount,
|
|
8832
|
+
hadLearningsAvailable: hadLearnings,
|
|
8833
|
+
learningsCount: existingLearnedItems,
|
|
8834
|
+
newLearningsProduced
|
|
8835
|
+
};
|
|
8836
|
+
const roiStats = recordSession(sessionSummary, roiLearningEntries);
|
|
8837
|
+
trackLearnSessionAnalyzed({
|
|
8838
|
+
eventCount: events.length,
|
|
8839
|
+
failureCount: waste.failureCount,
|
|
8840
|
+
correctionCount: waste.promptCount,
|
|
8841
|
+
hadLearningsAvailable: hadLearnings,
|
|
8842
|
+
learningsAvailableCount: existingLearnedItems,
|
|
8843
|
+
newLearningsProduced,
|
|
8844
|
+
wasteTokens: waste.totalWasteTokens
|
|
8845
|
+
});
|
|
8846
|
+
const t = roiStats.totals;
|
|
8847
|
+
const totalSessions = t.totalSessionsWithLearnings + t.totalSessionsWithoutLearnings;
|
|
8848
|
+
trackLearnROISnapshot({
|
|
8849
|
+
totalWasteTokens: t.totalWasteTokens,
|
|
8850
|
+
totalSessions,
|
|
8851
|
+
sessionsWithLearnings: t.totalSessionsWithLearnings,
|
|
8852
|
+
sessionsWithoutLearnings: t.totalSessionsWithoutLearnings,
|
|
8853
|
+
failureRateWithLearnings: t.totalSessionsWithLearnings > 0 ? t.totalFailuresWithLearnings / t.totalSessionsWithLearnings : 0,
|
|
8854
|
+
failureRateWithoutLearnings: t.totalSessionsWithoutLearnings > 0 ? t.totalFailuresWithoutLearnings / t.totalSessionsWithoutLearnings : 0,
|
|
8855
|
+
estimatedSavingsTokens: t.estimatedSavingsTokens,
|
|
8856
|
+
learningCount: roiStats.learnings.length
|
|
8857
|
+
});
|
|
8858
|
+
if (t.estimatedSavingsTokens > 0) {
|
|
8859
|
+
const totalLearnings = existingLearnedItems + newLearningsProduced;
|
|
8860
|
+
console.log(chalk18.dim(`caliber: ${totalLearnings} learnings active \u2014 est. ~${t.estimatedSavingsTokens.toLocaleString()} tokens saved across ${t.totalSessionsWithLearnings} sessions`));
|
|
8861
|
+
}
|
|
8653
8862
|
} catch (err) {
|
|
8654
8863
|
if (options?.force) {
|
|
8655
8864
|
console.error(chalk18.red("caliber: finalize failed \u2014"), err instanceof Error ? err.message : err);
|
|
@@ -8664,7 +8873,7 @@ async function learnFinalizeCommand(options) {
|
|
|
8664
8873
|
}
|
|
8665
8874
|
async function learnInstallCommand() {
|
|
8666
8875
|
let anyInstalled = false;
|
|
8667
|
-
if (
|
|
8876
|
+
if (fs33.existsSync(".claude")) {
|
|
8668
8877
|
const r = installLearningHooks();
|
|
8669
8878
|
if (r.installed) {
|
|
8670
8879
|
console.log(chalk18.green("\u2713") + " Claude Code learning hooks installed");
|
|
@@ -8673,7 +8882,7 @@ async function learnInstallCommand() {
|
|
|
8673
8882
|
console.log(chalk18.dim(" Claude Code hooks already installed"));
|
|
8674
8883
|
}
|
|
8675
8884
|
}
|
|
8676
|
-
if (
|
|
8885
|
+
if (fs33.existsSync(".cursor")) {
|
|
8677
8886
|
const r = installCursorLearningHooks();
|
|
8678
8887
|
if (r.installed) {
|
|
8679
8888
|
console.log(chalk18.green("\u2713") + " Cursor learning hooks installed");
|
|
@@ -8682,7 +8891,7 @@ async function learnInstallCommand() {
|
|
|
8682
8891
|
console.log(chalk18.dim(" Cursor hooks already installed"));
|
|
8683
8892
|
}
|
|
8684
8893
|
}
|
|
8685
|
-
if (!
|
|
8894
|
+
if (!fs33.existsSync(".claude") && !fs33.existsSync(".cursor")) {
|
|
8686
8895
|
console.log(chalk18.yellow("No .claude/ or .cursor/ directory found."));
|
|
8687
8896
|
console.log(chalk18.dim(" Run `caliber init` first, or create the directory manually."));
|
|
8688
8897
|
return;
|
|
@@ -8742,12 +8951,21 @@ async function learnStatusCommand() {
|
|
|
8742
8951
|
console.log(`
|
|
8743
8952
|
Learned items in CALIBER_LEARNINGS.md: ${chalk18.cyan(String(lineCount))}`);
|
|
8744
8953
|
}
|
|
8954
|
+
const roiStats = readROIStats();
|
|
8955
|
+
const roiSummary = formatROISummary(roiStats);
|
|
8956
|
+
if (roiSummary) {
|
|
8957
|
+
console.log();
|
|
8958
|
+
console.log(chalk18.bold(roiSummary.split("\n")[0]));
|
|
8959
|
+
for (const line of roiSummary.split("\n").slice(1)) {
|
|
8960
|
+
console.log(line);
|
|
8961
|
+
}
|
|
8962
|
+
}
|
|
8745
8963
|
}
|
|
8746
8964
|
|
|
8747
8965
|
// src/cli.ts
|
|
8748
|
-
var __dirname =
|
|
8966
|
+
var __dirname = path27.dirname(fileURLToPath(import.meta.url));
|
|
8749
8967
|
var pkg = JSON.parse(
|
|
8750
|
-
|
|
8968
|
+
fs34.readFileSync(path27.resolve(__dirname, "..", "package.json"), "utf-8")
|
|
8751
8969
|
);
|
|
8752
8970
|
var program = new Command();
|
|
8753
8971
|
var displayVersion = process.env.CALIBER_LOCAL ? `${pkg.version}-local` : pkg.version;
|
|
@@ -8821,16 +9039,16 @@ learn.command("remove").description("Remove learning hooks from .claude/settings
|
|
|
8821
9039
|
learn.command("status").description("Show learning system status").action(tracked("learn:status", learnStatusCommand));
|
|
8822
9040
|
|
|
8823
9041
|
// src/utils/version-check.ts
|
|
8824
|
-
import
|
|
8825
|
-
import
|
|
9042
|
+
import fs35 from "fs";
|
|
9043
|
+
import path28 from "path";
|
|
8826
9044
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
8827
9045
|
import { execSync as execSync14 } from "child_process";
|
|
8828
9046
|
import chalk19 from "chalk";
|
|
8829
9047
|
import ora6 from "ora";
|
|
8830
9048
|
import confirm2 from "@inquirer/confirm";
|
|
8831
|
-
var __dirname_vc =
|
|
9049
|
+
var __dirname_vc = path28.dirname(fileURLToPath2(import.meta.url));
|
|
8832
9050
|
var pkg2 = JSON.parse(
|
|
8833
|
-
|
|
9051
|
+
fs35.readFileSync(path28.resolve(__dirname_vc, "..", "package.json"), "utf-8")
|
|
8834
9052
|
);
|
|
8835
9053
|
function getChannel(version) {
|
|
8836
9054
|
const match = version.match(/-(dev|next)\./);
|
|
@@ -8855,8 +9073,8 @@ function isNewer(registry, current) {
|
|
|
8855
9073
|
function getInstalledVersion() {
|
|
8856
9074
|
try {
|
|
8857
9075
|
const globalRoot = execSync14("npm root -g", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
8858
|
-
const pkgPath =
|
|
8859
|
-
return JSON.parse(
|
|
9076
|
+
const pkgPath = path28.join(globalRoot, "@rely-ai", "caliber", "package.json");
|
|
9077
|
+
return JSON.parse(fs35.readFileSync(pkgPath, "utf-8")).version;
|
|
8860
9078
|
} catch {
|
|
8861
9079
|
return null;
|
|
8862
9080
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rely-ai/caliber",
|
|
3
|
-
"version": "1.20.0-dev.
|
|
3
|
+
"version": "1.20.0-dev.1773690306",
|
|
4
4
|
"description": "Analyze your codebase and generate optimized AI agent configs (CLAUDE.md, .cursorrules, skills) — no API key needed",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|