@rely-ai/caliber 0.4.1 → 0.4.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 +59 -15
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -997,7 +997,7 @@ function isCursorAgentAvailable() {
997
997
  // src/llm/claude-cli.ts
998
998
  import { spawn as spawn2, execSync as execSync3 } from "child_process";
999
999
  var CLAUDE_CLI_BIN = "claude";
1000
- var DEFAULT_TIMEOUT_MS = 5 * 60 * 1e3;
1000
+ var DEFAULT_TIMEOUT_MS = 10 * 60 * 1e3;
1001
1001
  var ClaudeCliProvider = class {
1002
1002
  defaultModel;
1003
1003
  timeoutMs;
@@ -1014,13 +1014,48 @@ var ClaudeCliProvider = class {
1014
1014
  return this.runClaudePrint(combined);
1015
1015
  }
1016
1016
  async stream(options, callbacks) {
1017
- try {
1018
- const text = await this.call(options);
1019
- if (text) callbacks.onText(text);
1020
- callbacks.onEnd({ stopReason: "end_turn" });
1021
- } catch (err) {
1022
- callbacks.onError(err instanceof Error ? err : new Error(String(err)));
1023
- }
1017
+ const combined = this.buildCombinedPrompt(options);
1018
+ const child = spawn2(CLAUDE_CLI_BIN, ["-p", combined], {
1019
+ cwd: process.cwd(),
1020
+ stdio: ["ignore", "pipe", "inherit"],
1021
+ env: process.env
1022
+ });
1023
+ let settled = false;
1024
+ const chunks = [];
1025
+ child.stdout.on("data", (chunk) => {
1026
+ chunks.push(chunk);
1027
+ callbacks.onText(chunk.toString("utf-8"));
1028
+ });
1029
+ const timer = setTimeout(() => {
1030
+ child.kill("SIGTERM");
1031
+ if (!settled) {
1032
+ settled = true;
1033
+ callbacks.onError(
1034
+ new Error(
1035
+ `Claude CLI timed out after ${this.timeoutMs / 1e3}s. Set CALIBER_CLAUDE_CLI_TIMEOUT_MS to increase.`
1036
+ )
1037
+ );
1038
+ }
1039
+ }, this.timeoutMs);
1040
+ child.on("error", (err) => {
1041
+ clearTimeout(timer);
1042
+ if (!settled) {
1043
+ settled = true;
1044
+ callbacks.onError(err);
1045
+ }
1046
+ });
1047
+ child.on("close", (code, signal) => {
1048
+ clearTimeout(timer);
1049
+ if (settled) return;
1050
+ settled = true;
1051
+ if (code === 0) {
1052
+ callbacks.onEnd({ stopReason: "end_turn" });
1053
+ } else {
1054
+ const stdout = Buffer.concat(chunks).toString("utf-8").trim();
1055
+ const msg = signal ? `Claude CLI killed (${signal})` : code != null ? `Claude CLI exited with code ${code}` : "Claude CLI exited";
1056
+ callbacks.onError(new Error(stdout ? `${msg}. Output: ${stdout.slice(0, 200)}` : msg));
1057
+ }
1058
+ });
1024
1059
  }
1025
1060
  buildCombinedPrompt(options) {
1026
1061
  const streamOpts = options;
@@ -1546,9 +1581,9 @@ function isTransientError2(error) {
1546
1581
  const msg = error.message.toLowerCase();
1547
1582
  return TRANSIENT_ERRORS.some((e) => msg.includes(e.toLowerCase()));
1548
1583
  }
1549
- async function generateSetup(fingerprint, targetAgent, prompt, callbacks, failingChecks, currentScore) {
1584
+ async function generateSetup(fingerprint, targetAgent, prompt, callbacks, failingChecks, currentScore, passingChecks) {
1550
1585
  const provider = getProvider();
1551
- const userMessage = buildGeneratePrompt(fingerprint, targetAgent, prompt, failingChecks, currentScore);
1586
+ const userMessage = buildGeneratePrompt(fingerprint, targetAgent, prompt, failingChecks, currentScore, passingChecks);
1552
1587
  let attempt = 0;
1553
1588
  const attemptGeneration = async () => {
1554
1589
  attempt++;
@@ -1658,7 +1693,7 @@ function truncate(text, maxChars) {
1658
1693
  return text.slice(0, maxChars) + `
1659
1694
  ... (truncated at ${maxChars} chars)`;
1660
1695
  }
1661
- function buildGeneratePrompt(fingerprint, targetAgent, prompt, failingChecks, currentScore) {
1696
+ function buildGeneratePrompt(fingerprint, targetAgent, prompt, failingChecks, currentScore, passingChecks) {
1662
1697
  const parts = [];
1663
1698
  const existing = fingerprint.existingConfigs;
1664
1699
  const hasExistingConfigs = !!(existing.claudeMd || existing.claudeSettings || existing.claudeSkills?.length || existing.readmeMd || existing.cursorrules || existing.cursorRules?.length);
@@ -1670,8 +1705,15 @@ The existing config is already high quality. ONLY fix these specific failing che
1670
1705
  for (const check of failingChecks) {
1671
1706
  parts.push(`- ${check.name}${check.suggestion ? `: ${check.suggestion}` : ""}`);
1672
1707
  }
1708
+ if (passingChecks && passingChecks.length > 0) {
1709
+ parts.push(`
1710
+ These checks are currently PASSING \u2014 do NOT break them:`);
1711
+ for (const check of passingChecks) {
1712
+ parts.push(`- ${check.name}`);
1713
+ }
1714
+ }
1673
1715
  parts.push(`
1674
- IMPORTANT: Return the existing CLAUDE.md and skills with MINIMAL changes \u2014 only the edits needed to fix the above checks. Do NOT rewrite, restructure, rephrase, or make cosmetic changes. Preserve the existing content as-is except for targeted fixes.`);
1716
+ IMPORTANT: Return the existing CLAUDE.md and skills with MINIMAL changes \u2014 only the edits needed to fix the above checks. Do NOT rewrite, restructure, rephrase, or make cosmetic changes. Preserve the existing content as-is except for targeted fixes. If a skill file is not related to a failing check, return it EXACTLY as-is, character for character.`);
1675
1717
  } else if (hasExistingConfigs) {
1676
1718
  parts.push(`Audit and improve the existing coding agent configuration for target: ${targetAgent}`);
1677
1719
  } else {
@@ -3792,10 +3834,9 @@ async function initCommand(options) {
3792
3834
  `));
3793
3835
  const targetAgent = options.agent || await promptAgent();
3794
3836
  const baselineScore = computeLocalScore(process.cwd(), targetAgent);
3837
+ displayScore(baselineScore);
3795
3838
  const hasExistingConfig = !!(fingerprint.existingConfigs.claudeMd || fingerprint.existingConfigs.claudeSettings || fingerprint.existingConfigs.claudeSkills?.length || fingerprint.existingConfigs.cursorrules || fingerprint.existingConfigs.cursorRules?.length);
3796
3839
  if (hasExistingConfig && baselineScore.score === 100) {
3797
- console.log(chalk4.hex("#6366f1").bold(" Step 3/4 \u2014 Score check\n"));
3798
- displayScore(baselineScore);
3799
3840
  console.log(chalk4.bold.green(" Your setup is already optimal \u2014 nothing to change.\n"));
3800
3841
  console.log(chalk4.dim(" Run `caliber init --force` to regenerate anyway.\n"));
3801
3842
  if (!options.force) return;
@@ -3805,9 +3846,11 @@ async function initCommand(options) {
3805
3846
  fingerprint.description = await promptInput2("What will you build in this project?");
3806
3847
  }
3807
3848
  let failingChecks;
3849
+ let passingChecks;
3808
3850
  let currentScore;
3809
3851
  if (hasExistingConfig && baselineScore.score >= 95 && !options.force) {
3810
3852
  failingChecks = baselineScore.checks.filter((c) => !c.passed && c.maxPoints > 0).map((c) => ({ name: c.name, suggestion: c.suggestion }));
3853
+ passingChecks = baselineScore.checks.filter((c) => c.passed).map((c) => ({ name: c.name }));
3811
3854
  currentScore = baselineScore.score;
3812
3855
  if (failingChecks.length > 0) {
3813
3856
  console.log(chalk4.hex("#6366f1").bold(" Step 3/4 \u2014 Targeted fixes\n"));
@@ -3851,7 +3894,8 @@ async function initCommand(options) {
3851
3894
  }
3852
3895
  },
3853
3896
  failingChecks,
3854
- currentScore
3897
+ currentScore,
3898
+ passingChecks
3855
3899
  );
3856
3900
  if (!generatedSetup) {
3857
3901
  generatedSetup = result.setup;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rely-ai/caliber",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "description": "Open-source CLI for configuring coding agent environments (CLAUDE.md, .cursorrules, skills). Bring your own LLM.",
5
5
  "type": "module",
6
6
  "bin": {