@rely-ai/caliber 1.40.0 → 1.40.2
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/README.md +13 -1
- package/dist/bin.js +73 -20
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -51,7 +51,7 @@ Requires **Node.js >= 20**.
|
|
|
51
51
|
npx @rely-ai/caliber bootstrap
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
Then, in your
|
|
54
|
+
Then, in your terminal (not the IDE chat), start a Claude Code or Cursor CLI session and type:
|
|
55
55
|
|
|
56
56
|
> **/setup-caliber**
|
|
57
57
|
|
|
@@ -61,6 +61,18 @@ Your agent detects your stack, generates tailored configs for every platform you
|
|
|
61
61
|
|
|
62
62
|
> **Your code stays on your machine.** Bootstrap is 100% local — no LLM calls, no code sent anywhere. Generation uses your own AI subscription or API key. Caliber never sees your code.
|
|
63
63
|
|
|
64
|
+
<details>
|
|
65
|
+
<summary><strong>Windows Users</strong></summary>
|
|
66
|
+
|
|
67
|
+
Caliber works on Windows with a few notes:
|
|
68
|
+
|
|
69
|
+
- **Run from your terminal** (PowerShell, CMD, or Git Bash) — not from inside an IDE chat window. Open a terminal, `cd` into your project folder, then run `npx @rely-ai/caliber bootstrap`.
|
|
70
|
+
- **Git Bash is recommended.** Caliber's pre-commit hooks and auto-sync scripts use shell syntax. Git for Windows includes Git Bash, which handles this automatically. If you only use PowerShell, hooks may be skipped silently.
|
|
71
|
+
- **Cursor Agent CLI:** If prompted to install it, download from [cursor.com/downloads](https://www.cursor.com/downloads) instead of the `curl | bash` command shown on macOS/Linux. Then run `agent login` in your terminal to authenticate.
|
|
72
|
+
- **One terminal at a time.** Avoid running Caliber from multiple terminals simultaneously — this can cause conflicting state and unexpected provider detection.
|
|
73
|
+
|
|
74
|
+
</details>
|
|
75
|
+
|
|
64
76
|
## Audits first, writes second
|
|
65
77
|
|
|
66
78
|
Caliber never overwrites your existing configs without asking. The workflow mirrors code review:
|
package/dist/bin.js
CHANGED
|
@@ -858,7 +858,7 @@ function openDiffsInEditor(editor, files) {
|
|
|
858
858
|
for (const file of files) {
|
|
859
859
|
try {
|
|
860
860
|
const leftPath = file.originalPath ?? getEmptyFilePath(file.proposedPath);
|
|
861
|
-
if (
|
|
861
|
+
if (IS_WINDOWS4) {
|
|
862
862
|
const quote = (s) => `"${s}"`;
|
|
863
863
|
spawn3([cmd, "--diff", quote(leftPath), quote(file.proposedPath)].join(" "), { shell: true, stdio: "ignore", detached: true }).unref();
|
|
864
864
|
} else {
|
|
@@ -869,11 +869,11 @@ function openDiffsInEditor(editor, files) {
|
|
|
869
869
|
}
|
|
870
870
|
}
|
|
871
871
|
}
|
|
872
|
-
var
|
|
872
|
+
var IS_WINDOWS4, DIFF_TEMP_DIR;
|
|
873
873
|
var init_editor = __esm({
|
|
874
874
|
"src/utils/editor.ts"() {
|
|
875
875
|
"use strict";
|
|
876
|
-
|
|
876
|
+
IS_WINDOWS4 = process.platform === "win32";
|
|
877
877
|
DIFF_TEMP_DIR = path25.join(os6.tmpdir(), "caliber-diff");
|
|
878
878
|
}
|
|
879
879
|
});
|
|
@@ -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: "
|
|
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:
|
|
@@ -3078,6 +3108,10 @@ async function llmCall(options) {
|
|
|
3078
3108
|
await new Promise((r) => setTimeout(r, 1e3 * Math.pow(2, attempt - 1)));
|
|
3079
3109
|
continue;
|
|
3080
3110
|
}
|
|
3111
|
+
if (isRateLimitError(error.message) && attempt < MAX_RETRIES) {
|
|
3112
|
+
await new Promise((r) => setTimeout(r, 2e3 * Math.pow(2, attempt - 1)));
|
|
3113
|
+
continue;
|
|
3114
|
+
}
|
|
3081
3115
|
if (isTransientError(error) && attempt < MAX_RETRIES) {
|
|
3082
3116
|
await new Promise((r) => setTimeout(r, 1e3 * Math.pow(2, attempt - 1)));
|
|
3083
3117
|
continue;
|
|
@@ -6274,6 +6308,7 @@ init_config();
|
|
|
6274
6308
|
import chalk3 from "chalk";
|
|
6275
6309
|
import select2 from "@inquirer/select";
|
|
6276
6310
|
import confirm from "@inquirer/confirm";
|
|
6311
|
+
var IS_WINDOWS3 = process.platform === "win32";
|
|
6277
6312
|
var PROVIDER_CHOICES = [
|
|
6278
6313
|
{ name: "Claude Code \u2014 use your existing subscription (no API key)", value: "claude-cli" },
|
|
6279
6314
|
{ name: "Cursor \u2014 use your existing subscription (no API key)", value: "cursor" },
|
|
@@ -6297,6 +6332,11 @@ async function runInteractiveProviderSetup(options) {
|
|
|
6297
6332
|
console.log(chalk3.dim(" Then run ") + chalk3.hex("#83D1EB")("claude") + chalk3.dim(" once to log in.\n"));
|
|
6298
6333
|
const proceed = await confirm({ message: "Continue anyway?" });
|
|
6299
6334
|
if (!proceed) throw new Error("__exit__");
|
|
6335
|
+
} else if (!isClaudeCliLoggedIn()) {
|
|
6336
|
+
console.log(chalk3.yellow("\n Claude Code CLI found but not logged in."));
|
|
6337
|
+
console.log(chalk3.dim(" Run ") + chalk3.hex("#83D1EB")("claude") + chalk3.dim(" once to log in.\n"));
|
|
6338
|
+
const proceed = await confirm({ message: "Continue anyway?" });
|
|
6339
|
+
if (!proceed) throw new Error("__exit__");
|
|
6300
6340
|
} else {
|
|
6301
6341
|
console.log(chalk3.dim(" Run `claude` once and log in with your Pro/Max/Team account if you haven't."));
|
|
6302
6342
|
}
|
|
@@ -6305,8 +6345,13 @@ async function runInteractiveProviderSetup(options) {
|
|
|
6305
6345
|
case "cursor": {
|
|
6306
6346
|
if (!isCursorAgentAvailable()) {
|
|
6307
6347
|
console.log(chalk3.yellow("\n Cursor Agent CLI not found."));
|
|
6308
|
-
|
|
6309
|
-
|
|
6348
|
+
if (IS_WINDOWS3) {
|
|
6349
|
+
console.log(chalk3.dim(" Install it from: ") + chalk3.hex("#83D1EB")("https://www.cursor.com/downloads"));
|
|
6350
|
+
console.log(chalk3.dim(" Then run ") + chalk3.hex("#83D1EB")("agent login") + chalk3.dim(" in PowerShell to authenticate.\n"));
|
|
6351
|
+
} else {
|
|
6352
|
+
console.log(chalk3.dim(" Install it: ") + chalk3.hex("#83D1EB")("curl https://cursor.com/install -fsS | bash"));
|
|
6353
|
+
console.log(chalk3.dim(" Then run ") + chalk3.hex("#83D1EB")("agent login") + chalk3.dim(" to authenticate.\n"));
|
|
6354
|
+
}
|
|
6310
6355
|
const proceed = await confirm({ message: "Continue anyway?" });
|
|
6311
6356
|
if (!proceed) throw new Error("__exit__");
|
|
6312
6357
|
} else if (!isCursorLoggedIn()) {
|
|
@@ -6611,7 +6656,7 @@ function checkExistence(dir) {
|
|
|
6611
6656
|
earnedPoints: Math.min(skillPoints, maxSkillPoints),
|
|
6612
6657
|
passed: skillCount >= 1,
|
|
6613
6658
|
detail: skillCount === 0 ? "No skills found" : `${skillCount} skill${skillCount === 1 ? "" : "s"} found`,
|
|
6614
|
-
suggestion: skillCount === 0 ? "
|
|
6659
|
+
suggestion: skillCount === 0 ? "Skills are reusable agent workflows (e.g., deploy, test, review). Add 2-3 for your most common tasks" : skillCount < 3 ? "Optimal is 2-3 focused skills" : void 0,
|
|
6615
6660
|
fix: skillCount === 0 ? {
|
|
6616
6661
|
action: "create_skills",
|
|
6617
6662
|
data: { currentCount: 0 },
|
|
@@ -6628,7 +6673,7 @@ function checkExistence(dir) {
|
|
|
6628
6673
|
earnedPoints: mdcCount >= 1 ? POINTS_CURSOR_MDC_RULES : 0,
|
|
6629
6674
|
passed: mdcCount >= 1,
|
|
6630
6675
|
detail: mdcCount === 0 ? "No .mdc rule files" : `${mdcCount} .mdc rule${mdcCount === 1 ? "" : "s"} found`,
|
|
6631
|
-
suggestion: mdcCount === 0 ? "
|
|
6676
|
+
suggestion: mdcCount === 0 ? "Cursor .mdc rules use frontmatter to scope rules to specific files/paths. Add them for more targeted Cursor behavior" : void 0,
|
|
6632
6677
|
fix: mdcCount === 0 ? {
|
|
6633
6678
|
action: "create_mdc_rules",
|
|
6634
6679
|
data: {},
|
|
@@ -6644,7 +6689,7 @@ function checkExistence(dir) {
|
|
|
6644
6689
|
earnedPoints: mcp.count >= 1 ? POINTS_MCP_SERVERS : 0,
|
|
6645
6690
|
passed: mcp.count >= 1,
|
|
6646
6691
|
detail: mcp.count > 0 ? `${mcp.count} server${mcp.count === 1 ? "" : "s"} in ${mcp.sources.join(", ")}` : "No MCP servers configured",
|
|
6647
|
-
suggestion: mcp.count === 0 ? "
|
|
6692
|
+
suggestion: mcp.count === 0 ? "MCP servers connect your agent to external tools (databases, Slack, Linear, etc). Add if your team uses external services" : void 0,
|
|
6648
6693
|
fix: mcp.count === 0 ? {
|
|
6649
6694
|
action: "configure_mcp",
|
|
6650
6695
|
data: {},
|
|
@@ -6713,7 +6758,7 @@ function checkQuality(dir) {
|
|
|
6713
6758
|
earnedPoints: tokenPoints,
|
|
6714
6759
|
passed: tokenPoints >= 4,
|
|
6715
6760
|
detail: totalContent.length === 0 ? "No config files to measure" : `~${totalTokens} tokens total across all config files`,
|
|
6716
|
-
suggestion: tokenPoints < 4 && totalContent.length > 0 ? `
|
|
6761
|
+
suggestion: tokenPoints < 4 && totalContent.length > 0 ? `Config is ~${totalTokens} tokens. Agents work best under ~5000 tokens (~4 pages of text) \u2014 trim verbose sections` : void 0,
|
|
6717
6762
|
fix: tokenPoints < 4 && totalContent.length > 0 ? {
|
|
6718
6763
|
action: "reduce_size",
|
|
6719
6764
|
data: { currentTokens: totalTokens, targetTokens: 5e3 },
|
|
@@ -7157,7 +7202,7 @@ function checkFreshness(dir) {
|
|
|
7157
7202
|
earnedPoints: hasPermissions ? POINTS_PERMISSIONS : 0,
|
|
7158
7203
|
passed: hasPermissions,
|
|
7159
7204
|
detail: permissionDetail,
|
|
7160
|
-
suggestion: hasPermissions ? void 0 : "
|
|
7205
|
+
suggestion: hasPermissions ? void 0 : "Permissions control which shell commands the agent can run without asking. Adds a safety layer for your team",
|
|
7161
7206
|
fix: hasPermissions ? void 0 : {
|
|
7162
7207
|
action: "add_permissions",
|
|
7163
7208
|
data: {},
|
|
@@ -7222,7 +7267,7 @@ function checkBonus(dir) {
|
|
|
7222
7267
|
earnedPoints: hasHooks ? POINTS_HOOKS : 0,
|
|
7223
7268
|
passed: hasHooks,
|
|
7224
7269
|
detail: hasHooks ? hookSources.join(", ") : "No hooks configured",
|
|
7225
|
-
suggestion: hasHooks ? void 0 : `Run \`${resolveCaliber()} init\` to
|
|
7270
|
+
suggestion: hasHooks ? void 0 : `Hooks auto-sync your agent config on every commit so it stays fresh. Run \`${resolveCaliber()} init\` to set up`,
|
|
7226
7271
|
fix: hasHooks ? void 0 : {
|
|
7227
7272
|
action: "install_hooks",
|
|
7228
7273
|
data: {},
|
|
@@ -7238,7 +7283,7 @@ function checkBonus(dir) {
|
|
|
7238
7283
|
earnedPoints: agentsMdExists ? POINTS_AGENTS_MD : 0,
|
|
7239
7284
|
passed: agentsMdExists,
|
|
7240
7285
|
detail: agentsMdExists ? "Found at project root" : "Not found",
|
|
7241
|
-
suggestion: agentsMdExists ? void 0 : "
|
|
7286
|
+
suggestion: agentsMdExists ? void 0 : "AGENTS.md provides project context to Codex, Copilot, and other agents. Works alongside CLAUDE.md",
|
|
7242
7287
|
fix: agentsMdExists ? void 0 : {
|
|
7243
7288
|
action: "create_file",
|
|
7244
7289
|
data: { file: "AGENTS.md" },
|
|
@@ -7274,7 +7319,7 @@ function checkBonus(dir) {
|
|
|
7274
7319
|
earnedPoints: allOpenSkills ? POINTS_OPEN_SKILLS_FORMAT : 0,
|
|
7275
7320
|
passed: allOpenSkills || totalSkillFiles === 0,
|
|
7276
7321
|
detail: totalSkillFiles === 0 ? "No skills to check" : allOpenSkills ? `All ${totalSkillFiles} skill${totalSkillFiles === 1 ? "" : "s"} use SKILL.md with frontmatter` : `${openSkillsCount}/${totalSkillFiles} use OpenSkills format`,
|
|
7277
|
-
suggestion: totalSkillFiles > 0 && !allOpenSkills ? "
|
|
7322
|
+
suggestion: totalSkillFiles > 0 && !allOpenSkills ? "OpenSkills format (SKILL.md with YAML header) makes skills portable across agents. Migrate for cross-tool compatibility" : void 0,
|
|
7278
7323
|
fix: totalSkillFiles > 0 && !allOpenSkills ? {
|
|
7279
7324
|
action: "migrate_skills",
|
|
7280
7325
|
data: { openSkills: openSkillsCount, total: totalSkillFiles },
|
|
@@ -7291,7 +7336,7 @@ function checkBonus(dir) {
|
|
|
7291
7336
|
earnedPoints: hasLearned ? POINTS_LEARNED_CONTENT : 0,
|
|
7292
7337
|
passed: hasLearned,
|
|
7293
7338
|
detail: hasLearned ? "Session learnings found in CALIBER_LEARNINGS.md" : "No learned content",
|
|
7294
|
-
suggestion: hasLearned ? void 0 : `
|
|
7339
|
+
suggestion: hasLearned ? void 0 : `Session learnings capture patterns from your coding sessions so the agent improves over time. Run \`${resolveCaliber()} learn install\``
|
|
7295
7340
|
});
|
|
7296
7341
|
return checks;
|
|
7297
7342
|
}
|
|
@@ -7532,7 +7577,7 @@ function displayScore(result) {
|
|
|
7532
7577
|
formatTopImprovements(result.checks);
|
|
7533
7578
|
}
|
|
7534
7579
|
function formatTopImprovements(checks) {
|
|
7535
|
-
const improvable = checks.filter((c) => c.earnedPoints < c.maxPoints).map((c) => ({ name: c.name, potential: c.maxPoints - c.earnedPoints })).sort((a, b) => b.potential - a.potential).slice(0, 5);
|
|
7580
|
+
const improvable = checks.filter((c) => c.earnedPoints < c.maxPoints).map((c) => ({ name: c.name, potential: c.maxPoints - c.earnedPoints, suggestion: c.suggestion })).sort((a, b) => b.potential - a.potential).slice(0, 5);
|
|
7536
7581
|
if (improvable.length === 0) return;
|
|
7537
7582
|
console.log(chalk4.gray(" \u2500 TOP IMPROVEMENTS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
7538
7583
|
console.log("");
|
|
@@ -7542,6 +7587,9 @@ function formatTopImprovements(checks) {
|
|
|
7542
7587
|
const label = chalk4.white(item.name.padEnd(42));
|
|
7543
7588
|
const pts = chalk4.yellow(`+${item.potential} pts`);
|
|
7544
7589
|
console.log(` ${num} ${label}${pts}`);
|
|
7590
|
+
if (item.suggestion) {
|
|
7591
|
+
console.log(chalk4.gray(` ${item.suggestion}`));
|
|
7592
|
+
}
|
|
7545
7593
|
}
|
|
7546
7594
|
console.log("");
|
|
7547
7595
|
}
|
|
@@ -10097,6 +10145,7 @@ function getScoreTrend(entries) {
|
|
|
10097
10145
|
}
|
|
10098
10146
|
|
|
10099
10147
|
// src/commands/init.ts
|
|
10148
|
+
var IS_WINDOWS5 = process.platform === "win32";
|
|
10100
10149
|
function log(verbose, ...args) {
|
|
10101
10150
|
if (verbose) console.log(chalk14.dim(` [verbose] ${args.map(String).join(" ")}`));
|
|
10102
10151
|
}
|
|
@@ -10141,7 +10190,7 @@ async function initCommand(options) {
|
|
|
10141
10190
|
console.log(title.bold(" Step 1/3 \u2014 Connect\n"));
|
|
10142
10191
|
let config = loadConfig();
|
|
10143
10192
|
if (!config && !options.autoApprove) {
|
|
10144
|
-
if (isClaudeCliAvailable()) {
|
|
10193
|
+
if (isClaudeCliAvailable() && isClaudeCliLoggedIn()) {
|
|
10145
10194
|
console.log(chalk14.dim(" Detected: Claude Code CLI (uses your Pro/Max/Team subscription)\n"));
|
|
10146
10195
|
const useIt = await confirm2({ message: "Use Claude Code as your LLM provider?" });
|
|
10147
10196
|
if (useIt) {
|
|
@@ -10161,7 +10210,7 @@ async function initCommand(options) {
|
|
|
10161
10210
|
}
|
|
10162
10211
|
if (!config) {
|
|
10163
10212
|
if (options.autoApprove) {
|
|
10164
|
-
if (isClaudeCliAvailable()) {
|
|
10213
|
+
if (isClaudeCliAvailable() && isClaudeCliLoggedIn()) {
|
|
10165
10214
|
const autoConfig = { provider: "claude-cli", model: "default" };
|
|
10166
10215
|
writeConfigFile(autoConfig);
|
|
10167
10216
|
config = autoConfig;
|
|
@@ -10232,6 +10281,10 @@ async function initCommand(options) {
|
|
|
10232
10281
|
console.log(` ${chalk14.green("\u2713")} Onboarding hook \u2014 nudges new team members to set up`);
|
|
10233
10282
|
installSessionStartHook();
|
|
10234
10283
|
console.log(` ${chalk14.green("\u2713")} Freshness hook \u2014 warns when configs are stale`);
|
|
10284
|
+
if (IS_WINDOWS5) {
|
|
10285
|
+
console.log(chalk14.yellow("\n Note: hooks use shell syntax and require Git Bash (included with Git for Windows)."));
|
|
10286
|
+
console.log(chalk14.dim(" If hooks don't run, ensure Git for Windows is installed and git is using its bundled sh."));
|
|
10287
|
+
}
|
|
10235
10288
|
const { ensureBuiltinSkills: ensureBuiltinSkills2 } = await Promise.resolve().then(() => (init_builtin_skills(), builtin_skills_exports));
|
|
10236
10289
|
for (const agent of targetAgent) {
|
|
10237
10290
|
if (agent === "claude" && !fs34.existsSync(".claude"))
|
|
@@ -11209,12 +11262,12 @@ async function scoreCommand(options) {
|
|
|
11209
11262
|
chalk18.gray(" Biggest gain: ") + chalk18.yellow(`+${pts} pts`) + chalk18.gray(` from "${topFix.name}"`) + (topFix.suggestion ? chalk18.gray(` \u2014 ${topFix.suggestion}`) : "")
|
|
11210
11263
|
);
|
|
11211
11264
|
console.log(
|
|
11212
|
-
chalk18.gray(" Run ") + chalk18.hex("#83D1EB")(`${bin} init`) + chalk18.gray(" to
|
|
11265
|
+
chalk18.gray(" Run ") + chalk18.hex("#83D1EB")(`${bin} init`) + chalk18.gray(" to generate or update your agent config files.")
|
|
11213
11266
|
);
|
|
11214
11267
|
} else if (failing.length > 0) {
|
|
11215
11268
|
console.log(
|
|
11216
11269
|
chalk18.green(" Looking good!") + chalk18.gray(
|
|
11217
|
-
` ${failing.length}
|
|
11270
|
+
` ${failing.length} optional improvement${failing.length === 1 ? "" : "s"} available.`
|
|
11218
11271
|
)
|
|
11219
11272
|
);
|
|
11220
11273
|
console.log(
|
package/package.json
CHANGED