@rely-ai/caliber 1.40.1 → 1.40.3

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.
Files changed (2) hide show
  1. package/dist/bin.js +77 -8
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -2363,7 +2363,7 @@ import os3 from "os";
2363
2363
  // src/llm/seat-based-errors.ts
2364
2364
  init_resolve_caliber();
2365
2365
  var ERROR_PATTERNS = [
2366
- { pattern: /not logged in|not authenticated|login required|unauthorized/i, message: "Authentication required. Run the login command for your provider to re-authenticate." },
2366
+ { pattern: /not logged in|not authenticated|login required|unauthorized/i, message: "Not logged in. Run the login command for your provider to re-authenticate." },
2367
2367
  { pattern: /rate limit|too many requests|429/i, message: "Rate limit exceeded. Retrying..." },
2368
2368
  { pattern: /usage limit|out of usage|budget.*limit|limit.*reached/i, message: () => `Usage limit reached. Run \`${resolveCaliber()} config\` to switch models (e.g. auto or composer-1.5).` },
2369
2369
  { pattern: /model.*not found|invalid model|model.*unavailable/i, message: () => `The requested model is not available. Run \`${resolveCaliber()} config\` to select a different model.` }
@@ -2886,6 +2886,26 @@ function isClaudeCliAvailable() {
2886
2886
  return false;
2887
2887
  }
2888
2888
  }
2889
+ var cachedLoggedIn = null;
2890
+ function isClaudeCliLoggedIn() {
2891
+ if (cachedLoggedIn !== null) return cachedLoggedIn;
2892
+ try {
2893
+ const result = execSync6(`${CLAUDE_CLI_BIN} auth status`, {
2894
+ stdio: ["ignore", "pipe", "pipe"],
2895
+ timeout: 5e3
2896
+ });
2897
+ const output = result.toString().trim();
2898
+ try {
2899
+ const status = JSON.parse(output);
2900
+ cachedLoggedIn = status.loggedIn === true;
2901
+ } catch {
2902
+ cachedLoggedIn = !output.toLowerCase().includes("not logged in");
2903
+ }
2904
+ } catch {
2905
+ cachedLoggedIn = false;
2906
+ }
2907
+ return cachedLoggedIn;
2908
+ }
2889
2909
 
2890
2910
  // src/llm/model-recovery.ts
2891
2911
  init_config();
@@ -3017,6 +3037,11 @@ function createProvider(config) {
3017
3037
  "Cursor provider requires the Cursor Agent CLI. Install it from https://cursor.com/install then run `agent login`. Alternatively set ANTHROPIC_API_KEY or another provider."
3018
3038
  );
3019
3039
  }
3040
+ if (!isCursorLoggedIn()) {
3041
+ throw new Error(
3042
+ "Cursor Agent CLI is installed but not logged in. Run `agent login` in your terminal to authenticate, then retry."
3043
+ );
3044
+ }
3020
3045
  return new CursorAcpProvider(config);
3021
3046
  }
3022
3047
  case "claude-cli": {
@@ -3025,6 +3050,11 @@ function createProvider(config) {
3025
3050
  "Claude Code provider requires the Claude Code CLI. Install it from https://claude.ai/install (or run `claude` once and log in). Alternatively set ANTHROPIC_API_KEY or choose another provider."
3026
3051
  );
3027
3052
  }
3053
+ if (!isClaudeCliLoggedIn()) {
3054
+ throw new Error(
3055
+ "Claude Code CLI is installed but not logged in. Run `claude` in your terminal to log in, then retry."
3056
+ );
3057
+ }
3028
3058
  return new ClaudeCliProvider(config);
3029
3059
  }
3030
3060
  default:
@@ -3535,6 +3565,8 @@ You receive a chronological sequence of events from a Claude Code session. Most
3535
3565
 
3536
3566
  Your job is to find OPERATIONAL patterns \u2014 things that went wrong and how they were fixed, commands that required specific flags or configuration, APIs that needed a particular approach to work. Focus on the WORKFLOW, not the code logic.
3537
3567
 
3568
+ IMPORTANT CONTEXT: Your output will be committed to git and shared with all developers and AI agents working on this repo. Only include patterns that will genuinely help future work \u2014 not descriptions of bugs that were already fixed in this session, not local environment issues, and not implementation details of what was built.
3569
+
3538
3570
  CRITICAL FILTER \u2014 apply this to every potential learning before including it:
3539
3571
  The litmus test: "Would a different developer, working on a DIFFERENT task in this same repo next week, benefit from knowing this?" If the answer is no \u2014 if it only matters for the exact problem being debugged today \u2014 do NOT include it.
3540
3572
 
@@ -3543,7 +3575,7 @@ DO NOT extract:
3543
3575
  - General programming best practices everyone already knows
3544
3576
  - Summaries of successful routine operations that need no special handling
3545
3577
  - Anything already covered in the existing CLAUDE.md
3546
- - **One-time debugging artifacts** \u2014 fixes for a specific bug that was resolved in this session and won't recur (e.g. "fixed the stream parser by adding a null check at line 42"). Only extract if the pattern will help future sessions avoid the same trap.
3578
+ - **One-time debugging artifacts** \u2014 fixes for a specific bug that was resolved in this session and won't recur (e.g. "fixed the stream parser by adding a null check at line 42"). The fix is in the code and git history \u2014 don't duplicate it as a learning. Only extract if the pattern reveals a recurring trap that future sessions could fall into.
3547
3579
  - **Session-specific file paths, worktree locations, or branch names** \u2014 these are ephemeral and won't apply to future sessions
3548
3580
  - **Implementation details of a feature being built** \u2014 the learning should be about HOW to work in this project, not WHAT was built
3549
3581
 
@@ -6302,6 +6334,11 @@ async function runInteractiveProviderSetup(options) {
6302
6334
  console.log(chalk3.dim(" Then run ") + chalk3.hex("#83D1EB")("claude") + chalk3.dim(" once to log in.\n"));
6303
6335
  const proceed = await confirm({ message: "Continue anyway?" });
6304
6336
  if (!proceed) throw new Error("__exit__");
6337
+ } else if (!isClaudeCliLoggedIn()) {
6338
+ console.log(chalk3.yellow("\n Claude Code CLI found but not logged in."));
6339
+ console.log(chalk3.dim(" Run ") + chalk3.hex("#83D1EB")("claude") + chalk3.dim(" once to log in.\n"));
6340
+ const proceed = await confirm({ message: "Continue anyway?" });
6341
+ if (!proceed) throw new Error("__exit__");
6305
6342
  } else {
6306
6343
  console.log(chalk3.dim(" Run `claude` once and log in with your Pro/Max/Team account if you haven't."));
6307
6344
  }
@@ -10155,7 +10192,7 @@ async function initCommand(options) {
10155
10192
  console.log(title.bold(" Step 1/3 \u2014 Connect\n"));
10156
10193
  let config = loadConfig();
10157
10194
  if (!config && !options.autoApprove) {
10158
- if (isClaudeCliAvailable()) {
10195
+ if (isClaudeCliAvailable() && isClaudeCliLoggedIn()) {
10159
10196
  console.log(chalk14.dim(" Detected: Claude Code CLI (uses your Pro/Max/Team subscription)\n"));
10160
10197
  const useIt = await confirm2({ message: "Use Claude Code as your LLM provider?" });
10161
10198
  if (useIt) {
@@ -10175,7 +10212,7 @@ async function initCommand(options) {
10175
10212
  }
10176
10213
  if (!config) {
10177
10214
  if (options.autoApprove) {
10178
- if (isClaudeCliAvailable()) {
10215
+ if (isClaudeCliAvailable() && isClaudeCliLoggedIn()) {
10179
10216
  const autoConfig = { provider: "claude-cli", model: "default" };
10180
10217
  writeConfigFile(autoConfig);
10181
10218
  config = autoConfig;
@@ -12437,6 +12474,8 @@ function readStdin() {
12437
12474
  import fs43 from "fs";
12438
12475
  import path35 from "path";
12439
12476
  var MAX_RESPONSE_LENGTH = 2e3;
12477
+ var MAX_PROMPT_LENGTH = 2e3;
12478
+ var MAX_SESSION_FILE_BYTES = 10 * 1024 * 1024;
12440
12479
  var DEFAULT_STATE = {
12441
12480
  sessionId: null,
12442
12481
  eventCount: 0,
@@ -12460,6 +12499,15 @@ function truncateResponse(response) {
12460
12499
  return { _truncated: str.slice(0, MAX_RESPONSE_LENGTH) };
12461
12500
  }
12462
12501
  function trimSessionFileIfNeeded(filePath) {
12502
+ try {
12503
+ const stat = fs43.statSync(filePath);
12504
+ if (stat.size > MAX_SESSION_FILE_BYTES) {
12505
+ fs43.writeFileSync(filePath, "");
12506
+ return;
12507
+ }
12508
+ } catch {
12509
+ return;
12510
+ }
12463
12511
  const state = readState2();
12464
12512
  if (state.eventCount + 1 > LEARNING_MAX_EVENTS) {
12465
12513
  const lines = fs43.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
@@ -12478,13 +12526,25 @@ function appendEvent(event) {
12478
12526
  }
12479
12527
  function appendPromptEvent(event) {
12480
12528
  ensureLearningDir();
12529
+ const truncated = {
12530
+ ...event,
12531
+ prompt_content: event.prompt_content.length > MAX_PROMPT_LENGTH ? event.prompt_content.slice(0, MAX_PROMPT_LENGTH) : event.prompt_content
12532
+ };
12481
12533
  const filePath = sessionFilePath();
12482
- fs43.appendFileSync(filePath, JSON.stringify(event) + "\n");
12534
+ fs43.appendFileSync(filePath, JSON.stringify(truncated) + "\n");
12483
12535
  trimSessionFileIfNeeded(filePath);
12484
12536
  }
12485
12537
  function readAllEvents() {
12486
12538
  const filePath = sessionFilePath();
12487
- if (!fs43.existsSync(filePath)) return [];
12539
+ try {
12540
+ const stat = fs43.statSync(filePath);
12541
+ if (stat.size > MAX_SESSION_FILE_BYTES) {
12542
+ fs43.writeFileSync(filePath, "");
12543
+ return [];
12544
+ }
12545
+ } catch {
12546
+ return [];
12547
+ }
12488
12548
  const lines = fs43.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
12489
12549
  const events = [];
12490
12550
  for (const line of lines) {
@@ -12497,7 +12557,12 @@ function readAllEvents() {
12497
12557
  }
12498
12558
  function getEventCount() {
12499
12559
  const filePath = sessionFilePath();
12500
- if (!fs43.existsSync(filePath)) return 0;
12560
+ try {
12561
+ const stat = fs43.statSync(filePath);
12562
+ if (stat.size > MAX_SESSION_FILE_BYTES) return 0;
12563
+ } catch {
12564
+ return 0;
12565
+ }
12501
12566
  const content = fs43.readFileSync(filePath, "utf-8");
12502
12567
  return content.split("\n").filter(Boolean).length;
12503
12568
  }
@@ -13025,11 +13090,15 @@ async function learnObserveCommand(options) {
13025
13090
  const hookData = JSON.parse(raw);
13026
13091
  const sessionId = hookData.session_id || hookData.conversation_id || "unknown";
13027
13092
  if (options.prompt) {
13093
+ const content = String(hookData.prompt_content || hookData.content || hookData.prompt || "");
13094
+ if (/^You are an expert\b/i.test(content)) {
13095
+ return;
13096
+ }
13028
13097
  const event2 = {
13029
13098
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
13030
13099
  session_id: sessionId,
13031
13100
  hook_event_name: "UserPromptSubmit",
13032
- prompt_content: sanitizeSecrets(String(hookData.prompt_content || hookData.content || hookData.prompt || "")),
13101
+ prompt_content: sanitizeSecrets(content),
13033
13102
  cwd: hookData.cwd || process.cwd()
13034
13103
  };
13035
13104
  appendPromptEvent(event2);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rely-ai/caliber",
3
- "version": "1.40.1",
3
+ "version": "1.40.3",
4
4
  "description": "AI context infrastructure for coding agents — keeps CLAUDE.md, Cursor rules, and skills in sync as your codebase evolves",
5
5
  "type": "module",
6
6
  "bin": {