@rely-ai/caliber 1.6.0 → 1.6.1

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 +381 -896
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -51,17 +51,17 @@ var init_constants = __esm({
51
51
 
52
52
  // src/cli.ts
53
53
  import { Command } from "commander";
54
- import fs28 from "fs";
55
- import path22 from "path";
54
+ import fs27 from "fs";
55
+ import path21 from "path";
56
56
  import { fileURLToPath } from "url";
57
57
 
58
58
  // src/commands/onboard.ts
59
- import chalk7 from "chalk";
60
- import ora3 from "ora";
61
- import readline4 from "readline";
59
+ import chalk6 from "chalk";
60
+ import ora2 from "ora";
61
+ import readline3 from "readline";
62
62
  import select4 from "@inquirer/select";
63
63
  import checkbox from "@inquirer/checkbox";
64
- import fs22 from "fs";
64
+ import fs21 from "fs";
65
65
 
66
66
  // src/fingerprint/index.ts
67
67
  import fs6 from "fs";
@@ -3016,15 +3016,15 @@ function computeGrade(score) {
3016
3016
  // src/scoring/checks/coverage.ts
3017
3017
  import { readFileSync, readdirSync } from "fs";
3018
3018
  import { join } from "path";
3019
- function readFileOrNull(path24) {
3019
+ function readFileOrNull(path23) {
3020
3020
  try {
3021
- return readFileSync(path24, "utf-8");
3021
+ return readFileSync(path23, "utf-8");
3022
3022
  } catch {
3023
3023
  return null;
3024
3024
  }
3025
3025
  }
3026
- function readJsonOrNull(path24) {
3027
- const content = readFileOrNull(path24);
3026
+ function readJsonOrNull(path23) {
3027
+ const content = readFileOrNull(path23);
3028
3028
  if (!content) return null;
3029
3029
  try {
3030
3030
  return JSON.parse(content);
@@ -3392,9 +3392,9 @@ function checkExistence(dir) {
3392
3392
  // src/scoring/checks/quality.ts
3393
3393
  import { readFileSync as readFileSync3 } from "fs";
3394
3394
  import { join as join3 } from "path";
3395
- function readFileOrNull2(path24) {
3395
+ function readFileOrNull2(path23) {
3396
3396
  try {
3397
- return readFileSync3(path24, "utf-8");
3397
+ return readFileSync3(path23, "utf-8");
3398
3398
  } catch {
3399
3399
  return null;
3400
3400
  }
@@ -3547,15 +3547,15 @@ function checkQuality(dir) {
3547
3547
  // src/scoring/checks/accuracy.ts
3548
3548
  import { existsSync as existsSync5, readFileSync as readFileSync4, readdirSync as readdirSync3, statSync } from "fs";
3549
3549
  import { join as join4 } from "path";
3550
- function readFileOrNull3(path24) {
3550
+ function readFileOrNull3(path23) {
3551
3551
  try {
3552
- return readFileSync4(path24, "utf-8");
3552
+ return readFileSync4(path23, "utf-8");
3553
3553
  } catch {
3554
3554
  return null;
3555
3555
  }
3556
3556
  }
3557
- function readJsonOrNull2(path24) {
3558
- const content = readFileOrNull3(path24);
3557
+ function readJsonOrNull2(path23) {
3558
+ const content = readFileOrNull3(path23);
3559
3559
  if (!content) return null;
3560
3560
  try {
3561
3561
  return JSON.parse(content);
@@ -3738,9 +3738,9 @@ function checkAccuracy(dir) {
3738
3738
  // src/scoring/checks/freshness.ts
3739
3739
  import { existsSync as existsSync6, readFileSync as readFileSync5, statSync as statSync2 } from "fs";
3740
3740
  import { join as join5 } from "path";
3741
- function readFileOrNull4(path24) {
3741
+ function readFileOrNull4(path23) {
3742
3742
  try {
3743
- return readFileSync5(path24, "utf-8");
3743
+ return readFileSync5(path23, "utf-8");
3744
3744
  } catch {
3745
3745
  return null;
3746
3746
  }
@@ -3854,9 +3854,9 @@ function checkFreshness(dir) {
3854
3854
  import { existsSync as existsSync7, readFileSync as readFileSync6, readdirSync as readdirSync4 } from "fs";
3855
3855
  import { execSync as execSync7 } from "child_process";
3856
3856
  import { join as join6 } from "path";
3857
- function readFileOrNull5(path24) {
3857
+ function readFileOrNull5(path23) {
3858
3858
  try {
3859
- return readFileSync6(path24, "utf-8");
3859
+ return readFileSync6(path23, "utf-8");
3860
3860
  } catch {
3861
3861
  return null;
3862
3862
  }
@@ -4153,517 +4153,21 @@ function displayScoreDelta(before, after) {
4153
4153
  }
4154
4154
  }
4155
4155
 
4156
- // src/mcp/index.ts
4156
+ // src/commands/recommend.ts
4157
4157
  import chalk5 from "chalk";
4158
4158
  import ora from "ora";
4159
- import readline3 from "readline";
4160
- import fs20 from "fs";
4161
- import path16 from "path";
4162
-
4163
- // src/mcp/search.ts
4164
- var AWESOME_MCP_URL = "https://raw.githubusercontent.com/punkpeye/awesome-mcp-servers/main/README.md";
4165
- var GITHUB_SEARCH_URL = "https://github.com/search";
4166
- var SEARCH_HEADERS = {
4167
- "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
4168
- "Accept": "text/html"
4169
- };
4170
- function parseGitHubSearchHtml(html) {
4171
- try {
4172
- const scriptMatch = html.match(/<script type="application\/json" data-target="react-app\.embeddedData">([\s\S]*?)<\/script>/);
4173
- if (!scriptMatch) {
4174
- return [];
4175
- }
4176
- const data = JSON.parse(scriptMatch[1]);
4177
- const results = data?.payload?.results;
4178
- if (!Array.isArray(results)) {
4179
- return [];
4180
- }
4181
- return results.map((r) => {
4182
- const repo = r.repo?.repository;
4183
- const ownerLogin = repo?.owner_login || "";
4184
- const name = repo?.name || "";
4185
- const description = typeof r.hl_trunc_description === "string" ? r.hl_trunc_description.replace(/<\/?em>/g, "") : null;
4186
- return {
4187
- full_name: `${ownerLogin}/${name}`,
4188
- description,
4189
- stargazers_count: typeof r.followers === "number" ? r.followers : 0,
4190
- pushed_at: repo?.updated_at || "",
4191
- owner_login: ownerLogin
4192
- };
4193
- });
4194
- } catch {
4195
- return [];
4196
- }
4197
- }
4198
- async function searchAllMcpSources(toolDeps) {
4199
- if (toolDeps.length === 0) return [];
4200
- const searches = [
4201
- searchAwesomeMcpLists(toolDeps),
4202
- ...toolDeps.map((dep) => searchGitHub(dep)),
4203
- ...toolDeps.map((dep) => searchVendorOrg(dep))
4204
- ];
4205
- const results = await Promise.all(searches);
4206
- const seen = /* @__PURE__ */ new Map();
4207
- for (const batch of results) {
4208
- for (const candidate of batch) {
4209
- const key = candidate.repoFullName.toLowerCase();
4210
- const existing = seen.get(key);
4211
- if (!existing || candidate.vendor || candidate.stars > existing.stars) {
4212
- seen.set(key, candidate);
4213
- }
4214
- }
4215
- }
4216
- return Array.from(seen.values());
4217
- }
4218
- async function searchAwesomeMcpLists(toolDeps) {
4219
- try {
4220
- const resp = await fetch(AWESOME_MCP_URL, {
4221
- signal: AbortSignal.timeout(1e4)
4222
- });
4223
- if (!resp.ok) return [];
4224
- const markdown = await resp.text();
4225
- const candidates = [];
4226
- const depLower = toolDeps.map((d) => d.toLowerCase().replace(/^@[^/]+\//, ""));
4227
- const itemPattern = /^[-*]\s+\[([^\]]+)\]\(([^)]+)\)\s*[-–—:]\s*(.*)/gm;
4228
- let match;
4229
- while ((match = itemPattern.exec(markdown)) !== null) {
4230
- const [, name, url, description] = match;
4231
- if (!url.includes("github.com")) continue;
4232
- const text = `${name} ${description}`.toLowerCase();
4233
- const matchedDep = depLower.find((d) => text.includes(d));
4234
- if (!matchedDep) continue;
4235
- const repoMatch = url.match(/github\.com\/([^/]+\/[^/]+)/);
4236
- if (!repoMatch) continue;
4237
- candidates.push({
4238
- name: name.trim(),
4239
- repoFullName: repoMatch[1],
4240
- url: url.trim(),
4241
- description: description.trim().slice(0, 200),
4242
- stars: 0,
4243
- lastPush: "",
4244
- vendor: false,
4245
- score: 0,
4246
- reason: "",
4247
- matchedDep: toolDeps.find((d) => d.toLowerCase().replace(/^@[^/]+\//, "") === matchedDep) || matchedDep
4248
- });
4249
- }
4250
- return candidates;
4251
- } catch {
4252
- return [];
4253
- }
4254
- }
4255
- async function searchGitHub(dep) {
4256
- const depName = dep.replace(/^@[^/]+\//, "");
4257
- try {
4258
- const query = encodeURIComponent(`${depName} mcp server`);
4259
- const url = `${GITHUB_SEARCH_URL}?q=${query}&type=repositories&s=stars&o=desc`;
4260
- const resp = await fetch(url, {
4261
- signal: AbortSignal.timeout(1e4),
4262
- headers: SEARCH_HEADERS
4263
- });
4264
- if (!resp.ok) return [];
4265
- const html = await resp.text();
4266
- const repos = parseGitHubSearchHtml(html).slice(0, 5);
4267
- return repos.map((repo) => ({
4268
- name: repo.full_name.split("/")[1],
4269
- repoFullName: repo.full_name,
4270
- url: `https://github.com/${repo.full_name}`,
4271
- description: repo.description || "",
4272
- stars: repo.stargazers_count,
4273
- lastPush: repo.pushed_at,
4274
- vendor: false,
4275
- score: 0,
4276
- reason: "",
4277
- matchedDep: dep
4278
- }));
4279
- } catch {
4280
- return [];
4281
- }
4282
- }
4283
- async function searchVendorOrg(dep) {
4284
- const depName = dep.replace(/^@([^/]+)\/.*/, "$1").replace(/^@/, "");
4285
- const orgName = depName.toLowerCase();
4286
- try {
4287
- const query = encodeURIComponent(`mcp org:${orgName}`);
4288
- const url = `${GITHUB_SEARCH_URL}?q=${query}&type=repositories&s=stars&o=desc`;
4289
- const resp = await fetch(url, {
4290
- signal: AbortSignal.timeout(1e4),
4291
- headers: SEARCH_HEADERS
4292
- });
4293
- if (!resp.ok) return [];
4294
- const html = await resp.text();
4295
- const repos = parseGitHubSearchHtml(html).slice(0, 5);
4296
- return repos.map((repo) => ({
4297
- name: repo.full_name.split("/")[1],
4298
- repoFullName: repo.full_name,
4299
- url: `https://github.com/${repo.full_name}`,
4300
- description: repo.description || "",
4301
- stars: repo.stargazers_count,
4302
- lastPush: repo.pushed_at,
4303
- vendor: repo.owner_login.toLowerCase() === orgName,
4304
- score: 0,
4305
- reason: "",
4306
- matchedDep: dep
4307
- }));
4308
- } catch {
4309
- return [];
4310
- }
4311
- }
4312
-
4313
- // src/mcp/prompts.ts
4314
- var SCORE_MCP_PROMPT = `You evaluate MCP (Model Context Protocol) server candidates for relevance to a software project.
4315
-
4316
- Score each candidate from 0-100 based on:
4317
- - **Relevance** (40%): How directly does it match the project's detected tool dependencies?
4318
- - **Capabilities** (30%): Does it provide meaningful read+write operations (not just read-only)?
4319
- - **Quality signals** (30%): Stars, recent activity, vendor/official status
4320
-
4321
- Return a JSON array where each element has:
4322
- - "index": the candidate's index number
4323
- - "score": relevance score 0-100
4324
- - "reason": one-liner explaining the score (max 80 chars)
4325
-
4326
- Be selective. Only score candidates that would genuinely help developers working on this project.
4327
- Return ONLY the JSON array.`;
4328
- var EXTRACT_CONFIG_PROMPT = `You extract MCP server configuration from a README file.
4329
-
4330
- Look for the MCP server's configuration block \u2014 typically a JSON snippet showing how to add it to claude_desktop_config.json, .mcp.json, or similar.
4331
-
4332
- Return a JSON object with:
4333
- - "command": the executable command (e.g., "npx", "uvx", "node", "docker")
4334
- - "args": array of arguments (e.g., ["-y", "@supabase/mcp-server"])
4335
- - "env": array of objects, each with:
4336
- - "key": environment variable name (e.g., "SUPABASE_ACCESS_TOKEN")
4337
- - "description": brief description of what this value is (e.g., "Personal access token from dashboard")
4338
- - "required": boolean
4339
-
4340
- If the README shows multiple configuration methods, prefer npx > uvx > node > docker.
4341
- If you cannot determine the configuration, return {"command": "", "args": [], "env": []}.
4342
- Return ONLY the JSON object.`;
4343
-
4344
- // src/mcp/validate.ts
4345
- var MIN_STARS = 100;
4346
- var MAX_AGE_DAYS = 180;
4347
- async function validateAndScore(candidates, toolDeps) {
4348
- const qualityFiltered = candidates.filter((c) => {
4349
- if (c.vendor) return true;
4350
- if (c.stars > 0 && c.stars < MIN_STARS) return false;
4351
- if (c.lastPush) {
4352
- const pushDate = new Date(c.lastPush);
4353
- const daysAgo = (Date.now() - pushDate.getTime()) / (1e3 * 60 * 60 * 24);
4354
- if (daysAgo > MAX_AGE_DAYS) return false;
4355
- }
4356
- return true;
4357
- });
4358
- if (qualityFiltered.length === 0) return [];
4359
- try {
4360
- return await scoreWithLLM(qualityFiltered, toolDeps);
4361
- } catch {
4362
- return qualityFiltered.slice(0, 5).map((c) => ({
4363
- ...c,
4364
- score: 50,
4365
- reason: c.description.slice(0, 80)
4366
- }));
4367
- }
4368
- }
4369
- async function scoreWithLLM(candidates, toolDeps) {
4370
- const candidateList = candidates.map((c, i) => {
4371
- const vendorTag = c.vendor ? " [VENDOR/OFFICIAL]" : "";
4372
- return `${i}. "${c.name}"${vendorTag} (${c.stars} stars) \u2014 ${c.description.slice(0, 100)}`;
4373
- }).join("\n");
4374
- const fastModel = getFastModel();
4375
- const scored = await llmJsonCall({
4376
- system: SCORE_MCP_PROMPT,
4377
- prompt: `TOOL DEPENDENCIES IN PROJECT:
4378
- ${toolDeps.join(", ")}
4379
-
4380
- MCP SERVER CANDIDATES:
4381
- ${candidateList}`,
4382
- maxTokens: 4e3,
4383
- ...fastModel ? { model: fastModel } : {}
4384
- });
4385
- if (!Array.isArray(scored)) return [];
4386
- return scored.filter((s) => s.score >= 60 && s.index >= 0 && s.index < candidates.length).sort((a, b) => b.score - a.score).slice(0, 5).map((s) => ({
4387
- ...candidates[s.index],
4388
- score: s.score,
4389
- reason: s.reason || candidates[s.index].description.slice(0, 80)
4390
- }));
4391
- }
4392
-
4393
- // src/mcp/config-extract.ts
4394
- async function fetchReadme(repoFullName) {
4395
- try {
4396
- const resp = await fetch(
4397
- `https://raw.githubusercontent.com/${repoFullName}/HEAD/README.md`,
4398
- { signal: AbortSignal.timeout(1e4) }
4399
- );
4400
- if (resp.ok) return await resp.text();
4401
- } catch {
4402
- }
4403
- try {
4404
- const resp = await fetch(
4405
- `https://raw.githubusercontent.com/${repoFullName}/main/README.md`,
4406
- { signal: AbortSignal.timeout(1e4) }
4407
- );
4408
- if (resp.ok) return await resp.text();
4409
- } catch {
4410
- }
4411
- return null;
4412
- }
4413
- async function extractMcpConfig(readme, serverName) {
4414
- try {
4415
- const truncated = readme.length > 15e3 ? readme.slice(0, 15e3) : readme;
4416
- const fastModel = getFastModel();
4417
- const result = await llmJsonCall({
4418
- system: EXTRACT_CONFIG_PROMPT,
4419
- prompt: `MCP Server: ${serverName}
4420
-
4421
- README:
4422
- ${truncated}`,
4423
- maxTokens: 2e3,
4424
- ...fastModel ? { model: fastModel } : {}
4425
- });
4426
- if (!result || !result.command) return null;
4427
- return {
4428
- command: result.command,
4429
- args: Array.isArray(result.args) ? result.args : [],
4430
- env: Array.isArray(result.env) ? result.env : []
4431
- };
4432
- } catch {
4433
- return null;
4434
- }
4435
- }
4436
-
4437
- // src/mcp/index.ts
4438
- async function discoverAndInstallMcps(targetAgent, fingerprint, dir) {
4439
- console.log(chalk5.hex("#6366f1").bold("\n MCP Server Discovery\n"));
4440
- const toolDeps = fingerprint.tools;
4441
- if (toolDeps.length === 0) {
4442
- console.log(chalk5.dim(" No external tools or services detected \u2014 skipping MCP discovery"));
4443
- return { installed: 0, names: [] };
4444
- }
4445
- const spinner = ora(`Searching MCP servers for ${toolDeps.length} detected tool${toolDeps.length === 1 ? "" : "s"}...`).start();
4446
- console.log(chalk5.dim(` Detected: ${toolDeps.join(", ")}`));
4447
- const existingMcps = getExistingMcpNames(fingerprint, targetAgent);
4448
- const filteredDeps = toolDeps.filter((d) => {
4449
- const lower = d.toLowerCase();
4450
- return !existingMcps.some((name) => name.includes(lower) || lower.includes(name));
4451
- });
4452
- if (filteredDeps.length === 0) {
4453
- spinner.succeed(chalk5.dim("All detected tools already have MCP servers configured"));
4454
- return { installed: 0, names: [] };
4455
- }
4456
- const candidates = await searchAllMcpSources(filteredDeps);
4457
- if (candidates.length === 0) {
4458
- spinner.succeed(chalk5.dim("No MCP servers found for detected tools"));
4459
- return { installed: 0, names: [] };
4460
- }
4461
- spinner.succeed(`Found ${candidates.length} candidate${candidates.length === 1 ? "" : "s"} for ${filteredDeps.join(", ")}`);
4462
- const scoreSpinner = ora("Scoring MCP candidates...").start();
4463
- const scored = await validateAndScore(candidates, filteredDeps);
4464
- if (scored.length === 0) {
4465
- scoreSpinner.succeed(chalk5.dim("No quality MCP servers passed validation"));
4466
- console.log(chalk5.dim(` Candidates checked: ${candidates.map((c) => c.name).join(", ")}`));
4467
- return { installed: 0, names: [] };
4468
- }
4469
- scoreSpinner.succeed(`${scored.length} quality MCP server${scored.length === 1 ? "" : "s"} found`);
4470
- console.log(chalk5.dim(` Scored: ${scored.map((c) => `${c.name} (${c.score})`).join(", ")}`));
4471
- const selected = await interactiveSelect(scored);
4472
- if (!selected || selected.length === 0) {
4473
- return { installed: 0, names: [] };
4474
- }
4475
- const mcpServers = {};
4476
- const installedNames = [];
4477
- for (const mcp of selected) {
4478
- console.log(chalk5.bold(`
4479
- Configuring ${mcp.name}...`));
4480
- const readme = await fetchReadme(mcp.repoFullName);
4481
- if (!readme) {
4482
- console.log(chalk5.yellow(` Could not fetch README for ${mcp.repoFullName} \u2014 skipping`));
4483
- console.log(chalk5.dim(` Manual setup: ${mcp.url}`));
4484
- continue;
4485
- }
4486
- const config = await extractMcpConfig(readme, mcp.name);
4487
- if (!config || !config.command) {
4488
- console.log(chalk5.yellow(` Could not extract config for ${mcp.name} \u2014 skipping`));
4489
- console.log(chalk5.dim(` Manual setup: ${mcp.url}`));
4490
- continue;
4491
- }
4492
- const env = {};
4493
- for (const envVar of config.env) {
4494
- if (!envVar.required) continue;
4495
- const value = await promptInput2(` ? ${envVar.key} (${envVar.description})`);
4496
- if (value) {
4497
- env[envVar.key] = value;
4498
- }
4499
- }
4500
- const serverConfig = {
4501
- command: config.command
4502
- };
4503
- if (config.args.length > 0) serverConfig.args = config.args;
4504
- if (Object.keys(env).length > 0) serverConfig.env = env;
4505
- mcpServers[mcp.name] = serverConfig;
4506
- installedNames.push(mcp.name);
4507
- console.log(` ${chalk5.green("\u2713")} ${mcp.name} configured`);
4508
- }
4509
- if (installedNames.length === 0) {
4510
- return { installed: 0, names: [] };
4511
- }
4512
- if (targetAgent.includes("claude") || targetAgent.includes("codex")) {
4513
- writeMcpJson(path16.join(dir, ".mcp.json"), mcpServers);
4514
- }
4515
- if (targetAgent.includes("cursor")) {
4516
- const cursorDir = path16.join(dir, ".cursor");
4517
- if (!fs20.existsSync(cursorDir)) fs20.mkdirSync(cursorDir, { recursive: true });
4518
- writeMcpJson(path16.join(cursorDir, "mcp.json"), mcpServers);
4519
- }
4520
- return { installed: installedNames.length, names: installedNames };
4521
- }
4522
- function writeMcpJson(filePath, mcpServers) {
4523
- let existing = {};
4524
- try {
4525
- if (fs20.existsSync(filePath)) {
4526
- const parsed = JSON.parse(fs20.readFileSync(filePath, "utf-8"));
4527
- if (parsed.mcpServers) existing = parsed.mcpServers;
4528
- }
4529
- } catch {
4530
- }
4531
- const merged = { ...existing, ...mcpServers };
4532
- fs20.writeFileSync(filePath, JSON.stringify({ mcpServers: merged }, null, 2) + "\n");
4533
- }
4534
- function getExistingMcpNames(fingerprint, targetAgent) {
4535
- const names = [];
4536
- if (targetAgent.includes("claude")) {
4537
- if (fingerprint.existingConfigs.claudeMcpServers) {
4538
- names.push(...Object.keys(fingerprint.existingConfigs.claudeMcpServers).map((k) => k.toLowerCase()));
4539
- }
4540
- }
4541
- if (targetAgent.includes("cursor")) {
4542
- if (fingerprint.existingConfigs.cursorMcpServers) {
4543
- names.push(...Object.keys(fingerprint.existingConfigs.cursorMcpServers).map((k) => k.toLowerCase()));
4544
- }
4545
- }
4546
- return names;
4547
- }
4548
- function promptInput2(question) {
4549
- const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
4550
- return new Promise((resolve2) => {
4551
- rl.question(chalk5.cyan(`${question}: `), (answer) => {
4552
- rl.close();
4553
- resolve2(answer.trim());
4554
- });
4555
- });
4556
- }
4557
- async function interactiveSelect(candidates) {
4558
- if (!process.stdin.isTTY) {
4559
- console.log(chalk5.bold("\n Available MCP servers:\n"));
4560
- for (const c of candidates) {
4561
- const vendorTag = c.vendor ? chalk5.blue(" (vendor)") : "";
4562
- console.log(` ${String(c.score).padStart(3)} ${c.name}${vendorTag} ${chalk5.dim(c.reason)}`);
4563
- }
4564
- console.log("");
4565
- return null;
4566
- }
4567
- const selected = /* @__PURE__ */ new Set();
4568
- let cursor = 0;
4569
- const { stdin, stdout } = process;
4570
- let lineCount = 0;
4571
- function render() {
4572
- const lines = [];
4573
- lines.push(chalk5.bold(" Select MCP servers to install:"));
4574
- lines.push("");
4575
- for (let i = 0; i < candidates.length; i++) {
4576
- const c = candidates[i];
4577
- const check = selected.has(i) ? chalk5.green("[x]") : "[ ]";
4578
- const ptr = i === cursor ? chalk5.cyan(">") : " ";
4579
- const scoreColor = c.score >= 90 ? chalk5.green : c.score >= 70 ? chalk5.yellow : chalk5.dim;
4580
- const vendorTag = c.vendor ? chalk5.blue(" (vendor)") : "";
4581
- lines.push(` ${ptr} ${check} ${scoreColor(String(c.score).padStart(3))} ${c.name}${vendorTag} ${chalk5.dim(c.reason.slice(0, 40))}`);
4582
- }
4583
- lines.push("");
4584
- lines.push(chalk5.dim(" \u2191\u2193 navigate \u23B5 toggle a all n none \u23CE install q skip"));
4585
- return lines.join("\n");
4586
- }
4587
- function draw(initial) {
4588
- if (!initial && lineCount > 0) {
4589
- stdout.write(`\x1B[${lineCount}A`);
4590
- }
4591
- stdout.write("\x1B[0J");
4592
- const output = render();
4593
- stdout.write(output + "\n");
4594
- lineCount = output.split("\n").length;
4595
- }
4596
- return new Promise((resolve2) => {
4597
- console.log("");
4598
- draw(true);
4599
- stdin.setRawMode(true);
4600
- stdin.resume();
4601
- stdin.setEncoding("utf8");
4602
- function cleanup() {
4603
- stdin.removeListener("data", onData);
4604
- stdin.setRawMode(false);
4605
- stdin.pause();
4606
- }
4607
- function onData(key) {
4608
- switch (key) {
4609
- case "\x1B[A":
4610
- cursor = (cursor - 1 + candidates.length) % candidates.length;
4611
- draw(false);
4612
- break;
4613
- case "\x1B[B":
4614
- cursor = (cursor + 1) % candidates.length;
4615
- draw(false);
4616
- break;
4617
- case " ":
4618
- selected.has(cursor) ? selected.delete(cursor) : selected.add(cursor);
4619
- draw(false);
4620
- break;
4621
- case "a":
4622
- candidates.forEach((_, i) => selected.add(i));
4623
- draw(false);
4624
- break;
4625
- case "n":
4626
- selected.clear();
4627
- draw(false);
4628
- break;
4629
- case "\r":
4630
- case "\n":
4631
- cleanup();
4632
- if (selected.size === 0) {
4633
- console.log(chalk5.dim("\n No MCP servers selected.\n"));
4634
- resolve2(null);
4635
- } else {
4636
- resolve2(Array.from(selected).sort().map((i) => candidates[i]));
4637
- }
4638
- break;
4639
- case "q":
4640
- case "\x1B":
4641
- case "":
4642
- cleanup();
4643
- console.log(chalk5.dim("\n Skipped MCP server installation.\n"));
4644
- resolve2(null);
4645
- break;
4646
- }
4647
- }
4648
- stdin.on("data", onData);
4649
- });
4650
- }
4651
-
4652
- // src/commands/recommend.ts
4653
- import chalk6 from "chalk";
4654
- import ora2 from "ora";
4655
4159
  import select3 from "@inquirer/select";
4656
4160
  import { mkdirSync, readFileSync as readFileSync7, readdirSync as readdirSync5, existsSync as existsSync9, writeFileSync } from "fs";
4657
4161
  import { join as join8, dirname as dirname2 } from "path";
4658
4162
 
4659
4163
  // src/scanner/index.ts
4660
- import fs21 from "fs";
4661
- import path17 from "path";
4164
+ import fs20 from "fs";
4165
+ import path16 from "path";
4662
4166
  import crypto2 from "crypto";
4663
4167
  function scanLocalState(dir) {
4664
4168
  const items = [];
4665
- const claudeMdPath = path17.join(dir, "CLAUDE.md");
4666
- if (fs21.existsSync(claudeMdPath)) {
4169
+ const claudeMdPath = path16.join(dir, "CLAUDE.md");
4170
+ if (fs20.existsSync(claudeMdPath)) {
4667
4171
  items.push({
4668
4172
  type: "rule",
4669
4173
  platform: "claude",
@@ -4672,10 +4176,10 @@ function scanLocalState(dir) {
4672
4176
  path: claudeMdPath
4673
4177
  });
4674
4178
  }
4675
- const skillsDir = path17.join(dir, ".claude", "skills");
4676
- if (fs21.existsSync(skillsDir)) {
4677
- for (const file of fs21.readdirSync(skillsDir).filter((f) => f.endsWith(".md"))) {
4678
- const filePath = path17.join(skillsDir, file);
4179
+ const skillsDir = path16.join(dir, ".claude", "skills");
4180
+ if (fs20.existsSync(skillsDir)) {
4181
+ for (const file of fs20.readdirSync(skillsDir).filter((f) => f.endsWith(".md"))) {
4182
+ const filePath = path16.join(skillsDir, file);
4679
4183
  items.push({
4680
4184
  type: "skill",
4681
4185
  platform: "claude",
@@ -4685,10 +4189,10 @@ function scanLocalState(dir) {
4685
4189
  });
4686
4190
  }
4687
4191
  }
4688
- const mcpJsonPath = path17.join(dir, ".mcp.json");
4689
- if (fs21.existsSync(mcpJsonPath)) {
4192
+ const mcpJsonPath = path16.join(dir, ".mcp.json");
4193
+ if (fs20.existsSync(mcpJsonPath)) {
4690
4194
  try {
4691
- const mcpJson = JSON.parse(fs21.readFileSync(mcpJsonPath, "utf-8"));
4195
+ const mcpJson = JSON.parse(fs20.readFileSync(mcpJsonPath, "utf-8"));
4692
4196
  if (mcpJson.mcpServers) {
4693
4197
  for (const name of Object.keys(mcpJson.mcpServers)) {
4694
4198
  items.push({
@@ -4703,8 +4207,8 @@ function scanLocalState(dir) {
4703
4207
  } catch {
4704
4208
  }
4705
4209
  }
4706
- const agentsMdPath = path17.join(dir, "AGENTS.md");
4707
- if (fs21.existsSync(agentsMdPath)) {
4210
+ const agentsMdPath = path16.join(dir, "AGENTS.md");
4211
+ if (fs20.existsSync(agentsMdPath)) {
4708
4212
  items.push({
4709
4213
  type: "rule",
4710
4214
  platform: "codex",
@@ -4713,12 +4217,12 @@ function scanLocalState(dir) {
4713
4217
  path: agentsMdPath
4714
4218
  });
4715
4219
  }
4716
- const codexSkillsDir = path17.join(dir, ".agents", "skills");
4717
- if (fs21.existsSync(codexSkillsDir)) {
4220
+ const codexSkillsDir = path16.join(dir, ".agents", "skills");
4221
+ if (fs20.existsSync(codexSkillsDir)) {
4718
4222
  try {
4719
- for (const name of fs21.readdirSync(codexSkillsDir)) {
4720
- const skillFile = path17.join(codexSkillsDir, name, "SKILL.md");
4721
- if (fs21.existsSync(skillFile)) {
4223
+ for (const name of fs20.readdirSync(codexSkillsDir)) {
4224
+ const skillFile = path16.join(codexSkillsDir, name, "SKILL.md");
4225
+ if (fs20.existsSync(skillFile)) {
4722
4226
  items.push({
4723
4227
  type: "skill",
4724
4228
  platform: "codex",
@@ -4731,8 +4235,8 @@ function scanLocalState(dir) {
4731
4235
  } catch {
4732
4236
  }
4733
4237
  }
4734
- const cursorrulesPath = path17.join(dir, ".cursorrules");
4735
- if (fs21.existsSync(cursorrulesPath)) {
4238
+ const cursorrulesPath = path16.join(dir, ".cursorrules");
4239
+ if (fs20.existsSync(cursorrulesPath)) {
4736
4240
  items.push({
4737
4241
  type: "rule",
4738
4242
  platform: "cursor",
@@ -4741,10 +4245,10 @@ function scanLocalState(dir) {
4741
4245
  path: cursorrulesPath
4742
4246
  });
4743
4247
  }
4744
- const cursorRulesDir = path17.join(dir, ".cursor", "rules");
4745
- if (fs21.existsSync(cursorRulesDir)) {
4746
- for (const file of fs21.readdirSync(cursorRulesDir).filter((f) => f.endsWith(".mdc"))) {
4747
- const filePath = path17.join(cursorRulesDir, file);
4248
+ const cursorRulesDir = path16.join(dir, ".cursor", "rules");
4249
+ if (fs20.existsSync(cursorRulesDir)) {
4250
+ for (const file of fs20.readdirSync(cursorRulesDir).filter((f) => f.endsWith(".mdc"))) {
4251
+ const filePath = path16.join(cursorRulesDir, file);
4748
4252
  items.push({
4749
4253
  type: "rule",
4750
4254
  platform: "cursor",
@@ -4754,12 +4258,12 @@ function scanLocalState(dir) {
4754
4258
  });
4755
4259
  }
4756
4260
  }
4757
- const cursorSkillsDir = path17.join(dir, ".cursor", "skills");
4758
- if (fs21.existsSync(cursorSkillsDir)) {
4261
+ const cursorSkillsDir = path16.join(dir, ".cursor", "skills");
4262
+ if (fs20.existsSync(cursorSkillsDir)) {
4759
4263
  try {
4760
- for (const name of fs21.readdirSync(cursorSkillsDir)) {
4761
- const skillFile = path17.join(cursorSkillsDir, name, "SKILL.md");
4762
- if (fs21.existsSync(skillFile)) {
4264
+ for (const name of fs20.readdirSync(cursorSkillsDir)) {
4265
+ const skillFile = path16.join(cursorSkillsDir, name, "SKILL.md");
4266
+ if (fs20.existsSync(skillFile)) {
4763
4267
  items.push({
4764
4268
  type: "skill",
4765
4269
  platform: "cursor",
@@ -4772,10 +4276,10 @@ function scanLocalState(dir) {
4772
4276
  } catch {
4773
4277
  }
4774
4278
  }
4775
- const cursorMcpPath = path17.join(dir, ".cursor", "mcp.json");
4776
- if (fs21.existsSync(cursorMcpPath)) {
4279
+ const cursorMcpPath = path16.join(dir, ".cursor", "mcp.json");
4280
+ if (fs20.existsSync(cursorMcpPath)) {
4777
4281
  try {
4778
- const mcpJson = JSON.parse(fs21.readFileSync(cursorMcpPath, "utf-8"));
4282
+ const mcpJson = JSON.parse(fs20.readFileSync(cursorMcpPath, "utf-8"));
4779
4283
  if (mcpJson.mcpServers) {
4780
4284
  for (const name of Object.keys(mcpJson.mcpServers)) {
4781
4285
  items.push({
@@ -4793,7 +4297,7 @@ function scanLocalState(dir) {
4793
4297
  return items;
4794
4298
  }
4795
4299
  function hashFile(filePath) {
4796
- const text = fs21.readFileSync(filePath, "utf-8");
4300
+ const text = fs20.readFileSync(filePath, "utf-8");
4797
4301
  return crypto2.createHash("sha256").update(JSON.stringify({ text })).digest("hex");
4798
4302
  }
4799
4303
  function hashJson(obj) {
@@ -4955,7 +4459,7 @@ async function searchAllProviders(technologies, platform) {
4955
4459
  }
4956
4460
  return combined;
4957
4461
  }
4958
- async function scoreWithLLM2(candidates, projectContext, technologies) {
4462
+ async function scoreWithLLM(candidates, projectContext, technologies) {
4959
4463
  const candidateList = candidates.map((c, i) => `${i}. "${c.name}" \u2014 ${c.reason || "no description"}`).join("\n");
4960
4464
  const fastModel = getFastModel();
4961
4465
  const scored = await llmJsonCall({
@@ -5108,7 +4612,7 @@ async function recommendCommand() {
5108
4612
  ]
5109
4613
  });
5110
4614
  if (!proceed) {
5111
- console.log(chalk6.dim(" Cancelled.\n"));
4615
+ console.log(chalk5.dim(" Cancelled.\n"));
5112
4616
  return;
5113
4617
  }
5114
4618
  await searchAndInstallSkills();
@@ -5123,11 +4627,11 @@ async function searchAndInstallSkills() {
5123
4627
  ...extractTopDeps()
5124
4628
  ].filter(Boolean))];
5125
4629
  if (technologies.length === 0) {
5126
- console.log(chalk6.yellow("Could not detect any languages or dependencies. Try running from a project root."));
4630
+ console.log(chalk5.yellow("Could not detect any languages or dependencies. Try running from a project root."));
5127
4631
  throw new Error("__exit__");
5128
4632
  }
5129
4633
  const primaryPlatform = platforms.includes("claude") ? "claude" : platforms[0];
5130
- const searchSpinner = ora2("Searching skill registries...").start();
4634
+ const searchSpinner = ora("Searching skill registries...").start();
5131
4635
  const allCandidates = await searchAllProviders(technologies, primaryPlatform);
5132
4636
  if (!allCandidates.length) {
5133
4637
  searchSpinner.succeed("No skills found matching your tech stack.");
@@ -5140,15 +4644,15 @@ async function searchAndInstallSkills() {
5140
4644
  return;
5141
4645
  }
5142
4646
  searchSpinner.succeed(
5143
- `Found ${allCandidates.length} skills` + (filteredCount > 0 ? chalk6.dim(` (${filteredCount} already installed)`) : "")
4647
+ `Found ${allCandidates.length} skills` + (filteredCount > 0 ? chalk5.dim(` (${filteredCount} already installed)`) : "")
5144
4648
  );
5145
4649
  let results;
5146
4650
  const config = loadConfig();
5147
4651
  if (config) {
5148
- const scoreSpinner = ora2("Scoring relevance for your project...").start();
4652
+ const scoreSpinner = ora("Scoring relevance for your project...").start();
5149
4653
  try {
5150
4654
  const projectContext = buildProjectContext(fingerprint);
5151
- results = await scoreWithLLM2(newCandidates, projectContext, technologies);
4655
+ results = await scoreWithLLM(newCandidates, projectContext, technologies);
5152
4656
  if (results.length === 0) {
5153
4657
  scoreSpinner.succeed("No highly relevant skills found for your specific project.");
5154
4658
  return;
@@ -5161,7 +4665,7 @@ async function searchAndInstallSkills() {
5161
4665
  } else {
5162
4666
  results = newCandidates.slice(0, 20);
5163
4667
  }
5164
- const fetchSpinner = ora2("Verifying skill availability...").start();
4668
+ const fetchSpinner = ora("Verifying skill availability...").start();
5165
4669
  const contentMap = /* @__PURE__ */ new Map();
5166
4670
  await Promise.all(results.map(async (rec) => {
5167
4671
  const content = await fetchSkillContent(rec);
@@ -5174,14 +4678,14 @@ async function searchAndInstallSkills() {
5174
4678
  }
5175
4679
  const unavailableCount = results.length - available.length;
5176
4680
  fetchSpinner.succeed(
5177
- `${available.length} installable skill${available.length > 1 ? "s" : ""}` + (unavailableCount > 0 ? chalk6.dim(` (${unavailableCount} unavailable)`) : "")
4681
+ `${available.length} installable skill${available.length > 1 ? "s" : ""}` + (unavailableCount > 0 ? chalk5.dim(` (${unavailableCount} unavailable)`) : "")
5178
4682
  );
5179
- const selected = await interactiveSelect2(available);
4683
+ const selected = await interactiveSelect(available);
5180
4684
  if (selected?.length) {
5181
4685
  await installSkills(selected, platforms, contentMap);
5182
4686
  }
5183
4687
  }
5184
- async function interactiveSelect2(recs) {
4688
+ async function interactiveSelect(recs) {
5185
4689
  if (!process.stdin.isTTY) {
5186
4690
  printSkills(recs);
5187
4691
  return null;
@@ -5197,30 +4701,30 @@ async function interactiveSelect2(recs) {
5197
4701
  const nameWidth = Math.max(...recs.map((r) => r.name.length), 4) + 2;
5198
4702
  const prefixWidth = 8;
5199
4703
  const scoreWidth = 6;
5200
- lines.push(chalk6.bold(" Skills"));
4704
+ lines.push(chalk5.bold(" Skills"));
5201
4705
  lines.push("");
5202
4706
  if (hasScores) {
5203
- const header = " ".repeat(prefixWidth) + chalk6.dim("Score".padEnd(scoreWidth)) + chalk6.dim("Name".padEnd(nameWidth)) + chalk6.dim("Why");
4707
+ const header = " ".repeat(prefixWidth) + chalk5.dim("Score".padEnd(scoreWidth)) + chalk5.dim("Name".padEnd(nameWidth)) + chalk5.dim("Why");
5204
4708
  lines.push(header);
5205
4709
  } else {
5206
- const header = " ".repeat(prefixWidth) + chalk6.dim("Name".padEnd(nameWidth)) + chalk6.dim("Technology".padEnd(18)) + chalk6.dim("Source");
4710
+ const header = " ".repeat(prefixWidth) + chalk5.dim("Name".padEnd(nameWidth)) + chalk5.dim("Technology".padEnd(18)) + chalk5.dim("Source");
5207
4711
  lines.push(header);
5208
4712
  }
5209
- lines.push(chalk6.dim(" " + "\u2500".repeat(Math.min(cols - 4, 90))));
4713
+ lines.push(chalk5.dim(" " + "\u2500".repeat(Math.min(cols - 4, 90))));
5210
4714
  for (let i = 0; i < recs.length; i++) {
5211
4715
  const rec = recs[i];
5212
- const check = selected.has(i) ? chalk6.green("[x]") : "[ ]";
5213
- const ptr = i === cursor ? chalk6.cyan(">") : " ";
4716
+ const check = selected.has(i) ? chalk5.green("[x]") : "[ ]";
4717
+ const ptr = i === cursor ? chalk5.cyan(">") : " ";
5214
4718
  if (hasScores) {
5215
- const scoreColor = rec.score >= 90 ? chalk6.green : rec.score >= 70 ? chalk6.yellow : chalk6.dim;
4719
+ const scoreColor = rec.score >= 90 ? chalk5.green : rec.score >= 70 ? chalk5.yellow : chalk5.dim;
5216
4720
  const reasonMax = Math.max(cols - prefixWidth - scoreWidth - nameWidth - 2, 20);
5217
- lines.push(` ${ptr} ${check} ${scoreColor(String(rec.score).padStart(3))} ${rec.name.padEnd(nameWidth)}${chalk6.dim(rec.reason.slice(0, reasonMax))}`);
4721
+ lines.push(` ${ptr} ${check} ${scoreColor(String(rec.score).padStart(3))} ${rec.name.padEnd(nameWidth)}${chalk5.dim(rec.reason.slice(0, reasonMax))}`);
5218
4722
  } else {
5219
- lines.push(` ${ptr} ${check} ${rec.name.padEnd(nameWidth)}${rec.detected_technology.padEnd(16)} ${chalk6.dim(rec.source_url || "")}`);
4723
+ lines.push(` ${ptr} ${check} ${rec.name.padEnd(nameWidth)}${rec.detected_technology.padEnd(16)} ${chalk5.dim(rec.source_url || "")}`);
5220
4724
  }
5221
4725
  }
5222
4726
  lines.push("");
5223
- lines.push(chalk6.dim(" \u2191\u2193 navigate \u23B5 toggle a all n none \u23CE install q cancel"));
4727
+ lines.push(chalk5.dim(" \u2191\u2193 navigate \u23B5 toggle a all n none \u23CE install q cancel"));
5224
4728
  return lines.join("\n");
5225
4729
  }
5226
4730
  function draw(initial) {
@@ -5269,7 +4773,7 @@ async function interactiveSelect2(recs) {
5269
4773
  case "\n":
5270
4774
  cleanup();
5271
4775
  if (selected.size === 0) {
5272
- console.log(chalk6.dim("\n No skills selected.\n"));
4776
+ console.log(chalk5.dim("\n No skills selected.\n"));
5273
4777
  resolve2(null);
5274
4778
  } else {
5275
4779
  resolve2(Array.from(selected).sort().map((i) => recs[i]));
@@ -5279,7 +4783,7 @@ async function interactiveSelect2(recs) {
5279
4783
  case "\x1B":
5280
4784
  case "":
5281
4785
  cleanup();
5282
- console.log(chalk6.dim("\n Cancelled.\n"));
4786
+ console.log(chalk5.dim("\n Cancelled.\n"));
5283
4787
  resolve2(null);
5284
4788
  break;
5285
4789
  }
@@ -5326,7 +4830,7 @@ async function fetchSkillContent(rec) {
5326
4830
  return null;
5327
4831
  }
5328
4832
  async function installSkills(recs, platforms, contentMap) {
5329
- const spinner = ora2(`Installing ${recs.length} skill${recs.length > 1 ? "s" : ""}...`).start();
4833
+ const spinner = ora(`Installing ${recs.length} skill${recs.length > 1 ? "s" : ""}...`).start();
5330
4834
  const installed = [];
5331
4835
  for (const rec of recs) {
5332
4836
  const content = contentMap.get(rec.slug);
@@ -5342,7 +4846,7 @@ async function installSkills(recs, platforms, contentMap) {
5342
4846
  if (installed.length > 0) {
5343
4847
  spinner.succeed(`Installed ${installed.length} file${installed.length > 1 ? "s" : ""}`);
5344
4848
  for (const p of installed) {
5345
- console.log(chalk6.green(` \u2713 ${p}`));
4849
+ console.log(chalk5.green(` \u2713 ${p}`));
5346
4850
  }
5347
4851
  } else {
5348
4852
  spinner.fail("No skills were installed");
@@ -5355,19 +4859,19 @@ function printSkills(recs) {
5355
4859
  const nameWidth = Math.max(...recs.map((r) => r.name.length), 4) + 2;
5356
4860
  const scoreWidth = 6;
5357
4861
  const prefixWidth = 2;
5358
- console.log(chalk6.bold("\n Skills\n"));
4862
+ console.log(chalk5.bold("\n Skills\n"));
5359
4863
  if (hasScores) {
5360
- console.log(" ".repeat(prefixWidth) + chalk6.dim("Score".padEnd(scoreWidth)) + chalk6.dim("Name".padEnd(nameWidth)) + chalk6.dim("Why"));
4864
+ console.log(" ".repeat(prefixWidth) + chalk5.dim("Score".padEnd(scoreWidth)) + chalk5.dim("Name".padEnd(nameWidth)) + chalk5.dim("Why"));
5361
4865
  } else {
5362
- console.log(" ".repeat(prefixWidth) + chalk6.dim("Name".padEnd(nameWidth)) + chalk6.dim("Technology".padEnd(18)) + chalk6.dim("Source"));
4866
+ console.log(" ".repeat(prefixWidth) + chalk5.dim("Name".padEnd(nameWidth)) + chalk5.dim("Technology".padEnd(18)) + chalk5.dim("Source"));
5363
4867
  }
5364
- console.log(chalk6.dim(" " + "\u2500".repeat(Math.min(cols - 4, 90))));
4868
+ console.log(chalk5.dim(" " + "\u2500".repeat(Math.min(cols - 4, 90))));
5365
4869
  for (const rec of recs) {
5366
4870
  if (hasScores) {
5367
4871
  const reasonMax = Math.max(cols - prefixWidth - scoreWidth - nameWidth - 2, 20);
5368
- console.log(` ${String(rec.score).padStart(3)} ${rec.name.padEnd(nameWidth)}${chalk6.dim(rec.reason.slice(0, reasonMax))}`);
4872
+ console.log(` ${String(rec.score).padStart(3)} ${rec.name.padEnd(nameWidth)}${chalk5.dim(rec.reason.slice(0, reasonMax))}`);
5369
4873
  } else {
5370
- console.log(` ${rec.name.padEnd(nameWidth)}${rec.detected_technology.padEnd(16)} ${chalk6.dim(rec.source_url || "")}`);
4874
+ console.log(` ${rec.name.padEnd(nameWidth)}${rec.detected_technology.padEnd(16)} ${chalk5.dim(rec.source_url || "")}`);
5371
4875
  }
5372
4876
  }
5373
4877
  console.log("");
@@ -5375,8 +4879,8 @@ function printSkills(recs) {
5375
4879
 
5376
4880
  // src/commands/onboard.ts
5377
4881
  async function initCommand(options) {
5378
- const brand = chalk7.hex("#EB9D83");
5379
- const title = chalk7.hex("#83D1EB");
4882
+ const brand = chalk6.hex("#EB9D83");
4883
+ const title = chalk6.hex("#83D1EB");
5380
4884
  console.log(brand.bold(`
5381
4885
  \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557
5382
4886
  \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557
@@ -5385,21 +4889,21 @@ async function initCommand(options) {
5385
4889
  \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551
5386
4890
  \u255A\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D
5387
4891
  `));
5388
- console.log(chalk7.dim(" Onboard your project for AI-assisted development\n"));
4892
+ console.log(chalk6.dim(" Onboard your project for AI-assisted development\n"));
5389
4893
  console.log(title.bold(" Welcome to Caliber\n"));
5390
- console.log(chalk7.dim(" Caliber analyzes your codebase and creates tailored config files"));
5391
- console.log(chalk7.dim(" so your AI coding agents understand your project from day one.\n"));
4894
+ console.log(chalk6.dim(" Caliber analyzes your codebase and creates tailored config files"));
4895
+ console.log(chalk6.dim(" so your AI coding agents understand your project from day one.\n"));
5392
4896
  console.log(title.bold(" How onboarding works:\n"));
5393
- console.log(chalk7.dim(" 1. Connect Set up your LLM provider"));
5394
- console.log(chalk7.dim(" 2. Discover Analyze your code, dependencies, and structure"));
5395
- console.log(chalk7.dim(" 3. Generate Create config files tailored to your project"));
5396
- console.log(chalk7.dim(" 4. Review Preview, refine, and apply the changes"));
5397
- console.log(chalk7.dim(" 5. Enhance Discover MCP servers for your tools"));
5398
- console.log(chalk7.dim(" 6. Skills Browse community skills for your stack\n"));
4897
+ console.log(chalk6.dim(" 1. Connect Set up your LLM provider"));
4898
+ console.log(chalk6.dim(" 2. Discover Analyze your code, dependencies, and structure"));
4899
+ console.log(chalk6.dim(" 3. Generate Create config files tailored to your project"));
4900
+ console.log(chalk6.dim(" 4. Review Preview, refine, and apply the changes"));
4901
+ console.log(chalk6.dim(" 5. Enhance Discover MCP servers for your tools"));
4902
+ console.log(chalk6.dim(" 6. Skills Browse community skills for your stack\n"));
5399
4903
  console.log(title.bold(" Step 1/6 \u2014 Connect your LLM\n"));
5400
4904
  let config = loadConfig();
5401
4905
  if (!config) {
5402
- console.log(chalk7.dim(" No LLM provider set yet. Choose how to run Caliber:\n"));
4906
+ console.log(chalk6.dim(" No LLM provider set yet. Choose how to run Caliber:\n"));
5403
4907
  try {
5404
4908
  await runInteractiveProviderSetup({
5405
4909
  selectMessage: "How do you want to use Caliber? (choose LLM provider)"
@@ -5410,22 +4914,22 @@ async function initCommand(options) {
5410
4914
  }
5411
4915
  config = loadConfig();
5412
4916
  if (!config) {
5413
- console.log(chalk7.red(" Setup was cancelled or failed.\n"));
4917
+ console.log(chalk6.red(" Setup was cancelled or failed.\n"));
5414
4918
  throw new Error("__exit__");
5415
4919
  }
5416
- console.log(chalk7.green(" \u2713 Provider saved. Let's continue.\n"));
4920
+ console.log(chalk6.green(" \u2713 Provider saved. Let's continue.\n"));
5417
4921
  }
5418
4922
  const displayModel = config.model === "default" && config.provider === "claude-cli" ? process.env.ANTHROPIC_MODEL || "default (inherited from Claude Code)" : config.model;
5419
4923
  const fastModel = getFastModel();
5420
4924
  const modelLine = fastModel ? ` Provider: ${config.provider} | Model: ${displayModel} | Scan: ${fastModel}` : ` Provider: ${config.provider} | Model: ${displayModel}`;
5421
- console.log(chalk7.dim(modelLine + "\n"));
4925
+ console.log(chalk6.dim(modelLine + "\n"));
5422
4926
  console.log(title.bold(" Step 2/6 \u2014 Discover your project\n"));
5423
- console.log(chalk7.dim(" Learning about your languages, dependencies, structure, and existing configs.\n"));
5424
- const spinner = ora3("Analyzing project...").start();
4927
+ console.log(chalk6.dim(" Learning about your languages, dependencies, structure, and existing configs.\n"));
4928
+ const spinner = ora2("Analyzing project...").start();
5425
4929
  const fingerprint = await collectFingerprint(process.cwd());
5426
4930
  spinner.succeed("Project analyzed");
5427
- console.log(chalk7.dim(` Languages: ${fingerprint.languages.join(", ") || "none detected"}`));
5428
- console.log(chalk7.dim(` Files: ${fingerprint.fileTree.length} found
4931
+ console.log(chalk6.dim(` Languages: ${fingerprint.languages.join(", ") || "none detected"}`));
4932
+ console.log(chalk6.dim(` Files: ${fingerprint.fileTree.length} found
5429
4933
  `));
5430
4934
  const targetAgent = options.agent || await promptAgent();
5431
4935
  const preScore = computeLocalScore(process.cwd(), targetAgent);
@@ -5444,28 +4948,28 @@ async function initCommand(options) {
5444
4948
  const hasExistingConfig = !!(fingerprint.existingConfigs.claudeMd || fingerprint.existingConfigs.claudeSettings || fingerprint.existingConfigs.claudeSkills?.length || fingerprint.existingConfigs.cursorrules || fingerprint.existingConfigs.cursorRules?.length || fingerprint.existingConfigs.agentsMd);
5445
4949
  const NON_LLM_CHECKS = /* @__PURE__ */ new Set(["hooks_configured", "agents_md_exists", "permissions_configured", "mcp_servers"]);
5446
4950
  if (hasExistingConfig && baselineScore.score === 100) {
5447
- console.log(chalk7.bold.green(" Your setup is already optimal \u2014 nothing to change.\n"));
5448
- console.log(chalk7.dim(" Run ") + chalk7.hex("#83D1EB")("caliber onboard --force") + chalk7.dim(" to regenerate anyway.\n"));
4951
+ console.log(chalk6.bold.green(" Your setup is already optimal \u2014 nothing to change.\n"));
4952
+ console.log(chalk6.dim(" Run ") + chalk6.hex("#83D1EB")("caliber onboard --force") + chalk6.dim(" to regenerate anyway.\n"));
5449
4953
  if (!options.force) return;
5450
4954
  }
5451
4955
  const allFailingChecks = baselineScore.checks.filter((c) => !c.passed && c.maxPoints > 0);
5452
4956
  const llmFixableChecks = allFailingChecks.filter((c) => !NON_LLM_CHECKS.has(c.id));
5453
4957
  if (hasExistingConfig && llmFixableChecks.length === 0 && allFailingChecks.length > 0 && !options.force) {
5454
- console.log(chalk7.bold.green("\n Your config is fully optimized for LLM generation.\n"));
5455
- console.log(chalk7.dim(" Remaining items need CLI actions:\n"));
4958
+ console.log(chalk6.bold.green("\n Your config is fully optimized for LLM generation.\n"));
4959
+ console.log(chalk6.dim(" Remaining items need CLI actions:\n"));
5456
4960
  for (const check of allFailingChecks) {
5457
- console.log(chalk7.dim(` \u2022 ${check.name}`));
4961
+ console.log(chalk6.dim(` \u2022 ${check.name}`));
5458
4962
  if (check.suggestion) {
5459
- console.log(` ${chalk7.hex("#83D1EB")(check.suggestion)}`);
4963
+ console.log(` ${chalk6.hex("#83D1EB")(check.suggestion)}`);
5460
4964
  }
5461
4965
  }
5462
4966
  console.log("");
5463
- console.log(chalk7.dim(" Run ") + chalk7.hex("#83D1EB")("caliber onboard --force") + chalk7.dim(" to regenerate anyway.\n"));
4967
+ console.log(chalk6.dim(" Run ") + chalk6.hex("#83D1EB")("caliber onboard --force") + chalk6.dim(" to regenerate anyway.\n"));
5464
4968
  return;
5465
4969
  }
5466
4970
  const isEmpty = fingerprint.fileTree.length < 3;
5467
4971
  if (isEmpty) {
5468
- fingerprint.description = await promptInput3("What will you build in this project?");
4972
+ fingerprint.description = await promptInput2("What will you build in this project?");
5469
4973
  }
5470
4974
  let failingChecks;
5471
4975
  let passingChecks;
@@ -5476,24 +4980,24 @@ async function initCommand(options) {
5476
4980
  currentScore = baselineScore.score;
5477
4981
  if (failingChecks.length > 0) {
5478
4982
  console.log(title.bold(" Step 3/6 \u2014 Fine-tuning\n"));
5479
- console.log(chalk7.dim(` Your setup scores ${baselineScore.score}/100 \u2014 fixing ${failingChecks.length} remaining issue${failingChecks.length === 1 ? "" : "s"}:
4983
+ console.log(chalk6.dim(` Your setup scores ${baselineScore.score}/100 \u2014 fixing ${failingChecks.length} remaining issue${failingChecks.length === 1 ? "" : "s"}:
5480
4984
  `));
5481
4985
  for (const check of failingChecks) {
5482
- console.log(chalk7.dim(` \u2022 ${check.name}`));
4986
+ console.log(chalk6.dim(` \u2022 ${check.name}`));
5483
4987
  }
5484
4988
  console.log("");
5485
4989
  }
5486
4990
  } else if (hasExistingConfig) {
5487
4991
  console.log(title.bold(" Step 3/6 \u2014 Improve your setup\n"));
5488
- console.log(chalk7.dim(" Reviewing your existing configs against your codebase"));
5489
- console.log(chalk7.dim(" and preparing improvements.\n"));
4992
+ console.log(chalk6.dim(" Reviewing your existing configs against your codebase"));
4993
+ console.log(chalk6.dim(" and preparing improvements.\n"));
5490
4994
  } else {
5491
4995
  console.log(title.bold(" Step 3/6 \u2014 Build your agent setup\n"));
5492
- console.log(chalk7.dim(" Creating config files tailored to your project.\n"));
4996
+ console.log(chalk6.dim(" Creating config files tailored to your project.\n"));
5493
4997
  }
5494
- console.log(chalk7.dim(" This can take a couple of minutes depending on your model and provider.\n"));
4998
+ console.log(chalk6.dim(" This can take a couple of minutes depending on your model and provider.\n"));
5495
4999
  const genStartTime = Date.now();
5496
- const genSpinner = ora3("Generating setup...").start();
5000
+ const genSpinner = ora2("Generating setup...").start();
5497
5001
  const genMessages = new SpinnerMessages(genSpinner, GENERATION_MESSAGES, { showElapsedTime: true });
5498
5002
  genMessages.start();
5499
5003
  let generatedSetup = null;
@@ -5533,8 +5037,8 @@ async function initCommand(options) {
5533
5037
  if (!generatedSetup) {
5534
5038
  genSpinner.fail("Failed to generate setup.");
5535
5039
  if (rawOutput) {
5536
- console.log(chalk7.dim("\nRaw LLM output (JSON parse failed):"));
5537
- console.log(chalk7.dim(rawOutput.slice(0, 500)));
5040
+ console.log(chalk6.dim("\nRaw LLM output (JSON parse failed):"));
5041
+ console.log(chalk6.dim(rawOutput.slice(0, 500)));
5538
5042
  }
5539
5043
  throw new Error("__exit__");
5540
5044
  }
@@ -5542,7 +5046,7 @@ async function initCommand(options) {
5542
5046
  const mins = Math.floor(elapsedMs / 6e4);
5543
5047
  const secs = Math.floor(elapsedMs % 6e4 / 1e3);
5544
5048
  const timeStr = mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;
5545
- genSpinner.succeed(`Setup generated ${chalk7.dim(`in ${timeStr}`)}`);
5049
+ genSpinner.succeed(`Setup generated ${chalk6.dim(`in ${timeStr}`)}`);
5546
5050
  printSetupSummary(generatedSetup);
5547
5051
  const sessionHistory = [];
5548
5052
  sessionHistory.push({
@@ -5553,11 +5057,11 @@ async function initCommand(options) {
5553
5057
  const setupFiles = collectSetupFiles(generatedSetup);
5554
5058
  const staged = stageFiles(setupFiles, process.cwd());
5555
5059
  const totalChanges = staged.newFiles + staged.modifiedFiles;
5556
- console.log(chalk7.dim(` ${chalk7.green(`${staged.newFiles} new`)} / ${chalk7.yellow(`${staged.modifiedFiles} modified`)} file${totalChanges !== 1 ? "s" : ""}
5060
+ console.log(chalk6.dim(` ${chalk6.green(`${staged.newFiles} new`)} / ${chalk6.yellow(`${staged.modifiedFiles} modified`)} file${totalChanges !== 1 ? "s" : ""}
5557
5061
  `));
5558
5062
  let action;
5559
5063
  if (totalChanges === 0) {
5560
- console.log(chalk7.dim(" No changes needed \u2014 your configs are already up to date.\n"));
5064
+ console.log(chalk6.dim(" No changes needed \u2014 your configs are already up to date.\n"));
5561
5065
  cleanupStaging();
5562
5066
  action = "accept";
5563
5067
  } else {
@@ -5572,12 +5076,12 @@ async function initCommand(options) {
5572
5076
  generatedSetup = await refineLoop(generatedSetup, targetAgent, sessionHistory);
5573
5077
  if (!generatedSetup) {
5574
5078
  cleanupStaging();
5575
- console.log(chalk7.dim("Refinement cancelled. No files were modified."));
5079
+ console.log(chalk6.dim("Refinement cancelled. No files were modified."));
5576
5080
  return;
5577
5081
  }
5578
5082
  const updatedFiles = collectSetupFiles(generatedSetup);
5579
5083
  const restaged = stageFiles(updatedFiles, process.cwd());
5580
- console.log(chalk7.dim(` ${chalk7.green(`${restaged.newFiles} new`)} / ${chalk7.yellow(`${restaged.modifiedFiles} modified`)} file${restaged.newFiles + restaged.modifiedFiles !== 1 ? "s" : ""}
5084
+ console.log(chalk6.dim(` ${chalk6.green(`${restaged.newFiles} new`)} / ${chalk6.yellow(`${restaged.modifiedFiles} modified`)} file${restaged.newFiles + restaged.modifiedFiles !== 1 ? "s" : ""}
5581
5085
  `));
5582
5086
  printSetupSummary(generatedSetup);
5583
5087
  await openReview("terminal", restaged.stagedFiles);
@@ -5585,56 +5089,37 @@ async function initCommand(options) {
5585
5089
  }
5586
5090
  cleanupStaging();
5587
5091
  if (action === "decline") {
5588
- console.log(chalk7.dim("Setup declined. No files were modified."));
5092
+ console.log(chalk6.dim("Setup declined. No files were modified."));
5589
5093
  return;
5590
5094
  }
5591
5095
  if (options.dryRun) {
5592
- console.log(chalk7.yellow("\n[Dry run] Would write the following files:"));
5096
+ console.log(chalk6.yellow("\n[Dry run] Would write the following files:"));
5593
5097
  console.log(JSON.stringify(generatedSetup, null, 2));
5594
5098
  return;
5595
5099
  }
5596
- const writeSpinner = ora3("Writing config files...").start();
5100
+ const writeSpinner = ora2("Writing config files...").start();
5597
5101
  try {
5598
5102
  const result = writeSetup(generatedSetup);
5599
5103
  writeSpinner.succeed("Config files written");
5600
- console.log(chalk7.bold("\nFiles created/updated:"));
5104
+ console.log(chalk6.bold("\nFiles created/updated:"));
5601
5105
  for (const file of result.written) {
5602
- console.log(` ${chalk7.green("\u2713")} ${file}`);
5106
+ console.log(` ${chalk6.green("\u2713")} ${file}`);
5603
5107
  }
5604
5108
  if (result.deleted.length > 0) {
5605
- console.log(chalk7.bold("\nFiles removed:"));
5109
+ console.log(chalk6.bold("\nFiles removed:"));
5606
5110
  for (const file of result.deleted) {
5607
- console.log(` ${chalk7.red("\u2717")} ${file}`);
5111
+ console.log(` ${chalk6.red("\u2717")} ${file}`);
5608
5112
  }
5609
5113
  }
5610
5114
  if (result.backupDir) {
5611
- console.log(chalk7.dim(`
5115
+ console.log(chalk6.dim(`
5612
5116
  Backups saved to ${result.backupDir}`));
5613
5117
  }
5614
5118
  } catch (err) {
5615
5119
  writeSpinner.fail("Failed to write files");
5616
- console.error(chalk7.red(err instanceof Error ? err.message : "Unknown error"));
5120
+ console.error(chalk6.red(err instanceof Error ? err.message : "Unknown error"));
5617
5121
  throw new Error("__exit__");
5618
5122
  }
5619
- console.log(title.bold("\n Step 5/6 \u2014 Enhance with MCP servers\n"));
5620
- console.log(chalk7.dim(" MCP servers connect your AI agents to external tools and services"));
5621
- console.log(chalk7.dim(" like databases, APIs, and platforms your project depends on.\n"));
5622
- if (fingerprint.tools.length > 0) {
5623
- try {
5624
- const mcpResult = await discoverAndInstallMcps(targetAgent, fingerprint, process.cwd());
5625
- if (mcpResult.installed > 0) {
5626
- console.log(chalk7.bold(`
5627
- ${mcpResult.installed} MCP server${mcpResult.installed > 1 ? "s" : ""} configured`));
5628
- for (const name of mcpResult.names) {
5629
- console.log(` ${chalk7.green("\u2713")} ${name}`);
5630
- }
5631
- }
5632
- } catch (err) {
5633
- console.log(chalk7.dim(" MCP discovery skipped: " + (err instanceof Error ? err.message : "unknown error")));
5634
- }
5635
- } else {
5636
- console.log(chalk7.dim(" No external tools or services detected \u2014 skipping MCP discovery.\n"));
5637
- }
5638
5123
  ensurePermissions();
5639
5124
  const sha = getCurrentHeadSha();
5640
5125
  writeState({
@@ -5644,55 +5129,55 @@ async function initCommand(options) {
5644
5129
  });
5645
5130
  console.log("");
5646
5131
  console.log(title.bold(" Keep your configs fresh\n"));
5647
- console.log(chalk7.dim(" Caliber can automatically update your agent configs when your code changes.\n"));
5132
+ console.log(chalk6.dim(" Caliber can automatically update your agent configs when your code changes.\n"));
5648
5133
  const hookChoice = await promptHookType(targetAgent);
5649
5134
  if (hookChoice === "claude" || hookChoice === "both") {
5650
5135
  const hookResult = installHook();
5651
5136
  if (hookResult.installed) {
5652
- console.log(` ${chalk7.green("\u2713")} Claude Code hook installed \u2014 docs update on session end`);
5653
- console.log(chalk7.dim(" Run ") + chalk7.hex("#83D1EB")("caliber hooks --remove") + chalk7.dim(" to disable"));
5137
+ console.log(` ${chalk6.green("\u2713")} Claude Code hook installed \u2014 docs update on session end`);
5138
+ console.log(chalk6.dim(" Run ") + chalk6.hex("#83D1EB")("caliber hooks --remove") + chalk6.dim(" to disable"));
5654
5139
  } else if (hookResult.alreadyInstalled) {
5655
- console.log(chalk7.dim(" Claude Code hook already installed"));
5140
+ console.log(chalk6.dim(" Claude Code hook already installed"));
5656
5141
  }
5657
5142
  const learnResult = installLearningHooks();
5658
5143
  if (learnResult.installed) {
5659
- console.log(` ${chalk7.green("\u2713")} Learning hooks installed \u2014 session insights captured automatically`);
5660
- console.log(chalk7.dim(" Run ") + chalk7.hex("#83D1EB")("caliber learn remove") + chalk7.dim(" to disable"));
5144
+ console.log(` ${chalk6.green("\u2713")} Learning hooks installed \u2014 session insights captured automatically`);
5145
+ console.log(chalk6.dim(" Run ") + chalk6.hex("#83D1EB")("caliber learn remove") + chalk6.dim(" to disable"));
5661
5146
  } else if (learnResult.alreadyInstalled) {
5662
- console.log(chalk7.dim(" Learning hooks already installed"));
5147
+ console.log(chalk6.dim(" Learning hooks already installed"));
5663
5148
  }
5664
5149
  }
5665
5150
  if (hookChoice === "precommit" || hookChoice === "both") {
5666
5151
  const precommitResult = installPreCommitHook();
5667
5152
  if (precommitResult.installed) {
5668
- console.log(` ${chalk7.green("\u2713")} Pre-commit hook installed \u2014 docs refresh before each commit`);
5669
- console.log(chalk7.dim(" Run ") + chalk7.hex("#83D1EB")("caliber hooks --remove") + chalk7.dim(" to disable"));
5153
+ console.log(` ${chalk6.green("\u2713")} Pre-commit hook installed \u2014 docs refresh before each commit`);
5154
+ console.log(chalk6.dim(" Run ") + chalk6.hex("#83D1EB")("caliber hooks --remove") + chalk6.dim(" to disable"));
5670
5155
  } else if (precommitResult.alreadyInstalled) {
5671
- console.log(chalk7.dim(" Pre-commit hook already installed"));
5156
+ console.log(chalk6.dim(" Pre-commit hook already installed"));
5672
5157
  } else {
5673
- console.log(chalk7.yellow(" Could not install pre-commit hook (not a git repository?)"));
5158
+ console.log(chalk6.yellow(" Could not install pre-commit hook (not a git repository?)"));
5674
5159
  }
5675
5160
  }
5676
5161
  if (hookChoice === "skip") {
5677
- console.log(chalk7.dim(" Skipped auto-refresh hooks. Run ") + chalk7.hex("#83D1EB")("caliber hooks --install") + chalk7.dim(" later to enable."));
5162
+ console.log(chalk6.dim(" Skipped auto-refresh hooks. Run ") + chalk6.hex("#83D1EB")("caliber hooks --install") + chalk6.dim(" later to enable."));
5678
5163
  }
5679
5164
  const afterScore = computeLocalScore(process.cwd(), targetAgent);
5680
5165
  if (afterScore.score < baselineScore.score) {
5681
5166
  console.log("");
5682
- console.log(chalk7.yellow(` Score would drop from ${baselineScore.score} to ${afterScore.score} \u2014 reverting changes.`));
5167
+ console.log(chalk6.yellow(` Score would drop from ${baselineScore.score} to ${afterScore.score} \u2014 reverting changes.`));
5683
5168
  try {
5684
5169
  const { restored, removed } = undoSetup();
5685
5170
  if (restored.length > 0 || removed.length > 0) {
5686
- console.log(chalk7.dim(` Reverted ${restored.length + removed.length} file${restored.length + removed.length === 1 ? "" : "s"} from backup.`));
5171
+ console.log(chalk6.dim(` Reverted ${restored.length + removed.length} file${restored.length + removed.length === 1 ? "" : "s"} from backup.`));
5687
5172
  }
5688
5173
  } catch {
5689
5174
  }
5690
- console.log(chalk7.dim(" Run ") + chalk7.hex("#83D1EB")("caliber onboard --force") + chalk7.dim(" to override.\n"));
5175
+ console.log(chalk6.dim(" Run ") + chalk6.hex("#83D1EB")("caliber onboard --force") + chalk6.dim(" to override.\n"));
5691
5176
  return;
5692
5177
  }
5693
5178
  displayScoreDelta(baselineScore, afterScore);
5694
5179
  console.log(title.bold("\n Step 6/6 \u2014 Community skills\n"));
5695
- console.log(chalk7.dim(" Search public skill registries for skills that match your tech stack.\n"));
5180
+ console.log(chalk6.dim(" Search public skill registries for skills that match your tech stack.\n"));
5696
5181
  const wantsSkills = await select4({
5697
5182
  message: "Search public repos for relevant skills to add to this project?",
5698
5183
  choices: [
@@ -5705,16 +5190,16 @@ async function initCommand(options) {
5705
5190
  await searchAndInstallSkills();
5706
5191
  } catch (err) {
5707
5192
  if (err.message !== "__exit__") {
5708
- console.log(chalk7.dim(" Skills search failed: " + (err.message || "unknown error")));
5193
+ console.log(chalk6.dim(" Skills search failed: " + (err.message || "unknown error")));
5709
5194
  }
5710
- console.log(chalk7.dim(" Run ") + chalk7.hex("#83D1EB")("caliber skills") + chalk7.dim(" later to try again.\n"));
5195
+ console.log(chalk6.dim(" Run ") + chalk6.hex("#83D1EB")("caliber skills") + chalk6.dim(" later to try again.\n"));
5711
5196
  }
5712
5197
  } else {
5713
- console.log(chalk7.dim(" Skipped. Run ") + chalk7.hex("#83D1EB")("caliber skills") + chalk7.dim(" later to browse.\n"));
5198
+ console.log(chalk6.dim(" Skipped. Run ") + chalk6.hex("#83D1EB")("caliber skills") + chalk6.dim(" later to browse.\n"));
5714
5199
  }
5715
- console.log(chalk7.bold.green(" Onboarding complete! Your project is ready for AI-assisted development."));
5716
- console.log(chalk7.dim(" Run ") + chalk7.hex("#83D1EB")("caliber undo") + chalk7.dim(" to revert changes.\n"));
5717
- console.log(chalk7.bold(" Next steps:\n"));
5200
+ console.log(chalk6.bold.green(" Onboarding complete! Your project is ready for AI-assisted development."));
5201
+ console.log(chalk6.dim(" Run ") + chalk6.hex("#83D1EB")("caliber undo") + chalk6.dim(" to revert changes.\n"));
5202
+ console.log(chalk6.bold(" Next steps:\n"));
5718
5203
  console.log(` ${title("caliber score")} See your full config breakdown`);
5719
5204
  console.log(` ${title("caliber skills")} Discover community skills for your stack`);
5720
5205
  console.log(` ${title("caliber undo")} Revert all changes from this run`);
@@ -5722,7 +5207,7 @@ async function initCommand(options) {
5722
5207
  }
5723
5208
  async function refineLoop(currentSetup, _targetAgent, sessionHistory) {
5724
5209
  while (true) {
5725
- const message = await promptInput3("\nWhat would you like to change?");
5210
+ const message = await promptInput2("\nWhat would you like to change?");
5726
5211
  if (!message || message.toLowerCase() === "done" || message.toLowerCase() === "accept") {
5727
5212
  return currentSetup;
5728
5213
  }
@@ -5731,12 +5216,12 @@ async function refineLoop(currentSetup, _targetAgent, sessionHistory) {
5731
5216
  }
5732
5217
  const isValid = await classifyRefineIntent(message);
5733
5218
  if (!isValid) {
5734
- console.log(chalk7.dim(" This doesn't look like a config change request."));
5735
- console.log(chalk7.dim(" Describe what to add, remove, or modify in your configs."));
5736
- console.log(chalk7.dim(' Type "done" to accept the current setup.\n'));
5219
+ console.log(chalk6.dim(" This doesn't look like a config change request."));
5220
+ console.log(chalk6.dim(" Describe what to add, remove, or modify in your configs."));
5221
+ console.log(chalk6.dim(' Type "done" to accept the current setup.\n'));
5737
5222
  continue;
5738
5223
  }
5739
- const refineSpinner = ora3("Refining setup...").start();
5224
+ const refineSpinner = ora2("Refining setup...").start();
5740
5225
  const refineMessages = new SpinnerMessages(refineSpinner, REFINE_MESSAGES);
5741
5226
  refineMessages.start();
5742
5227
  const refined = await refineSetup(
@@ -5754,16 +5239,16 @@ async function refineLoop(currentSetup, _targetAgent, sessionHistory) {
5754
5239
  });
5755
5240
  refineSpinner.succeed("Setup updated");
5756
5241
  printSetupSummary(refined);
5757
- console.log(chalk7.dim('Type "done" to accept, or describe more changes.'));
5242
+ console.log(chalk6.dim('Type "done" to accept, or describe more changes.'));
5758
5243
  } else {
5759
5244
  refineSpinner.fail("Refinement failed \u2014 could not parse AI response.");
5760
- console.log(chalk7.dim('Try rephrasing your request, or type "done" to keep the current setup.'));
5245
+ console.log(chalk6.dim('Try rephrasing your request, or type "done" to keep the current setup.'));
5761
5246
  }
5762
5247
  }
5763
5248
  }
5764
5249
  function summarizeSetup(action, setup) {
5765
5250
  const descriptions = setup.fileDescriptions;
5766
- const files = descriptions ? Object.entries(descriptions).map(([path24, desc]) => ` ${path24}: ${desc}`).join("\n") : Object.keys(setup).filter((k) => k !== "targetAgent" && k !== "fileDescriptions").join(", ");
5251
+ const files = descriptions ? Object.entries(descriptions).map(([path23, desc]) => ` ${path23}: ${desc}`).join("\n") : Object.keys(setup).filter((k) => k !== "targetAgent" && k !== "fileDescriptions").join(", ");
5767
5252
  return `${action}. Files:
5768
5253
  ${files}`;
5769
5254
  }
@@ -5814,10 +5299,10 @@ ${JSON.stringify(checkList, null, 2)}`,
5814
5299
  return [];
5815
5300
  }
5816
5301
  }
5817
- function promptInput3(question) {
5818
- const rl = readline4.createInterface({ input: process.stdin, output: process.stdout });
5302
+ function promptInput2(question) {
5303
+ const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
5819
5304
  return new Promise((resolve2) => {
5820
- rl.question(chalk7.cyan(`${question} `), (answer) => {
5305
+ rl.question(chalk6.cyan(`${question} `), (answer) => {
5821
5306
  rl.close();
5822
5307
  resolve2(answer.trim());
5823
5308
  });
@@ -5870,26 +5355,26 @@ function printSetupSummary(setup) {
5870
5355
  const fileDescriptions = setup.fileDescriptions;
5871
5356
  const deletions = setup.deletions;
5872
5357
  console.log("");
5873
- console.log(chalk7.bold(" Proposed changes:\n"));
5358
+ console.log(chalk6.bold(" Proposed changes:\n"));
5874
5359
  const getDescription = (filePath) => {
5875
5360
  return fileDescriptions?.[filePath];
5876
5361
  };
5877
5362
  if (claude) {
5878
5363
  if (claude.claudeMd) {
5879
- const icon = fs22.existsSync("CLAUDE.md") ? chalk7.yellow("~") : chalk7.green("+");
5364
+ const icon = fs21.existsSync("CLAUDE.md") ? chalk6.yellow("~") : chalk6.green("+");
5880
5365
  const desc = getDescription("CLAUDE.md");
5881
- console.log(` ${icon} ${chalk7.bold("CLAUDE.md")}`);
5882
- if (desc) console.log(chalk7.dim(` ${desc}`));
5366
+ console.log(` ${icon} ${chalk6.bold("CLAUDE.md")}`);
5367
+ if (desc) console.log(chalk6.dim(` ${desc}`));
5883
5368
  console.log("");
5884
5369
  }
5885
5370
  const skills = claude.skills;
5886
5371
  if (Array.isArray(skills) && skills.length > 0) {
5887
5372
  for (const skill of skills) {
5888
5373
  const skillPath = `.claude/skills/${skill.name}/SKILL.md`;
5889
- const icon = fs22.existsSync(skillPath) ? chalk7.yellow("~") : chalk7.green("+");
5374
+ const icon = fs21.existsSync(skillPath) ? chalk6.yellow("~") : chalk6.green("+");
5890
5375
  const desc = getDescription(skillPath);
5891
- console.log(` ${icon} ${chalk7.bold(skillPath)}`);
5892
- console.log(chalk7.dim(` ${desc || skill.description || skill.name}`));
5376
+ console.log(` ${icon} ${chalk6.bold(skillPath)}`);
5377
+ console.log(chalk6.dim(` ${desc || skill.description || skill.name}`));
5893
5378
  console.log("");
5894
5379
  }
5895
5380
  }
@@ -5897,40 +5382,40 @@ function printSetupSummary(setup) {
5897
5382
  const codex = setup.codex;
5898
5383
  if (codex) {
5899
5384
  if (codex.agentsMd) {
5900
- const icon = fs22.existsSync("AGENTS.md") ? chalk7.yellow("~") : chalk7.green("+");
5385
+ const icon = fs21.existsSync("AGENTS.md") ? chalk6.yellow("~") : chalk6.green("+");
5901
5386
  const desc = getDescription("AGENTS.md");
5902
- console.log(` ${icon} ${chalk7.bold("AGENTS.md")}`);
5903
- if (desc) console.log(chalk7.dim(` ${desc}`));
5387
+ console.log(` ${icon} ${chalk6.bold("AGENTS.md")}`);
5388
+ if (desc) console.log(chalk6.dim(` ${desc}`));
5904
5389
  console.log("");
5905
5390
  }
5906
5391
  const codexSkills = codex.skills;
5907
5392
  if (Array.isArray(codexSkills) && codexSkills.length > 0) {
5908
5393
  for (const skill of codexSkills) {
5909
5394
  const skillPath = `.agents/skills/${skill.name}/SKILL.md`;
5910
- const icon = fs22.existsSync(skillPath) ? chalk7.yellow("~") : chalk7.green("+");
5395
+ const icon = fs21.existsSync(skillPath) ? chalk6.yellow("~") : chalk6.green("+");
5911
5396
  const desc = getDescription(skillPath);
5912
- console.log(` ${icon} ${chalk7.bold(skillPath)}`);
5913
- console.log(chalk7.dim(` ${desc || skill.description || skill.name}`));
5397
+ console.log(` ${icon} ${chalk6.bold(skillPath)}`);
5398
+ console.log(chalk6.dim(` ${desc || skill.description || skill.name}`));
5914
5399
  console.log("");
5915
5400
  }
5916
5401
  }
5917
5402
  }
5918
5403
  if (cursor) {
5919
5404
  if (cursor.cursorrules) {
5920
- const icon = fs22.existsSync(".cursorrules") ? chalk7.yellow("~") : chalk7.green("+");
5405
+ const icon = fs21.existsSync(".cursorrules") ? chalk6.yellow("~") : chalk6.green("+");
5921
5406
  const desc = getDescription(".cursorrules");
5922
- console.log(` ${icon} ${chalk7.bold(".cursorrules")}`);
5923
- if (desc) console.log(chalk7.dim(` ${desc}`));
5407
+ console.log(` ${icon} ${chalk6.bold(".cursorrules")}`);
5408
+ if (desc) console.log(chalk6.dim(` ${desc}`));
5924
5409
  console.log("");
5925
5410
  }
5926
5411
  const cursorSkills = cursor.skills;
5927
5412
  if (Array.isArray(cursorSkills) && cursorSkills.length > 0) {
5928
5413
  for (const skill of cursorSkills) {
5929
5414
  const skillPath = `.cursor/skills/${skill.name}/SKILL.md`;
5930
- const icon = fs22.existsSync(skillPath) ? chalk7.yellow("~") : chalk7.green("+");
5415
+ const icon = fs21.existsSync(skillPath) ? chalk6.yellow("~") : chalk6.green("+");
5931
5416
  const desc = getDescription(skillPath);
5932
- console.log(` ${icon} ${chalk7.bold(skillPath)}`);
5933
- console.log(chalk7.dim(` ${desc || skill.description || skill.name}`));
5417
+ console.log(` ${icon} ${chalk6.bold(skillPath)}`);
5418
+ console.log(chalk6.dim(` ${desc || skill.description || skill.name}`));
5934
5419
  console.log("");
5935
5420
  }
5936
5421
  }
@@ -5938,40 +5423,40 @@ function printSetupSummary(setup) {
5938
5423
  if (Array.isArray(rules) && rules.length > 0) {
5939
5424
  for (const rule of rules) {
5940
5425
  const rulePath = `.cursor/rules/${rule.filename}`;
5941
- const icon = fs22.existsSync(rulePath) ? chalk7.yellow("~") : chalk7.green("+");
5426
+ const icon = fs21.existsSync(rulePath) ? chalk6.yellow("~") : chalk6.green("+");
5942
5427
  const desc = getDescription(rulePath);
5943
- console.log(` ${icon} ${chalk7.bold(rulePath)}`);
5428
+ console.log(` ${icon} ${chalk6.bold(rulePath)}`);
5944
5429
  if (desc) {
5945
- console.log(chalk7.dim(` ${desc}`));
5430
+ console.log(chalk6.dim(` ${desc}`));
5946
5431
  } else {
5947
5432
  const firstLine = rule.content.split("\n").filter((l) => l.trim() && !l.trim().startsWith("#"))[0];
5948
- if (firstLine) console.log(chalk7.dim(` ${firstLine.trim().slice(0, 80)}`));
5433
+ if (firstLine) console.log(chalk6.dim(` ${firstLine.trim().slice(0, 80)}`));
5949
5434
  }
5950
5435
  console.log("");
5951
5436
  }
5952
5437
  }
5953
5438
  }
5954
- if (!codex && !fs22.existsSync("AGENTS.md")) {
5955
- console.log(` ${chalk7.green("+")} ${chalk7.bold("AGENTS.md")}`);
5956
- console.log(chalk7.dim(" Cross-agent coordination file"));
5439
+ if (!codex && !fs21.existsSync("AGENTS.md")) {
5440
+ console.log(` ${chalk6.green("+")} ${chalk6.bold("AGENTS.md")}`);
5441
+ console.log(chalk6.dim(" Cross-agent coordination file"));
5957
5442
  console.log("");
5958
5443
  }
5959
5444
  if (Array.isArray(deletions) && deletions.length > 0) {
5960
5445
  for (const del of deletions) {
5961
- console.log(` ${chalk7.red("-")} ${chalk7.bold(del.filePath)}`);
5962
- console.log(chalk7.dim(` ${del.reason}`));
5446
+ console.log(` ${chalk6.red("-")} ${chalk6.bold(del.filePath)}`);
5447
+ console.log(chalk6.dim(` ${del.reason}`));
5963
5448
  console.log("");
5964
5449
  }
5965
5450
  }
5966
- console.log(` ${chalk7.green("+")} ${chalk7.dim("new")} ${chalk7.yellow("~")} ${chalk7.dim("modified")} ${chalk7.red("-")} ${chalk7.dim("removed")}`);
5451
+ console.log(` ${chalk6.green("+")} ${chalk6.dim("new")} ${chalk6.yellow("~")} ${chalk6.dim("modified")} ${chalk6.red("-")} ${chalk6.dim("removed")}`);
5967
5452
  console.log("");
5968
5453
  }
5969
5454
  function ensurePermissions() {
5970
5455
  const settingsPath = ".claude/settings.json";
5971
5456
  let settings = {};
5972
5457
  try {
5973
- if (fs22.existsSync(settingsPath)) {
5974
- settings = JSON.parse(fs22.readFileSync(settingsPath, "utf-8"));
5458
+ if (fs21.existsSync(settingsPath)) {
5459
+ settings = JSON.parse(fs21.readFileSync(settingsPath, "utf-8"));
5975
5460
  }
5976
5461
  } catch {
5977
5462
  }
@@ -5985,15 +5470,15 @@ function ensurePermissions() {
5985
5470
  "Bash(git *)"
5986
5471
  ];
5987
5472
  settings.permissions = permissions;
5988
- if (!fs22.existsSync(".claude")) fs22.mkdirSync(".claude", { recursive: true });
5989
- fs22.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
5473
+ if (!fs21.existsSync(".claude")) fs21.mkdirSync(".claude", { recursive: true });
5474
+ fs21.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
5990
5475
  }
5991
5476
 
5992
5477
  // src/commands/undo.ts
5993
- import chalk8 from "chalk";
5994
- import ora4 from "ora";
5478
+ import chalk7 from "chalk";
5479
+ import ora3 from "ora";
5995
5480
  function undoCommand() {
5996
- const spinner = ora4("Reverting setup...").start();
5481
+ const spinner = ora3("Reverting setup...").start();
5997
5482
  try {
5998
5483
  const { restored, removed } = undoSetup();
5999
5484
  if (restored.length === 0 && removed.length === 0) {
@@ -6002,27 +5487,27 @@ function undoCommand() {
6002
5487
  }
6003
5488
  spinner.succeed("Setup reverted successfully.\n");
6004
5489
  if (restored.length > 0) {
6005
- console.log(chalk8.cyan(" Restored from backup:"));
5490
+ console.log(chalk7.cyan(" Restored from backup:"));
6006
5491
  for (const file of restored) {
6007
- console.log(` ${chalk8.green("\u21A9")} ${file}`);
5492
+ console.log(` ${chalk7.green("\u21A9")} ${file}`);
6008
5493
  }
6009
5494
  }
6010
5495
  if (removed.length > 0) {
6011
- console.log(chalk8.cyan(" Removed:"));
5496
+ console.log(chalk7.cyan(" Removed:"));
6012
5497
  for (const file of removed) {
6013
- console.log(` ${chalk8.red("\u2717")} ${file}`);
5498
+ console.log(` ${chalk7.red("\u2717")} ${file}`);
6014
5499
  }
6015
5500
  }
6016
5501
  console.log("");
6017
5502
  } catch (err) {
6018
- spinner.fail(chalk8.red(err instanceof Error ? err.message : "Undo failed"));
5503
+ spinner.fail(chalk7.red(err instanceof Error ? err.message : "Undo failed"));
6019
5504
  throw new Error("__exit__");
6020
5505
  }
6021
5506
  }
6022
5507
 
6023
5508
  // src/commands/status.ts
6024
- import chalk9 from "chalk";
6025
- import fs23 from "fs";
5509
+ import chalk8 from "chalk";
5510
+ import fs22 from "fs";
6026
5511
  async function statusCommand(options) {
6027
5512
  const config = loadConfig();
6028
5513
  const manifest = readManifest();
@@ -6035,52 +5520,52 @@ async function statusCommand(options) {
6035
5520
  }, null, 2));
6036
5521
  return;
6037
5522
  }
6038
- console.log(chalk9.bold("\nCaliber Status\n"));
5523
+ console.log(chalk8.bold("\nCaliber Status\n"));
6039
5524
  if (config) {
6040
- console.log(` LLM: ${chalk9.green(config.provider)} (${config.model})`);
5525
+ console.log(` LLM: ${chalk8.green(config.provider)} (${config.model})`);
6041
5526
  } else {
6042
- console.log(` LLM: ${chalk9.yellow("Not configured")} \u2014 run ${chalk9.hex("#83D1EB")("caliber config")}`);
5527
+ console.log(` LLM: ${chalk8.yellow("Not configured")} \u2014 run ${chalk8.hex("#83D1EB")("caliber config")}`);
6043
5528
  }
6044
5529
  if (!manifest) {
6045
- console.log(` Setup: ${chalk9.dim("No setup applied")}`);
6046
- console.log(chalk9.dim("\n Run ") + chalk9.hex("#83D1EB")("caliber onboard") + chalk9.dim(" to get started.\n"));
5530
+ console.log(` Setup: ${chalk8.dim("No setup applied")}`);
5531
+ console.log(chalk8.dim("\n Run ") + chalk8.hex("#83D1EB")("caliber onboard") + chalk8.dim(" to get started.\n"));
6047
5532
  return;
6048
5533
  }
6049
- console.log(` Files managed: ${chalk9.cyan(manifest.entries.length.toString())}`);
5534
+ console.log(` Files managed: ${chalk8.cyan(manifest.entries.length.toString())}`);
6050
5535
  for (const entry of manifest.entries) {
6051
- const exists = fs23.existsSync(entry.path);
6052
- const icon = exists ? chalk9.green("\u2713") : chalk9.red("\u2717");
5536
+ const exists = fs22.existsSync(entry.path);
5537
+ const icon = exists ? chalk8.green("\u2713") : chalk8.red("\u2717");
6053
5538
  console.log(` ${icon} ${entry.path} (${entry.action})`);
6054
5539
  }
6055
5540
  console.log("");
6056
5541
  }
6057
5542
 
6058
5543
  // src/commands/regenerate.ts
6059
- import chalk10 from "chalk";
6060
- import ora5 from "ora";
5544
+ import chalk9 from "chalk";
5545
+ import ora4 from "ora";
6061
5546
  import select5 from "@inquirer/select";
6062
5547
  async function regenerateCommand(options) {
6063
5548
  const config = loadConfig();
6064
5549
  if (!config) {
6065
- console.log(chalk10.red("No LLM provider configured. Run ") + chalk10.hex("#83D1EB")("caliber config") + chalk10.red(" first."));
5550
+ console.log(chalk9.red("No LLM provider configured. Run ") + chalk9.hex("#83D1EB")("caliber config") + chalk9.red(" first."));
6066
5551
  throw new Error("__exit__");
6067
5552
  }
6068
5553
  const manifest = readManifest();
6069
5554
  if (!manifest) {
6070
- console.log(chalk10.yellow("No existing setup found. Run ") + chalk10.hex("#83D1EB")("caliber onboard") + chalk10.yellow(" first."));
5555
+ console.log(chalk9.yellow("No existing setup found. Run ") + chalk9.hex("#83D1EB")("caliber onboard") + chalk9.yellow(" first."));
6071
5556
  throw new Error("__exit__");
6072
5557
  }
6073
5558
  const targetAgent = readState()?.targetAgent ?? ["claude", "cursor"];
6074
- const spinner = ora5("Analyzing project...").start();
5559
+ const spinner = ora4("Analyzing project...").start();
6075
5560
  const fingerprint = await collectFingerprint(process.cwd());
6076
5561
  spinner.succeed("Project analyzed");
6077
5562
  const baselineScore = computeLocalScore(process.cwd(), targetAgent);
6078
5563
  displayScoreSummary(baselineScore);
6079
5564
  if (baselineScore.score === 100) {
6080
- console.log(chalk10.green(" Your setup is already at 100/100 \u2014 nothing to regenerate.\n"));
5565
+ console.log(chalk9.green(" Your setup is already at 100/100 \u2014 nothing to regenerate.\n"));
6081
5566
  return;
6082
5567
  }
6083
- const genSpinner = ora5("Regenerating setup...").start();
5568
+ const genSpinner = ora4("Regenerating setup...").start();
6084
5569
  const genMessages = new SpinnerMessages(genSpinner, GENERATION_MESSAGES, { showElapsedTime: true });
6085
5570
  genMessages.start();
6086
5571
  let generatedSetup = null;
@@ -6118,18 +5603,18 @@ async function regenerateCommand(options) {
6118
5603
  const setupFiles = collectSetupFiles(generatedSetup);
6119
5604
  const staged = stageFiles(setupFiles, process.cwd());
6120
5605
  const totalChanges = staged.newFiles + staged.modifiedFiles;
6121
- console.log(chalk10.dim(`
6122
- ${chalk10.green(`${staged.newFiles} new`)} / ${chalk10.yellow(`${staged.modifiedFiles} modified`)} file${totalChanges !== 1 ? "s" : ""}
5606
+ console.log(chalk9.dim(`
5607
+ ${chalk9.green(`${staged.newFiles} new`)} / ${chalk9.yellow(`${staged.modifiedFiles} modified`)} file${totalChanges !== 1 ? "s" : ""}
6123
5608
  `));
6124
5609
  if (totalChanges === 0) {
6125
- console.log(chalk10.dim(" No changes needed \u2014 your configs are already up to date.\n"));
5610
+ console.log(chalk9.dim(" No changes needed \u2014 your configs are already up to date.\n"));
6126
5611
  cleanupStaging();
6127
5612
  return;
6128
5613
  }
6129
5614
  if (options.dryRun) {
6130
- console.log(chalk10.yellow("[Dry run] Would write:"));
5615
+ console.log(chalk9.yellow("[Dry run] Would write:"));
6131
5616
  for (const f of staged.stagedFiles) {
6132
- console.log(` ${f.isNew ? chalk10.green("+") : chalk10.yellow("~")} ${f.relativePath}`);
5617
+ console.log(` ${f.isNew ? chalk9.green("+") : chalk9.yellow("~")} ${f.relativePath}`);
6133
5618
  }
6134
5619
  cleanupStaging();
6135
5620
  return;
@@ -6148,28 +5633,28 @@ async function regenerateCommand(options) {
6148
5633
  });
6149
5634
  cleanupStaging();
6150
5635
  if (action === "decline") {
6151
- console.log(chalk10.dim("Regeneration cancelled. No files were modified."));
5636
+ console.log(chalk9.dim("Regeneration cancelled. No files were modified."));
6152
5637
  return;
6153
5638
  }
6154
- const writeSpinner = ora5("Writing config files...").start();
5639
+ const writeSpinner = ora4("Writing config files...").start();
6155
5640
  try {
6156
5641
  const result = writeSetup(generatedSetup);
6157
5642
  writeSpinner.succeed("Config files written");
6158
5643
  for (const file of result.written) {
6159
- console.log(` ${chalk10.green("\u2713")} ${file}`);
5644
+ console.log(` ${chalk9.green("\u2713")} ${file}`);
6160
5645
  }
6161
5646
  if (result.deleted.length > 0) {
6162
5647
  for (const file of result.deleted) {
6163
- console.log(` ${chalk10.red("\u2717")} ${file}`);
5648
+ console.log(` ${chalk9.red("\u2717")} ${file}`);
6164
5649
  }
6165
5650
  }
6166
5651
  if (result.backupDir) {
6167
- console.log(chalk10.dim(`
5652
+ console.log(chalk9.dim(`
6168
5653
  Backups saved to ${result.backupDir}`));
6169
5654
  }
6170
5655
  } catch (err) {
6171
5656
  writeSpinner.fail("Failed to write files");
6172
- console.error(chalk10.red(err instanceof Error ? err.message : "Unknown error"));
5657
+ console.error(chalk9.red(err instanceof Error ? err.message : "Unknown error"));
6173
5658
  throw new Error("__exit__");
6174
5659
  }
6175
5660
  const sha = getCurrentHeadSha();
@@ -6181,24 +5666,24 @@ async function regenerateCommand(options) {
6181
5666
  const afterScore = computeLocalScore(process.cwd(), targetAgent);
6182
5667
  if (afterScore.score < baselineScore.score) {
6183
5668
  console.log("");
6184
- console.log(chalk10.yellow(` Score would drop from ${baselineScore.score} to ${afterScore.score} \u2014 reverting changes.`));
5669
+ console.log(chalk9.yellow(` Score would drop from ${baselineScore.score} to ${afterScore.score} \u2014 reverting changes.`));
6185
5670
  try {
6186
5671
  const { restored, removed } = undoSetup();
6187
5672
  if (restored.length > 0 || removed.length > 0) {
6188
- console.log(chalk10.dim(` Reverted ${restored.length + removed.length} file${restored.length + removed.length === 1 ? "" : "s"} from backup.`));
5673
+ console.log(chalk9.dim(` Reverted ${restored.length + removed.length} file${restored.length + removed.length === 1 ? "" : "s"} from backup.`));
6189
5674
  }
6190
5675
  } catch {
6191
5676
  }
6192
- console.log(chalk10.dim(" Run ") + chalk10.hex("#83D1EB")("caliber onboard --force") + chalk10.dim(" to override.\n"));
5677
+ console.log(chalk9.dim(" Run ") + chalk9.hex("#83D1EB")("caliber onboard --force") + chalk9.dim(" to override.\n"));
6193
5678
  return;
6194
5679
  }
6195
5680
  displayScoreDelta(baselineScore, afterScore);
6196
- console.log(chalk10.bold.green(" Regeneration complete!"));
6197
- console.log(chalk10.dim(" Run ") + chalk10.hex("#83D1EB")("caliber undo") + chalk10.dim(" to revert changes.\n"));
5681
+ console.log(chalk9.bold.green(" Regeneration complete!"));
5682
+ console.log(chalk9.dim(" Run ") + chalk9.hex("#83D1EB")("caliber undo") + chalk9.dim(" to revert changes.\n"));
6198
5683
  }
6199
5684
 
6200
5685
  // src/commands/score.ts
6201
- import chalk11 from "chalk";
5686
+ import chalk10 from "chalk";
6202
5687
  async function scoreCommand(options) {
6203
5688
  const dir = process.cwd();
6204
5689
  const target = options.agent ?? readState()?.targetAgent;
@@ -6212,23 +5697,23 @@ async function scoreCommand(options) {
6212
5697
  return;
6213
5698
  }
6214
5699
  displayScore(result);
6215
- const separator = chalk11.gray(" " + "\u2500".repeat(53));
5700
+ const separator = chalk10.gray(" " + "\u2500".repeat(53));
6216
5701
  console.log(separator);
6217
5702
  if (result.score < 40) {
6218
- console.log(chalk11.gray(" Run ") + chalk11.hex("#83D1EB")("caliber onboard") + chalk11.gray(" to generate a complete, optimized setup."));
5703
+ console.log(chalk10.gray(" Run ") + chalk10.hex("#83D1EB")("caliber onboard") + chalk10.gray(" to generate a complete, optimized setup."));
6219
5704
  } else if (result.score < 70) {
6220
- console.log(chalk11.gray(" Run ") + chalk11.hex("#83D1EB")("caliber onboard") + chalk11.gray(" to improve your setup."));
5705
+ console.log(chalk10.gray(" Run ") + chalk10.hex("#83D1EB")("caliber onboard") + chalk10.gray(" to improve your setup."));
6221
5706
  } else {
6222
- console.log(chalk11.green(" Looking good!") + chalk11.gray(" Run ") + chalk11.hex("#83D1EB")("caliber regenerate") + chalk11.gray(" to rebuild from scratch."));
5707
+ console.log(chalk10.green(" Looking good!") + chalk10.gray(" Run ") + chalk10.hex("#83D1EB")("caliber regenerate") + chalk10.gray(" to rebuild from scratch."));
6223
5708
  }
6224
5709
  console.log("");
6225
5710
  }
6226
5711
 
6227
5712
  // src/commands/refresh.ts
6228
- import fs25 from "fs";
6229
- import path19 from "path";
6230
- import chalk12 from "chalk";
6231
- import ora6 from "ora";
5713
+ import fs24 from "fs";
5714
+ import path18 from "path";
5715
+ import chalk11 from "chalk";
5716
+ import ora5 from "ora";
6232
5717
 
6233
5718
  // src/lib/git-diff.ts
6234
5719
  import { execSync as execSync8 } from "child_process";
@@ -6303,37 +5788,37 @@ function collectDiff(lastSha) {
6303
5788
  }
6304
5789
 
6305
5790
  // src/writers/refresh.ts
6306
- import fs24 from "fs";
6307
- import path18 from "path";
5791
+ import fs23 from "fs";
5792
+ import path17 from "path";
6308
5793
  function writeRefreshDocs(docs) {
6309
5794
  const written = [];
6310
5795
  if (docs.claudeMd) {
6311
- fs24.writeFileSync("CLAUDE.md", docs.claudeMd);
5796
+ fs23.writeFileSync("CLAUDE.md", docs.claudeMd);
6312
5797
  written.push("CLAUDE.md");
6313
5798
  }
6314
5799
  if (docs.readmeMd) {
6315
- fs24.writeFileSync("README.md", docs.readmeMd);
5800
+ fs23.writeFileSync("README.md", docs.readmeMd);
6316
5801
  written.push("README.md");
6317
5802
  }
6318
5803
  if (docs.cursorrules) {
6319
- fs24.writeFileSync(".cursorrules", docs.cursorrules);
5804
+ fs23.writeFileSync(".cursorrules", docs.cursorrules);
6320
5805
  written.push(".cursorrules");
6321
5806
  }
6322
5807
  if (docs.cursorRules) {
6323
- const rulesDir = path18.join(".cursor", "rules");
6324
- if (!fs24.existsSync(rulesDir)) fs24.mkdirSync(rulesDir, { recursive: true });
5808
+ const rulesDir = path17.join(".cursor", "rules");
5809
+ if (!fs23.existsSync(rulesDir)) fs23.mkdirSync(rulesDir, { recursive: true });
6325
5810
  for (const rule of docs.cursorRules) {
6326
- const filePath = path18.join(rulesDir, rule.filename);
6327
- fs24.writeFileSync(filePath, rule.content);
5811
+ const filePath = path17.join(rulesDir, rule.filename);
5812
+ fs23.writeFileSync(filePath, rule.content);
6328
5813
  written.push(filePath);
6329
5814
  }
6330
5815
  }
6331
5816
  if (docs.claudeSkills) {
6332
- const skillsDir = path18.join(".claude", "skills");
6333
- if (!fs24.existsSync(skillsDir)) fs24.mkdirSync(skillsDir, { recursive: true });
5817
+ const skillsDir = path17.join(".claude", "skills");
5818
+ if (!fs23.existsSync(skillsDir)) fs23.mkdirSync(skillsDir, { recursive: true });
6334
5819
  for (const skill of docs.claudeSkills) {
6335
- const filePath = path18.join(skillsDir, skill.filename);
6336
- fs24.writeFileSync(filePath, skill.content);
5820
+ const filePath = path17.join(skillsDir, skill.filename);
5821
+ fs23.writeFileSync(filePath, skill.content);
6337
5822
  written.push(filePath);
6338
5823
  }
6339
5824
  }
@@ -6410,11 +5895,11 @@ function log(quiet, ...args) {
6410
5895
  function discoverGitRepos(parentDir) {
6411
5896
  const repos = [];
6412
5897
  try {
6413
- const entries = fs25.readdirSync(parentDir, { withFileTypes: true });
5898
+ const entries = fs24.readdirSync(parentDir, { withFileTypes: true });
6414
5899
  for (const entry of entries) {
6415
5900
  if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
6416
- const childPath = path19.join(parentDir, entry.name);
6417
- if (fs25.existsSync(path19.join(childPath, ".git"))) {
5901
+ const childPath = path18.join(parentDir, entry.name);
5902
+ if (fs24.existsSync(path18.join(childPath, ".git"))) {
6418
5903
  repos.push(childPath);
6419
5904
  }
6420
5905
  }
@@ -6424,7 +5909,7 @@ function discoverGitRepos(parentDir) {
6424
5909
  }
6425
5910
  async function refreshSingleRepo(repoDir, options) {
6426
5911
  const quiet = !!options.quiet;
6427
- const prefix = options.label ? `${chalk12.bold(options.label)} ` : "";
5912
+ const prefix = options.label ? `${chalk11.bold(options.label)} ` : "";
6428
5913
  const state = readState();
6429
5914
  const lastSha = state?.lastRefreshSha ?? null;
6430
5915
  const diff = collectDiff(lastSha);
@@ -6433,10 +5918,10 @@ async function refreshSingleRepo(repoDir, options) {
6433
5918
  if (currentSha) {
6434
5919
  writeState({ lastRefreshSha: currentSha, lastRefreshTimestamp: (/* @__PURE__ */ new Date()).toISOString() });
6435
5920
  }
6436
- log(quiet, chalk12.dim(`${prefix}No changes since last refresh.`));
5921
+ log(quiet, chalk11.dim(`${prefix}No changes since last refresh.`));
6437
5922
  return;
6438
5923
  }
6439
- const spinner = quiet ? null : ora6(`${prefix}Analyzing changes...`).start();
5924
+ const spinner = quiet ? null : ora5(`${prefix}Analyzing changes...`).start();
6440
5925
  const existingDocs = readExistingConfigs(repoDir);
6441
5926
  const fingerprint = await collectFingerprint(repoDir);
6442
5927
  const projectContext = {
@@ -6465,10 +5950,10 @@ async function refreshSingleRepo(repoDir, options) {
6465
5950
  if (options.dryRun) {
6466
5951
  spinner?.info(`${prefix}Dry run \u2014 would update:`);
6467
5952
  for (const doc of response.docsUpdated) {
6468
- console.log(` ${chalk12.yellow("~")} ${doc}`);
5953
+ console.log(` ${chalk11.yellow("~")} ${doc}`);
6469
5954
  }
6470
5955
  if (response.changesSummary) {
6471
- console.log(chalk12.dim(`
5956
+ console.log(chalk11.dim(`
6472
5957
  ${response.changesSummary}`));
6473
5958
  }
6474
5959
  return;
@@ -6476,10 +5961,10 @@ async function refreshSingleRepo(repoDir, options) {
6476
5961
  const written = writeRefreshDocs(response.updatedDocs);
6477
5962
  spinner?.succeed(`${prefix}Updated ${written.length} doc${written.length === 1 ? "" : "s"}`);
6478
5963
  for (const file of written) {
6479
- log(quiet, ` ${chalk12.green("\u2713")} ${file}`);
5964
+ log(quiet, ` ${chalk11.green("\u2713")} ${file}`);
6480
5965
  }
6481
5966
  if (response.changesSummary) {
6482
- log(quiet, chalk12.dim(`
5967
+ log(quiet, chalk11.dim(`
6483
5968
  ${response.changesSummary}`));
6484
5969
  }
6485
5970
  if (currentSha) {
@@ -6492,7 +5977,7 @@ async function refreshCommand(options) {
6492
5977
  const config = loadConfig();
6493
5978
  if (!config) {
6494
5979
  if (quiet) return;
6495
- console.log(chalk12.red("No LLM provider configured. Run ") + chalk12.hex("#83D1EB")("caliber config") + chalk12.red(" (e.g. choose Cursor) or set an API key."));
5980
+ console.log(chalk11.red("No LLM provider configured. Run ") + chalk11.hex("#83D1EB")("caliber config") + chalk11.red(" (e.g. choose Cursor) or set an API key."));
6496
5981
  throw new Error("__exit__");
6497
5982
  }
6498
5983
  if (isGitRepo()) {
@@ -6502,20 +5987,20 @@ async function refreshCommand(options) {
6502
5987
  const repos = discoverGitRepos(process.cwd());
6503
5988
  if (repos.length === 0) {
6504
5989
  if (quiet) return;
6505
- console.log(chalk12.red("Not inside a git repository and no git repos found in child directories."));
5990
+ console.log(chalk11.red("Not inside a git repository and no git repos found in child directories."));
6506
5991
  throw new Error("__exit__");
6507
5992
  }
6508
- log(quiet, chalk12.dim(`Found ${repos.length} git repo${repos.length === 1 ? "" : "s"}
5993
+ log(quiet, chalk11.dim(`Found ${repos.length} git repo${repos.length === 1 ? "" : "s"}
6509
5994
  `));
6510
5995
  const originalDir = process.cwd();
6511
5996
  for (const repo of repos) {
6512
- const repoName = path19.basename(repo);
5997
+ const repoName = path18.basename(repo);
6513
5998
  try {
6514
5999
  process.chdir(repo);
6515
6000
  await refreshSingleRepo(repo, { ...options, label: repoName });
6516
6001
  } catch (err) {
6517
6002
  if (err instanceof Error && err.message === "__exit__") continue;
6518
- log(quiet, chalk12.yellow(`${repoName}: refresh failed \u2014 ${err instanceof Error ? err.message : "unknown error"}`));
6003
+ log(quiet, chalk11.yellow(`${repoName}: refresh failed \u2014 ${err instanceof Error ? err.message : "unknown error"}`));
6519
6004
  }
6520
6005
  }
6521
6006
  process.chdir(originalDir);
@@ -6523,13 +6008,13 @@ async function refreshCommand(options) {
6523
6008
  if (err instanceof Error && err.message === "__exit__") throw err;
6524
6009
  if (quiet) return;
6525
6010
  const msg = err instanceof Error ? err.message : "Unknown error";
6526
- console.log(chalk12.red(`Refresh failed: ${msg}`));
6011
+ console.log(chalk11.red(`Refresh failed: ${msg}`));
6527
6012
  throw new Error("__exit__");
6528
6013
  }
6529
6014
  }
6530
6015
 
6531
6016
  // src/commands/hooks.ts
6532
- import chalk13 from "chalk";
6017
+ import chalk12 from "chalk";
6533
6018
  var HOOKS = [
6534
6019
  {
6535
6020
  id: "session-end",
@@ -6549,13 +6034,13 @@ var HOOKS = [
6549
6034
  }
6550
6035
  ];
6551
6036
  function printStatus() {
6552
- console.log(chalk13.bold("\n Hooks\n"));
6037
+ console.log(chalk12.bold("\n Hooks\n"));
6553
6038
  for (const hook of HOOKS) {
6554
6039
  const installed = hook.isInstalled();
6555
- const icon = installed ? chalk13.green("\u2713") : chalk13.dim("\u2717");
6556
- const state = installed ? chalk13.green("enabled") : chalk13.dim("disabled");
6040
+ const icon = installed ? chalk12.green("\u2713") : chalk12.dim("\u2717");
6041
+ const state = installed ? chalk12.green("enabled") : chalk12.dim("disabled");
6557
6042
  console.log(` ${icon} ${hook.label.padEnd(26)} ${state}`);
6558
- console.log(chalk13.dim(` ${hook.description}`));
6043
+ console.log(chalk12.dim(` ${hook.description}`));
6559
6044
  }
6560
6045
  console.log("");
6561
6046
  }
@@ -6564,9 +6049,9 @@ async function hooksCommand(options) {
6564
6049
  for (const hook of HOOKS) {
6565
6050
  const result = hook.install();
6566
6051
  if (result.alreadyInstalled) {
6567
- console.log(chalk13.dim(` ${hook.label} already enabled.`));
6052
+ console.log(chalk12.dim(` ${hook.label} already enabled.`));
6568
6053
  } else {
6569
- console.log(chalk13.green(" \u2713") + ` ${hook.label} enabled`);
6054
+ console.log(chalk12.green(" \u2713") + ` ${hook.label} enabled`);
6570
6055
  }
6571
6056
  }
6572
6057
  return;
@@ -6575,9 +6060,9 @@ async function hooksCommand(options) {
6575
6060
  for (const hook of HOOKS) {
6576
6061
  const result = hook.remove();
6577
6062
  if (result.notFound) {
6578
- console.log(chalk13.dim(` ${hook.label} already disabled.`));
6063
+ console.log(chalk12.dim(` ${hook.label} already disabled.`));
6579
6064
  } else {
6580
- console.log(chalk13.green(" \u2713") + ` ${hook.label} removed`);
6065
+ console.log(chalk12.green(" \u2713") + ` ${hook.label} removed`);
6581
6066
  }
6582
6067
  }
6583
6068
  return;
@@ -6592,18 +6077,18 @@ async function hooksCommand(options) {
6592
6077
  const states = HOOKS.map((h) => h.isInstalled());
6593
6078
  function render() {
6594
6079
  const lines = [];
6595
- lines.push(chalk13.bold(" Hooks"));
6080
+ lines.push(chalk12.bold(" Hooks"));
6596
6081
  lines.push("");
6597
6082
  for (let i = 0; i < HOOKS.length; i++) {
6598
6083
  const hook = HOOKS[i];
6599
6084
  const enabled = states[i];
6600
- const toggle = enabled ? chalk13.green("[on] ") : chalk13.dim("[off]");
6601
- const ptr = i === cursor ? chalk13.cyan(">") : " ";
6085
+ const toggle = enabled ? chalk12.green("[on] ") : chalk12.dim("[off]");
6086
+ const ptr = i === cursor ? chalk12.cyan(">") : " ";
6602
6087
  lines.push(` ${ptr} ${toggle} ${hook.label}`);
6603
- lines.push(chalk13.dim(` ${hook.description}`));
6088
+ lines.push(chalk12.dim(` ${hook.description}`));
6604
6089
  }
6605
6090
  lines.push("");
6606
- lines.push(chalk13.dim(" \u2191\u2193 navigate \u23B5 toggle a all on n all off \u23CE apply q cancel"));
6091
+ lines.push(chalk12.dim(" \u2191\u2193 navigate \u23B5 toggle a all on n all off \u23CE apply q cancel"));
6607
6092
  return lines.join("\n");
6608
6093
  }
6609
6094
  function draw(initial) {
@@ -6634,16 +6119,16 @@ async function hooksCommand(options) {
6634
6119
  const wantEnabled = states[i];
6635
6120
  if (wantEnabled && !wasInstalled) {
6636
6121
  hook.install();
6637
- console.log(chalk13.green(" \u2713") + ` ${hook.label} enabled`);
6122
+ console.log(chalk12.green(" \u2713") + ` ${hook.label} enabled`);
6638
6123
  changed++;
6639
6124
  } else if (!wantEnabled && wasInstalled) {
6640
6125
  hook.remove();
6641
- console.log(chalk13.green(" \u2713") + ` ${hook.label} disabled`);
6126
+ console.log(chalk12.green(" \u2713") + ` ${hook.label} disabled`);
6642
6127
  changed++;
6643
6128
  }
6644
6129
  }
6645
6130
  if (changed === 0) {
6646
- console.log(chalk13.dim(" No changes."));
6131
+ console.log(chalk12.dim(" No changes."));
6647
6132
  }
6648
6133
  console.log("");
6649
6134
  }
@@ -6679,7 +6164,7 @@ async function hooksCommand(options) {
6679
6164
  case "\x1B":
6680
6165
  case "":
6681
6166
  cleanup();
6682
- console.log(chalk13.dim("\n Cancelled.\n"));
6167
+ console.log(chalk12.dim("\n Cancelled.\n"));
6683
6168
  resolve2();
6684
6169
  break;
6685
6170
  }
@@ -6689,48 +6174,48 @@ async function hooksCommand(options) {
6689
6174
  }
6690
6175
 
6691
6176
  // src/commands/config.ts
6692
- import chalk14 from "chalk";
6177
+ import chalk13 from "chalk";
6693
6178
  async function configCommand() {
6694
6179
  const existing = loadConfig();
6695
6180
  if (existing) {
6696
6181
  const displayModel = existing.model === "default" && existing.provider === "claude-cli" ? process.env.ANTHROPIC_MODEL || "default (inherited from Claude Code)" : existing.model;
6697
6182
  const fastModel = getFastModel();
6698
- console.log(chalk14.bold("\nCurrent Configuration\n"));
6699
- console.log(` Provider: ${chalk14.cyan(existing.provider)}`);
6700
- console.log(` Model: ${chalk14.cyan(displayModel)}`);
6183
+ console.log(chalk13.bold("\nCurrent Configuration\n"));
6184
+ console.log(` Provider: ${chalk13.cyan(existing.provider)}`);
6185
+ console.log(` Model: ${chalk13.cyan(displayModel)}`);
6701
6186
  if (fastModel) {
6702
- console.log(` Scan: ${chalk14.cyan(fastModel)}`);
6187
+ console.log(` Scan: ${chalk13.cyan(fastModel)}`);
6703
6188
  }
6704
6189
  if (existing.apiKey) {
6705
6190
  const masked = existing.apiKey.slice(0, 8) + "..." + existing.apiKey.slice(-4);
6706
- console.log(` API Key: ${chalk14.dim(masked)}`);
6191
+ console.log(` API Key: ${chalk13.dim(masked)}`);
6707
6192
  }
6708
6193
  if (existing.provider === "cursor") {
6709
- console.log(` Seat: ${chalk14.dim("Cursor (agent acp)")}`);
6194
+ console.log(` Seat: ${chalk13.dim("Cursor (agent acp)")}`);
6710
6195
  }
6711
6196
  if (existing.provider === "claude-cli") {
6712
- console.log(` Seat: ${chalk14.dim("Claude Code (claude -p)")}`);
6197
+ console.log(` Seat: ${chalk13.dim("Claude Code (claude -p)")}`);
6713
6198
  }
6714
6199
  if (existing.baseUrl) {
6715
- console.log(` Base URL: ${chalk14.dim(existing.baseUrl)}`);
6200
+ console.log(` Base URL: ${chalk13.dim(existing.baseUrl)}`);
6716
6201
  }
6717
6202
  if (existing.vertexProjectId) {
6718
- console.log(` Vertex Project: ${chalk14.dim(existing.vertexProjectId)}`);
6719
- console.log(` Vertex Region: ${chalk14.dim(existing.vertexRegion || "us-east5")}`);
6203
+ console.log(` Vertex Project: ${chalk13.dim(existing.vertexProjectId)}`);
6204
+ console.log(` Vertex Region: ${chalk13.dim(existing.vertexRegion || "us-east5")}`);
6720
6205
  }
6721
- console.log(` Source: ${chalk14.dim(process.env.ANTHROPIC_API_KEY || process.env.OPENAI_API_KEY || process.env.VERTEX_PROJECT_ID || process.env.CALIBER_USE_CURSOR_SEAT || process.env.CALIBER_USE_CLAUDE_CLI ? "environment variables" : getConfigFilePath())}`);
6206
+ console.log(` Source: ${chalk13.dim(process.env.ANTHROPIC_API_KEY || process.env.OPENAI_API_KEY || process.env.VERTEX_PROJECT_ID || process.env.CALIBER_USE_CURSOR_SEAT || process.env.CALIBER_USE_CLAUDE_CLI ? "environment variables" : getConfigFilePath())}`);
6722
6207
  console.log("");
6723
6208
  }
6724
6209
  await runInteractiveProviderSetup();
6725
- console.log(chalk14.green("\n\u2713 Configuration saved"));
6726
- console.log(chalk14.dim(` ${getConfigFilePath()}
6210
+ console.log(chalk13.green("\n\u2713 Configuration saved"));
6211
+ console.log(chalk13.dim(` ${getConfigFilePath()}
6727
6212
  `));
6728
- console.log(chalk14.dim(" You can also set environment variables instead:"));
6729
- console.log(chalk14.dim(" ANTHROPIC_API_KEY, OPENAI_API_KEY, VERTEX_PROJECT_ID, CALIBER_USE_CURSOR_SEAT=1, or CALIBER_USE_CLAUDE_CLI=1\n"));
6213
+ console.log(chalk13.dim(" You can also set environment variables instead:"));
6214
+ console.log(chalk13.dim(" ANTHROPIC_API_KEY, OPENAI_API_KEY, VERTEX_PROJECT_ID, CALIBER_USE_CURSOR_SEAT=1, or CALIBER_USE_CLAUDE_CLI=1\n"));
6730
6215
  }
6731
6216
 
6732
6217
  // src/commands/learn.ts
6733
- import chalk15 from "chalk";
6218
+ import chalk14 from "chalk";
6734
6219
 
6735
6220
  // src/learner/stdin.ts
6736
6221
  var STDIN_TIMEOUT_MS = 5e3;
@@ -6761,8 +6246,8 @@ function readStdin() {
6761
6246
 
6762
6247
  // src/learner/storage.ts
6763
6248
  init_constants();
6764
- import fs26 from "fs";
6765
- import path20 from "path";
6249
+ import fs25 from "fs";
6250
+ import path19 from "path";
6766
6251
  var MAX_RESPONSE_LENGTH = 2e3;
6767
6252
  var DEFAULT_STATE = {
6768
6253
  sessionId: null,
@@ -6770,15 +6255,15 @@ var DEFAULT_STATE = {
6770
6255
  lastAnalysisTimestamp: null
6771
6256
  };
6772
6257
  function ensureLearningDir() {
6773
- if (!fs26.existsSync(LEARNING_DIR)) {
6774
- fs26.mkdirSync(LEARNING_DIR, { recursive: true });
6258
+ if (!fs25.existsSync(LEARNING_DIR)) {
6259
+ fs25.mkdirSync(LEARNING_DIR, { recursive: true });
6775
6260
  }
6776
6261
  }
6777
6262
  function sessionFilePath() {
6778
- return path20.join(LEARNING_DIR, LEARNING_SESSION_FILE);
6263
+ return path19.join(LEARNING_DIR, LEARNING_SESSION_FILE);
6779
6264
  }
6780
6265
  function stateFilePath() {
6781
- return path20.join(LEARNING_DIR, LEARNING_STATE_FILE);
6266
+ return path19.join(LEARNING_DIR, LEARNING_STATE_FILE);
6782
6267
  }
6783
6268
  function truncateResponse(response) {
6784
6269
  const str = JSON.stringify(response);
@@ -6789,50 +6274,50 @@ function appendEvent(event) {
6789
6274
  ensureLearningDir();
6790
6275
  const truncated = { ...event, tool_response: truncateResponse(event.tool_response) };
6791
6276
  const filePath = sessionFilePath();
6792
- fs26.appendFileSync(filePath, JSON.stringify(truncated) + "\n");
6277
+ fs25.appendFileSync(filePath, JSON.stringify(truncated) + "\n");
6793
6278
  const count = getEventCount();
6794
6279
  if (count > LEARNING_MAX_EVENTS) {
6795
- const lines = fs26.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
6280
+ const lines = fs25.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
6796
6281
  const kept = lines.slice(lines.length - LEARNING_MAX_EVENTS);
6797
- fs26.writeFileSync(filePath, kept.join("\n") + "\n");
6282
+ fs25.writeFileSync(filePath, kept.join("\n") + "\n");
6798
6283
  }
6799
6284
  }
6800
6285
  function readAllEvents() {
6801
6286
  const filePath = sessionFilePath();
6802
- if (!fs26.existsSync(filePath)) return [];
6803
- const lines = fs26.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
6287
+ if (!fs25.existsSync(filePath)) return [];
6288
+ const lines = fs25.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
6804
6289
  return lines.map((line) => JSON.parse(line));
6805
6290
  }
6806
6291
  function getEventCount() {
6807
6292
  const filePath = sessionFilePath();
6808
- if (!fs26.existsSync(filePath)) return 0;
6809
- const content = fs26.readFileSync(filePath, "utf-8");
6293
+ if (!fs25.existsSync(filePath)) return 0;
6294
+ const content = fs25.readFileSync(filePath, "utf-8");
6810
6295
  return content.split("\n").filter(Boolean).length;
6811
6296
  }
6812
6297
  function clearSession() {
6813
6298
  const filePath = sessionFilePath();
6814
- if (fs26.existsSync(filePath)) fs26.unlinkSync(filePath);
6299
+ if (fs25.existsSync(filePath)) fs25.unlinkSync(filePath);
6815
6300
  }
6816
6301
  function readState2() {
6817
6302
  const filePath = stateFilePath();
6818
- if (!fs26.existsSync(filePath)) return { ...DEFAULT_STATE };
6303
+ if (!fs25.existsSync(filePath)) return { ...DEFAULT_STATE };
6819
6304
  try {
6820
- return JSON.parse(fs26.readFileSync(filePath, "utf-8"));
6305
+ return JSON.parse(fs25.readFileSync(filePath, "utf-8"));
6821
6306
  } catch {
6822
6307
  return { ...DEFAULT_STATE };
6823
6308
  }
6824
6309
  }
6825
6310
  function writeState2(state) {
6826
6311
  ensureLearningDir();
6827
- fs26.writeFileSync(stateFilePath(), JSON.stringify(state, null, 2));
6312
+ fs25.writeFileSync(stateFilePath(), JSON.stringify(state, null, 2));
6828
6313
  }
6829
6314
  function resetState() {
6830
6315
  writeState2({ ...DEFAULT_STATE });
6831
6316
  }
6832
6317
 
6833
6318
  // src/learner/writer.ts
6834
- import fs27 from "fs";
6835
- import path21 from "path";
6319
+ import fs26 from "fs";
6320
+ import path20 from "path";
6836
6321
  var LEARNED_START = "<!-- caliber:learned -->";
6837
6322
  var LEARNED_END = "<!-- /caliber:learned -->";
6838
6323
  function writeLearnedContent(update) {
@@ -6852,8 +6337,8 @@ function writeLearnedContent(update) {
6852
6337
  function writeLearnedSection(content) {
6853
6338
  const claudeMdPath = "CLAUDE.md";
6854
6339
  let existing = "";
6855
- if (fs27.existsSync(claudeMdPath)) {
6856
- existing = fs27.readFileSync(claudeMdPath, "utf-8");
6340
+ if (fs26.existsSync(claudeMdPath)) {
6341
+ existing = fs26.readFileSync(claudeMdPath, "utf-8");
6857
6342
  }
6858
6343
  const section = `${LEARNED_START}
6859
6344
  ${content}
@@ -6867,15 +6352,15 @@ ${LEARNED_END}`;
6867
6352
  const separator = existing.endsWith("\n") || existing === "" ? "" : "\n";
6868
6353
  updated = existing + separator + "\n" + section + "\n";
6869
6354
  }
6870
- fs27.writeFileSync(claudeMdPath, updated);
6355
+ fs26.writeFileSync(claudeMdPath, updated);
6871
6356
  }
6872
6357
  function writeLearnedSkill(skill) {
6873
- const skillDir = path21.join(".claude", "skills", skill.name);
6874
- if (!fs27.existsSync(skillDir)) fs27.mkdirSync(skillDir, { recursive: true });
6875
- const skillPath = path21.join(skillDir, "SKILL.md");
6876
- if (!skill.isNew && fs27.existsSync(skillPath)) {
6877
- const existing = fs27.readFileSync(skillPath, "utf-8");
6878
- fs27.writeFileSync(skillPath, existing.trimEnd() + "\n\n" + skill.content);
6358
+ const skillDir = path20.join(".claude", "skills", skill.name);
6359
+ if (!fs26.existsSync(skillDir)) fs26.mkdirSync(skillDir, { recursive: true });
6360
+ const skillPath = path20.join(skillDir, "SKILL.md");
6361
+ if (!skill.isNew && fs26.existsSync(skillPath)) {
6362
+ const existing = fs26.readFileSync(skillPath, "utf-8");
6363
+ fs26.writeFileSync(skillPath, existing.trimEnd() + "\n\n" + skill.content);
6879
6364
  } else {
6880
6365
  const frontmatter = [
6881
6366
  "---",
@@ -6884,14 +6369,14 @@ function writeLearnedSkill(skill) {
6884
6369
  "---",
6885
6370
  ""
6886
6371
  ].join("\n");
6887
- fs27.writeFileSync(skillPath, frontmatter + skill.content);
6372
+ fs26.writeFileSync(skillPath, frontmatter + skill.content);
6888
6373
  }
6889
6374
  return skillPath;
6890
6375
  }
6891
6376
  function readLearnedSection() {
6892
6377
  const claudeMdPath = "CLAUDE.md";
6893
- if (!fs27.existsSync(claudeMdPath)) return null;
6894
- const content = fs27.readFileSync(claudeMdPath, "utf-8");
6378
+ if (!fs26.existsSync(claudeMdPath)) return null;
6379
+ const content = fs26.readFileSync(claudeMdPath, "utf-8");
6895
6380
  const startIdx = content.indexOf(LEARNED_START);
6896
6381
  const endIdx = content.indexOf(LEARNED_END);
6897
6382
  if (startIdx === -1 || endIdx === -1) return null;
@@ -7033,53 +6518,53 @@ async function learnFinalizeCommand() {
7033
6518
  async function learnInstallCommand() {
7034
6519
  const result = installLearningHooks();
7035
6520
  if (result.alreadyInstalled) {
7036
- console.log(chalk15.dim("Learning hooks already installed."));
6521
+ console.log(chalk14.dim("Learning hooks already installed."));
7037
6522
  return;
7038
6523
  }
7039
- console.log(chalk15.green("\u2713") + " Learning hooks installed in .claude/settings.json");
7040
- console.log(chalk15.dim(" PostToolUse, PostToolUseFailure, and SessionEnd hooks active."));
7041
- console.log(chalk15.dim(" Session learnings will be written to CLAUDE.md and skills."));
6524
+ console.log(chalk14.green("\u2713") + " Learning hooks installed in .claude/settings.json");
6525
+ console.log(chalk14.dim(" PostToolUse, PostToolUseFailure, and SessionEnd hooks active."));
6526
+ console.log(chalk14.dim(" Session learnings will be written to CLAUDE.md and skills."));
7042
6527
  }
7043
6528
  async function learnRemoveCommand() {
7044
6529
  const result = removeLearningHooks();
7045
6530
  if (result.notFound) {
7046
- console.log(chalk15.dim("Learning hooks not found."));
6531
+ console.log(chalk14.dim("Learning hooks not found."));
7047
6532
  return;
7048
6533
  }
7049
- console.log(chalk15.green("\u2713") + " Learning hooks removed from .claude/settings.json");
6534
+ console.log(chalk14.green("\u2713") + " Learning hooks removed from .claude/settings.json");
7050
6535
  }
7051
6536
  async function learnStatusCommand() {
7052
6537
  const installed = areLearningHooksInstalled();
7053
6538
  const state = readState2();
7054
6539
  const eventCount = getEventCount();
7055
- console.log(chalk15.bold("Session Learning Status"));
6540
+ console.log(chalk14.bold("Session Learning Status"));
7056
6541
  console.log();
7057
6542
  if (installed) {
7058
- console.log(chalk15.green("\u2713") + " Learning hooks are " + chalk15.green("installed"));
6543
+ console.log(chalk14.green("\u2713") + " Learning hooks are " + chalk14.green("installed"));
7059
6544
  } else {
7060
- console.log(chalk15.dim("\u2717") + " Learning hooks are " + chalk15.yellow("not installed"));
7061
- console.log(chalk15.dim(" Run `caliber learn install` to enable session learning."));
6545
+ console.log(chalk14.dim("\u2717") + " Learning hooks are " + chalk14.yellow("not installed"));
6546
+ console.log(chalk14.dim(" Run `caliber learn install` to enable session learning."));
7062
6547
  }
7063
6548
  console.log();
7064
- console.log(`Events recorded: ${chalk15.cyan(String(eventCount))}`);
7065
- console.log(`Total this session: ${chalk15.cyan(String(state.eventCount))}`);
6549
+ console.log(`Events recorded: ${chalk14.cyan(String(eventCount))}`);
6550
+ console.log(`Total this session: ${chalk14.cyan(String(state.eventCount))}`);
7066
6551
  if (state.lastAnalysisTimestamp) {
7067
- console.log(`Last analysis: ${chalk15.cyan(state.lastAnalysisTimestamp)}`);
6552
+ console.log(`Last analysis: ${chalk14.cyan(state.lastAnalysisTimestamp)}`);
7068
6553
  } else {
7069
- console.log(`Last analysis: ${chalk15.dim("none")}`);
6554
+ console.log(`Last analysis: ${chalk14.dim("none")}`);
7070
6555
  }
7071
6556
  const learnedSection = readLearnedSection();
7072
6557
  if (learnedSection) {
7073
6558
  const lineCount = learnedSection.split("\n").filter(Boolean).length;
7074
6559
  console.log(`
7075
- Learned items in CLAUDE.md: ${chalk15.cyan(String(lineCount))}`);
6560
+ Learned items in CLAUDE.md: ${chalk14.cyan(String(lineCount))}`);
7076
6561
  }
7077
6562
  }
7078
6563
 
7079
6564
  // src/cli.ts
7080
- var __dirname = path22.dirname(fileURLToPath(import.meta.url));
6565
+ var __dirname = path21.dirname(fileURLToPath(import.meta.url));
7081
6566
  var pkg = JSON.parse(
7082
- fs28.readFileSync(path22.resolve(__dirname, "..", "package.json"), "utf-8")
6567
+ fs27.readFileSync(path21.resolve(__dirname, "..", "package.json"), "utf-8")
7083
6568
  );
7084
6569
  var program = new Command();
7085
6570
  var displayVersion = process.env.CALIBER_LOCAL ? `${pkg.version}-local` : pkg.version;
@@ -7112,22 +6597,22 @@ learn.command("remove").description("Remove learning hooks from .claude/settings
7112
6597
  learn.command("status").description("Show learning system status").action(learnStatusCommand);
7113
6598
 
7114
6599
  // src/utils/version-check.ts
7115
- import fs29 from "fs";
7116
- import path23 from "path";
6600
+ import fs28 from "fs";
6601
+ import path22 from "path";
7117
6602
  import { fileURLToPath as fileURLToPath2 } from "url";
7118
6603
  import { execSync as execSync9 } from "child_process";
7119
- import chalk16 from "chalk";
7120
- import ora7 from "ora";
6604
+ import chalk15 from "chalk";
6605
+ import ora6 from "ora";
7121
6606
  import confirm from "@inquirer/confirm";
7122
- var __dirname_vc = path23.dirname(fileURLToPath2(import.meta.url));
6607
+ var __dirname_vc = path22.dirname(fileURLToPath2(import.meta.url));
7123
6608
  var pkg2 = JSON.parse(
7124
- fs29.readFileSync(path23.resolve(__dirname_vc, "..", "package.json"), "utf-8")
6609
+ fs28.readFileSync(path22.resolve(__dirname_vc, "..", "package.json"), "utf-8")
7125
6610
  );
7126
6611
  function getInstalledVersion() {
7127
6612
  try {
7128
6613
  const globalRoot = execSync9("npm root -g", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
7129
- const pkgPath = path23.join(globalRoot, "@rely-ai", "caliber", "package.json");
7130
- return JSON.parse(fs29.readFileSync(pkgPath, "utf-8")).version;
6614
+ const pkgPath = path22.join(globalRoot, "@rely-ai", "caliber", "package.json");
6615
+ return JSON.parse(fs28.readFileSync(pkgPath, "utf-8")).version;
7131
6616
  } catch {
7132
6617
  return null;
7133
6618
  }
@@ -7150,17 +6635,17 @@ async function checkForUpdates() {
7150
6635
  const isInteractive = process.stdin.isTTY === true;
7151
6636
  if (!isInteractive) {
7152
6637
  console.log(
7153
- chalk16.yellow(
6638
+ chalk15.yellow(
7154
6639
  `
7155
6640
  Update available: ${current} -> ${latest}
7156
- Run ${chalk16.bold("npm install -g @rely-ai/caliber")} to upgrade.
6641
+ Run ${chalk15.bold("npm install -g @rely-ai/caliber")} to upgrade.
7157
6642
  `
7158
6643
  )
7159
6644
  );
7160
6645
  return;
7161
6646
  }
7162
6647
  console.log(
7163
- chalk16.yellow(`
6648
+ chalk15.yellow(`
7164
6649
  Update available: ${current} -> ${latest}`)
7165
6650
  );
7166
6651
  const shouldUpdate = await confirm({ message: "Would you like to update now? (Y/n)", default: true });
@@ -7168,7 +6653,7 @@ Update available: ${current} -> ${latest}`)
7168
6653
  console.log();
7169
6654
  return;
7170
6655
  }
7171
- const spinner = ora7("Updating caliber...").start();
6656
+ const spinner = ora6("Updating caliber...").start();
7172
6657
  try {
7173
6658
  execSync9(`npm install -g @rely-ai/caliber@${latest}`, {
7174
6659
  stdio: "pipe",
@@ -7178,13 +6663,13 @@ Update available: ${current} -> ${latest}`)
7178
6663
  const installed = getInstalledVersion();
7179
6664
  if (installed !== latest) {
7180
6665
  spinner.fail(`Update incomplete \u2014 got ${installed ?? "unknown"}, expected ${latest}`);
7181
- console.log(chalk16.yellow(`Run ${chalk16.bold(`npm install -g @rely-ai/caliber@${latest}`)} manually.
6666
+ console.log(chalk15.yellow(`Run ${chalk15.bold(`npm install -g @rely-ai/caliber@${latest}`)} manually.
7182
6667
  `));
7183
6668
  return;
7184
6669
  }
7185
- spinner.succeed(chalk16.green(`Updated to ${latest}`));
6670
+ spinner.succeed(chalk15.green(`Updated to ${latest}`));
7186
6671
  const args = process.argv.slice(2);
7187
- console.log(chalk16.dim(`
6672
+ console.log(chalk15.dim(`
7188
6673
  Restarting: caliber ${args.join(" ")}
7189
6674
  `));
7190
6675
  execSync9(`caliber ${args.map((a) => JSON.stringify(a)).join(" ")}`, {
@@ -7197,11 +6682,11 @@ Restarting: caliber ${args.join(" ")}
7197
6682
  if (err instanceof Error) {
7198
6683
  const stderr = err.stderr;
7199
6684
  const errMsg = stderr ? String(stderr).trim().split("\n").pop() : err.message.split("\n")[0];
7200
- if (errMsg && !errMsg.includes("SIGTERM")) console.log(chalk16.dim(` ${errMsg}`));
6685
+ if (errMsg && !errMsg.includes("SIGTERM")) console.log(chalk15.dim(` ${errMsg}`));
7201
6686
  }
7202
6687
  console.log(
7203
- chalk16.yellow(
7204
- `Run ${chalk16.bold(`npm install -g @rely-ai/caliber@${latest}`)} manually to upgrade.
6688
+ chalk15.yellow(
6689
+ `Run ${chalk15.bold(`npm install -g @rely-ai/caliber@${latest}`)} manually to upgrade.
7205
6690
  `
7206
6691
  )
7207
6692
  );