@rely-ai/caliber 1.18.1 → 1.18.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/dist/bin.js +493 -509
  3. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -26,6 +26,7 @@ __export(config_exports, {
26
26
  DEFAULT_FAST_MODELS: () => DEFAULT_FAST_MODELS,
27
27
  DEFAULT_MODELS: () => DEFAULT_MODELS,
28
28
  getConfigFilePath: () => getConfigFilePath,
29
+ getDisplayModel: () => getDisplayModel,
29
30
  getFastModel: () => getFastModel,
30
31
  loadConfig: () => loadConfig,
31
32
  readConfigFile: () => readConfigFile,
@@ -105,6 +106,12 @@ function writeConfigFile(config) {
105
106
  function getConfigFilePath() {
106
107
  return CONFIG_FILE;
107
108
  }
109
+ function getDisplayModel(config) {
110
+ if (config.model === "default" && config.provider === "claude-cli") {
111
+ return process.env.ANTHROPIC_MODEL || "default (inherited from Claude Code)";
112
+ }
113
+ return config.model;
114
+ }
108
115
  function getFastModel() {
109
116
  if (process.env.CALIBER_FAST_MODEL) return process.env.CALIBER_FAST_MODEL;
110
117
  if (process.env.ANTHROPIC_SMALL_FAST_MODEL) return process.env.ANTHROPIC_SMALL_FAST_MODEL;
@@ -218,9 +225,8 @@ import { fileURLToPath } from "url";
218
225
 
219
226
  // src/commands/init.ts
220
227
  import path19 from "path";
221
- import chalk8 from "chalk";
228
+ import chalk9 from "chalk";
222
229
  import ora2 from "ora";
223
- import readline3 from "readline";
224
230
  import select5 from "@inquirer/select";
225
231
  import checkbox from "@inquirer/checkbox";
226
232
  import fs24 from "fs";
@@ -1753,31 +1759,21 @@ async function validateModel(options) {
1753
1759
  init_config();
1754
1760
 
1755
1761
  // src/ai/prompts.ts
1756
- var GENERATION_SYSTEM_PROMPT = `You are an expert auditor for coding agent configurations (Claude Code, Cursor, and Codex).
1762
+ var ROLE_AND_CONTEXT = `You are an expert auditor for coding agent configurations (Claude Code, Cursor, and Codex).
1757
1763
 
1758
1764
  Your job depends on context:
1759
1765
  - If no existing configs exist \u2192 generate an initial setup from scratch.
1760
- - If existing configs are provided \u2192 audit them and suggest targeted improvements. Preserve accurate content \u2014 don't rewrite what's already correct.
1761
-
1762
- You understand these config files:
1766
+ - If existing configs are provided \u2192 audit them and suggest targeted improvements. Preserve accurate content \u2014 don't rewrite what's already correct.`;
1767
+ var CONFIG_FILE_TYPES = `You understand these config files:
1763
1768
  - CLAUDE.md: Project context for Claude Code \u2014 build/test commands, architecture, conventions.
1764
1769
  - AGENTS.md: Primary instructions file for OpenAI Codex \u2014 same purpose as CLAUDE.md but for the Codex agent. Also serves as a cross-agent coordination file.
1765
1770
  - .claude/skills/{name}/SKILL.md: Skill files following the OpenSkills standard (agentskills.io). Each skill is a directory named after the skill, containing a SKILL.md with YAML frontmatter.
1766
1771
  - .agents/skills/{name}/SKILL.md: Same OpenSkills format for Codex skills (Codex scans .agents/skills/ for skills).
1772
+ - .cursor/skills/{name}/SKILL.md: Same OpenSkills format for Cursor skills.
1767
1773
  - .cursorrules: Coding rules for Cursor (deprecated legacy format \u2014 do NOT generate this).
1768
- - .cursor/rules/*.mdc: Modern Cursor rules with frontmatter (description, globs, alwaysApply).
1769
- - .cursor/skills/{name}/SKILL.md: Same OpenSkills format as Claude skills.
1770
-
1771
- Audit checklist (when existing configs are provided):
1772
- 1. CLAUDE.md / README accuracy \u2014 do documented commands, paths, and architecture match the actual codebase?
1773
- 2. Missing skills \u2014 are there detected tools/frameworks that should have dedicated skills?
1774
- 3. Duplicate or overlapping skills \u2014 can any be merged or removed?
1775
- 4. Undocumented conventions \u2014 are there code patterns (commit style, async patterns, error handling) not captured in docs?
1776
- 5. Stale references \u2014 do docs mention removed files, renamed commands, or outdated patterns?
1777
-
1778
- Do NOT generate .claude/settings.json or .claude/settings.local.json \u2014 those are managed by the user directly.
1779
-
1780
- Your output MUST follow this exact format (no markdown fences):
1774
+ - .cursor/rules/*.mdc: Modern Cursor rules with frontmatter (description, globs, alwaysApply).`;
1775
+ var EXCLUSIONS = `Do NOT generate .claude/settings.json, .claude/settings.local.json, or mcpServers \u2014 those are managed separately.`;
1776
+ var OUTPUT_FORMAT = `Your output MUST follow this exact format (no markdown fences):
1781
1777
 
1782
1778
  1. Exactly 6 short status lines (one per line, prefixed with "STATUS: "). Each should be a creative, specific description of what you're analyzing for THIS project \u2014 reference the project's actual languages, frameworks, or tools.
1783
1779
 
@@ -1791,34 +1787,11 @@ EXPLAIN:
1791
1787
 
1792
1788
  Omit empty categories. Keep each reason punchy and specific. End with a blank line.
1793
1789
 
1794
- 3. The JSON object starting with {.
1790
+ 3. The JSON object starting with {.`;
1791
+ var FILE_DESCRIPTIONS_RULES = `The "fileDescriptions" object MUST include a one-liner for every file that will be created or modified. Use actual file paths as keys (e.g. "CLAUDE.md", "AGENTS.md", ".claude/skills/my-skill/SKILL.md", ".agents/skills/my-skill/SKILL.md", ".cursor/skills/my-skill/SKILL.md", ".cursor/rules/my-rule.mdc"). Each description should explain why the change is needed, be concise and lowercase.
1795
1792
 
1796
- AgentSetup schema:
1797
- {
1798
- "targetAgent": ["claude", "cursor", "codex"] (array of selected agents),
1799
- "fileDescriptions": {
1800
- "<file-path>": "reason for this change (max 80 chars)"
1801
- },
1802
- "deletions": [
1803
- { "filePath": "<path>", "reason": "why remove (max 80 chars)" }
1804
- ],
1805
- "claude": {
1806
- "claudeMd": "string (markdown content for CLAUDE.md)",
1807
- "skills": [{ "name": "string (kebab-case, matches directory name)", "description": "string (what this skill does and when to use it)", "content": "string (markdown body \u2014 NO frontmatter, it will be generated from name+description)" }]
1808
- },
1809
- "codex": {
1810
- "agentsMd": "string (markdown content for AGENTS.md \u2014 the primary Codex instructions file, same quality/structure as CLAUDE.md)",
1811
- "skills": [{ "name": "string (kebab-case, matches directory name)", "description": "string (what this skill does and when to use it)", "content": "string (markdown body \u2014 NO frontmatter, it will be generated from name+description)" }]
1812
- },
1813
- "cursor": {
1814
- "skills": [{ "name": "string (kebab-case, matches directory name)", "description": "string (what this skill does and when to use it)", "content": "string (markdown body \u2014 NO frontmatter, it will be generated from name+description)" }],
1815
- "rules": [{ "filename": "string.mdc", "content": "string (with frontmatter)" }]
1816
- }
1817
- }
1818
-
1819
- Do NOT generate mcpServers \u2014 MCP configuration is managed separately.
1820
-
1821
- All skills follow the OpenSkills standard (agentskills.io). Anthropic's official skill guide defines three levels of progressive disclosure:
1793
+ The "deletions" array should list files that should be removed (e.g. duplicate skills, stale configs). Include a reason for each. Omit the array or leave empty if nothing should be deleted.`;
1794
+ var SKILL_FORMAT_RULES = `All skills follow the OpenSkills standard (agentskills.io). Anthropic's official skill guide defines three levels of progressive disclosure:
1822
1795
  - Level 1 (YAML frontmatter): Always loaded. Must have enough info for the agent to decide when to activate the skill.
1823
1796
  - Level 2 (SKILL.md body): Loaded when the skill is relevant. Contains full instructions.
1824
1797
  - Level 3 (references/): Only loaded on demand for deep detail.
@@ -1834,84 +1807,93 @@ Skill content structure \u2014 follow this template:
1834
1807
  3. "## Examples" \u2014 at least one example showing: User says \u2192 Actions taken \u2192 Result
1835
1808
  4. "## Troubleshooting" (optional) \u2014 common errors and how to fix them
1836
1809
 
1837
- Keep skill content under 200 lines. Focus on actionable instructions, not documentation prose.
1838
-
1839
- The "fileDescriptions" object MUST include a one-liner for every file that will be created or modified. Use actual file paths as keys (e.g. "CLAUDE.md", "AGENTS.md", ".claude/skills/my-skill/SKILL.md", ".agents/skills/my-skill/SKILL.md", ".cursor/skills/my-skill/SKILL.md", ".cursor/rules/my-rule.mdc"). Each description should explain why the change is needed, be concise and lowercase.
1840
-
1841
- The "deletions" array should list files that should be removed (e.g. duplicate skills, stale configs). Include a reason for each. Omit the array or leave empty if nothing should be deleted.
1842
-
1843
- SCORING CRITERIA \u2014 your output is scored deterministically. Optimize for 100/100:
1810
+ Keep skill content under 200 lines. Focus on actionable instructions, not documentation prose.`;
1811
+ var SCORING_CRITERIA = `SCORING CRITERIA \u2014 your output is scored deterministically against the actual filesystem. Optimize for 100/100:
1844
1812
 
1845
1813
  Existence (25 pts):
1846
- - CLAUDE.md exists (6 pts) \u2014 always generate for claude/both targets
1847
- - AGENTS.md exists (6 pts) \u2014 always generate for codex target (serves as primary instructions file)
1848
- - Skills configured (8 pts) \u2014 generate at least 3 skills for full points. Generate more if the project has multiple distinct tools, frameworks, or workflows that benefit from dedicated skills.
1849
- - MCP servers mentioned (3 pts) \u2014 reference detected MCP integrations
1850
- - For "both" target: .cursorrules/.cursor/rules/ exist (3+3 pts), cross-platform parity (2 pts)
1814
+ - CLAUDE.md exists (6 pts) \u2014 always generate for claude targets
1815
+ - AGENTS.md exists (6 pts) \u2014 always generate for codex target
1816
+ - Skills configured (8 pts) \u2014 generate 3+ skills for full points
1817
+ - MCP servers referenced (3 pts) \u2014 mention detected MCP integrations in your config text
1818
+ - When cursor is targeted: Cursor rules exist (3+3 pts), cross-platform parity (2 pts)
1851
1819
 
1852
1820
  Quality (25 pts):
1853
- - Build/test/lint commands documented (8 pts) \u2014 include actual commands from the project
1854
- - Concise context files (6 pts) \u2014 keep CLAUDE.md under 150 lines for full points (200=4pts, 300=3pts, 500+=0pts)
1855
- - No vague instructions (4 pts) \u2014 avoid "follow best practices", "write clean code", "ensure quality"
1821
+ - Executable content (8 pts) \u2014 include 3+ code blocks with actual project commands (3 blocks = full points, 2 = 6pts, 1 = 3pts)
1822
+ - Concise config (6 pts) \u2014 total tokens across ALL config files must be under 2000 for full points (3500=5pts, 5000=4pts, 8000+=low)
1823
+ - Concrete instructions (4 pts) \u2014 every line should reference specific files, paths, or code in backticks. Avoid generic prose like "follow best practices" or "write clean code".
1856
1824
  - No directory tree listings (3 pts) \u2014 do NOT include tree-style file listings in code blocks
1857
- - No contradictions (2 pts) \u2014 consistent tool/style recommendations
1858
-
1859
- Coverage (20 pts):
1860
- - Dependency coverage (10 pts) \u2014 CRITICAL: the exact dependency list is provided in your input under "DEPENDENCY COVERAGE". Mention AT LEAST 85% of them by name in CLAUDE.md or skills. You get full points at 85%+, proportional below that. Weave them naturally into architecture, key deps, and conventions sections.
1861
- - Service/MCP coverage (6 pts) \u2014 reference detected services (DB, cloud, etc.)
1862
- - MCP completeness (4 pts) \u2014 full points if no external services detected
1863
-
1864
- Accuracy (15 pts) \u2014 THIS IS CRITICAL, READ CAREFULLY:
1865
- - Documented commands exist (6 pts) \u2014 the scoring system validates EVERY command you write against the project's actual package.json scripts, Makefile targets, or Cargo.toml. If you write "yarn build" but there is no "build" script in package.json, you LOSE points. Rules:
1866
- * Look at the "scripts" section in the provided package.json. ONLY reference scripts that exist there.
1867
- * If a project uses Makefiles, only reference targets that exist in the Makefile.
1868
- * If there are no build/test scripts, do NOT invent them. Document what actually exists.
1869
- * Use the exact package manager the project uses (npm/yarn/pnpm/bun) \u2014 check the lockfile.
1870
- - Documented paths exist (4 pts) \u2014 ONLY reference file paths from the provided file tree. Never guess paths.
1871
- - Config freshness (5 pts) \u2014 config must match current code state
1872
-
1873
- Freshness & Safety (10 pts):
1874
- - No secrets in configs (4 pts) \u2014 never include API keys, tokens, or credentials
1875
- - Permissions configured (2 pts) \u2014 handled by caliber, not your responsibility
1876
-
1877
- Bonus (5 pts):
1878
- - Hooks configured (2 pts), AGENTS.md (1 pt), OpenSkills format (2 pts) \u2014 handled by caliber
1879
-
1880
- OUTPUT SIZE CONSTRAINTS \u2014 these are critical:
1825
+ - No duplicate content (2 pts) \u2014 don't repeat the same content across CLAUDE.md and cursor rules
1826
+ - Structured with headings (2 pts) \u2014 use at least 3 ## sections and bullet lists
1827
+
1828
+ Grounding (20 pts) \u2014 CRITICAL:
1829
+ - Project grounding (12 pts) \u2014 reference the project's actual directories and files by name. The scoring checks which project dirs/files from the file tree appear in your config. Mention key directories and files. (50%+ coverage = full points, 35% = 9pts, 20% = 6pts, 10% = 3pts)
1830
+ - Reference density (8 pts) \u2014 use backticks and inline code extensively. Every file path, command, or identifier should be in backticks. Higher density of backtick references per line = higher score. (40%+ = full, 25% = 6pts, 15% = 4pts)
1831
+
1832
+ Accuracy (15 pts) \u2014 CRITICAL:
1833
+ - References valid (8 pts) \u2014 ONLY reference file paths that exist in the provided file tree. Every path in backticks is validated against the filesystem. If you write a path that doesn't exist, you LOSE points.
1834
+ - Config drift (7 pts) \u2014 handled automatically by caliber (git-based), not your responsibility.
1835
+
1836
+ Safety: Never include API keys, tokens, or credentials in config files.
1837
+
1838
+ Note: Permissions, hooks, freshness tracking, and OpenSkills frontmatter are scored automatically by caliber \u2014 do not optimize for them.`;
1839
+ var OUTPUT_SIZE_CONSTRAINTS = `OUTPUT SIZE CONSTRAINTS \u2014 these are critical:
1881
1840
  - CLAUDE.md / AGENTS.md: MUST be under 150 lines for maximum score. Aim for 100-140 lines. Be concise \u2014 commands, architecture overview, and key conventions. Use bullet points and tables, not prose.
1882
- - Skills: generate 3-6 skills per target platform based on project complexity. Each skill should cover a distinct tool, workflow, or domain \u2014 don't pad with generic skills.
1883
1841
  - Each skill content: max 150 lines. Focus on patterns and examples, not exhaustive docs.
1884
1842
  - Cursor rules: max 5 .mdc files.
1885
1843
  - If the project is large, prioritize depth on the 3-4 most critical tools over breadth across everything.`;
1886
- var CORE_GENERATION_PROMPT = `You are an expert auditor for coding agent configurations (Claude Code, Cursor, and Codex).
1844
+ var GENERATION_SYSTEM_PROMPT = `${ROLE_AND_CONTEXT}
1887
1845
 
1888
- Your job depends on context:
1889
- - If no existing configs exist \u2192 generate an initial setup from scratch.
1890
- - If existing configs are provided \u2192 audit them and suggest targeted improvements. Preserve accurate content \u2014 don't rewrite what's already correct.
1846
+ ${CONFIG_FILE_TYPES}
1891
1847
 
1892
- You understand these config files:
1893
- - CLAUDE.md: Project context for Claude Code \u2014 build/test commands, architecture, conventions.
1894
- - AGENTS.md: Primary instructions file for OpenAI Codex \u2014 same purpose as CLAUDE.md but for the Codex agent.
1895
- - .cursorrules: Coding rules for Cursor (deprecated legacy format \u2014 do NOT generate this).
1896
- - .cursor/rules/*.mdc: Modern Cursor rules with frontmatter (description, globs, alwaysApply).
1848
+ Audit checklist (when existing configs are provided):
1849
+ 1. CLAUDE.md / README accuracy \u2014 do documented commands, paths, and architecture match the actual codebase?
1850
+ 2. Missing skills \u2014 are there detected tools/frameworks that should have dedicated skills?
1851
+ 3. Duplicate or overlapping skills \u2014 can any be merged or removed?
1852
+ 4. Undocumented conventions \u2014 are there code patterns (commit style, async patterns, error handling) not captured in docs?
1853
+ 5. Stale references \u2014 do docs mention removed files, renamed commands, or outdated patterns?
1897
1854
 
1898
- Do NOT generate .claude/settings.json, .claude/settings.local.json, or mcpServers.
1855
+ ${EXCLUSIONS}
1899
1856
 
1900
- Your output MUST follow this exact format (no markdown fences):
1857
+ ${OUTPUT_FORMAT}
1901
1858
 
1902
- 1. Exactly 6 short status lines (one per line, prefixed with "STATUS: "). Each should be a creative, specific description of what you're analyzing for THIS project \u2014 reference the project's actual languages, frameworks, or tools.
1859
+ AgentSetup schema:
1860
+ {
1861
+ "targetAgent": ["claude", "cursor", "codex"] (array of selected agents),
1862
+ "fileDescriptions": {
1863
+ "<file-path>": "reason for this change (max 80 chars)"
1864
+ },
1865
+ "deletions": [
1866
+ { "filePath": "<path>", "reason": "why remove (max 80 chars)" }
1867
+ ],
1868
+ "claude": {
1869
+ "claudeMd": "string (markdown content for CLAUDE.md)",
1870
+ "skills": [{ "name": "string (kebab-case, matches directory name)", "description": "string (what this skill does and when to use it)", "content": "string (markdown body \u2014 NO frontmatter, it will be generated from name+description)" }]
1871
+ },
1872
+ "codex": {
1873
+ "agentsMd": "string (markdown content for AGENTS.md \u2014 the primary Codex instructions file, same quality/structure as CLAUDE.md)",
1874
+ "skills": [{ "name": "string (kebab-case, matches directory name)", "description": "string (what this skill does and when to use it)", "content": "string (markdown body \u2014 NO frontmatter, it will be generated from name+description)" }]
1875
+ },
1876
+ "cursor": {
1877
+ "skills": [{ "name": "string (kebab-case, matches directory name)", "description": "string (what this skill does and when to use it)", "content": "string (markdown body \u2014 NO frontmatter, it will be generated from name+description)" }],
1878
+ "rules": [{ "filename": "string.mdc", "content": "string (with frontmatter)" }]
1879
+ }
1880
+ }
1903
1881
 
1904
- 2. A brief explanation section starting with "EXPLAIN:" on its own line:
1882
+ ${SKILL_FORMAT_RULES}
1905
1883
 
1906
- EXPLAIN:
1907
- [Changes]
1908
- - **file-or-skill-name**: short reason (max 10 words)
1909
- [Deletions]
1910
- - **file-path**: short reason (max 10 words)
1884
+ ${FILE_DESCRIPTIONS_RULES}
1911
1885
 
1912
- Omit empty categories. Keep each reason punchy and specific. End with a blank line.
1886
+ ${SCORING_CRITERIA}
1913
1887
 
1914
- 3. The JSON object starting with {.
1888
+ ${OUTPUT_SIZE_CONSTRAINTS}
1889
+ - Skills: generate 3-6 skills per target platform based on project complexity. Each skill should cover a distinct tool, workflow, or domain \u2014 don't pad with generic skills.`;
1890
+ var CORE_GENERATION_PROMPT = `${ROLE_AND_CONTEXT}
1891
+
1892
+ ${CONFIG_FILE_TYPES}
1893
+
1894
+ ${EXCLUSIONS}
1895
+
1896
+ ${OUTPUT_FORMAT}
1915
1897
 
1916
1898
  CoreSetup schema:
1917
1899
  {
@@ -1949,40 +1931,11 @@ Skill topic description MUST follow this formula: [What it does] + [When to use
1949
1931
  Include specific trigger phrases users would actually say. Also include negative triggers to prevent over-triggering.
1950
1932
  Example: "Creates a new API endpoint following the project's route pattern. Handles request validation, error responses, and DB queries. Use when user says 'add endpoint', 'new route', 'create API', or adds files to src/routes/. Do NOT use for modifying existing routes."
1951
1933
 
1952
- The "fileDescriptions" object MUST include a one-liner for every file that will be created or modified.
1953
- The "deletions" array should list files that should be removed (e.g. stale configs). Omit if empty.
1954
-
1955
- SCORING CRITERIA \u2014 your output is scored deterministically against the actual filesystem. Optimize for 100/100:
1956
-
1957
- Existence (25 pts):
1958
- - CLAUDE.md exists (6 pts) \u2014 always generate for claude targets
1959
- - AGENTS.md exists (6 pts) \u2014 always generate for codex target
1960
- - Skills configured (8 pts) \u2014 generate 3+ skill topics for full points
1961
- - For "both" target: .cursor/rules/ exist (3+3 pts), cross-platform parity (2 pts)
1962
-
1963
- Quality (25 pts):
1964
- - Executable content (8 pts) \u2014 include 3+ code blocks with project commands (3 blocks = full points)
1965
- - Concise config (6 pts) \u2014 total tokens across ALL config files must be under 2000 for full points (5000=4pts, 8000+=low)
1966
- - Concrete instructions (4 pts) \u2014 every line should reference specific files, paths, or code in backticks. Avoid generic prose.
1967
- - No directory tree listings (3 pts) \u2014 do NOT include tree-style file listings
1968
- - Structured with headings (2 pts) \u2014 use at least 3 ## sections and bullet lists
1934
+ ${FILE_DESCRIPTIONS_RULES}
1969
1935
 
1970
- Grounding (20 pts) \u2014 CRITICAL:
1971
- - Project grounding (12 pts) \u2014 reference the project's actual directories and files by name. The scoring checks which project dirs/files appear in your config. Mention key directories from the file tree.
1972
- - Reference density (8 pts) \u2014 use backticks and inline code extensively. Every file path, command, or identifier should be in backticks. Higher density of specific references = higher score.
1936
+ ${SCORING_CRITERIA}
1973
1937
 
1974
- Accuracy (15 pts) \u2014 CRITICAL:
1975
- - References valid (8 pts) \u2014 ONLY reference file paths that exist in the provided file tree. Every path in backticks is validated against the filesystem.
1976
- - Config drift (7 pts) \u2014 config must match current code state
1977
-
1978
- Freshness & Safety (10 pts):
1979
- - No secrets (4 pts), Permissions (2 pts \u2014 handled by caliber), Freshness (4 pts \u2014 handled by caliber)
1980
-
1981
- Bonus (5 pts): Hooks (2 pts), AGENTS.md (1 pt), OpenSkills format (2 pts) \u2014 handled by caliber
1982
-
1983
- OUTPUT SIZE CONSTRAINTS:
1984
- - CLAUDE.md / AGENTS.md: MUST be under 150 lines. Aim for 100-140 lines.
1985
- - Cursor rules: max 5 .mdc files.
1938
+ ${OUTPUT_SIZE_CONSTRAINTS}
1986
1939
  - Skill topics: 3-6 per platform based on project complexity (name + description only, no content).`;
1987
1940
  var SKILL_GENERATION_PROMPT = `You generate a single skill file for a coding agent (Claude Code, Cursor, or Codex).
1988
1941
 
@@ -2047,12 +2000,20 @@ Rules:
2047
2000
  - Preserve all fields that the user did not ask to change.
2048
2001
  - Do NOT generate mcpServers \u2014 MCP configuration is managed separately.
2049
2002
  - Skills use OpenSkills format: name is kebab-case directory name, content is markdown body without frontmatter.
2050
- - Update the "fileDescriptions" to reflect any changes you make.`;
2003
+ - Update the "fileDescriptions" to reflect any changes you make.
2004
+
2005
+ Quality constraints \u2014 your changes are scored, so do not break these:
2006
+ - CLAUDE.md / AGENTS.md: MUST stay under 150 lines. If adding content, remove less important lines to stay within budget.
2007
+ - Avoid vague instructions ("follow best practices", "write clean code", "ensure quality").
2008
+ - Do NOT add directory tree listings in code blocks.
2009
+ - Use backticks for every file path, command, and identifier.
2010
+ - Keep skill content under 150 lines, focused on actionable instructions.
2011
+ - Only reference file paths that actually exist in the project.`;
2051
2012
  var REFRESH_SYSTEM_PROMPT = `You are an expert at maintaining coding project documentation. Your job is to update existing documentation files based on code changes (git diffs).
2052
2013
 
2053
2014
  You will receive:
2054
2015
  1. Git diffs showing what code changed
2055
- 2. Current contents of documentation files (CLAUDE.md, AGENTS.md, README.md, skills, cursor skills, cursor rules)
2016
+ 2. Current contents of documentation files (CLAUDE.md, README.md, skills, cursor rules)
2056
2017
  3. Project context (languages, frameworks)
2057
2018
 
2058
2019
  Rules:
@@ -2062,23 +2023,22 @@ Rules:
2062
2023
  - Don't add speculative or aspirational content
2063
2024
  - Keep managed blocks (<!-- caliber:managed --> ... <!-- /caliber:managed -->) intact
2064
2025
  - If a doc doesn't need updating, return null for it
2065
- - For CLAUDE.md: update commands, architecture notes, conventions, key files if the diffs affect them
2066
- - For AGENTS.md: same as CLAUDE.md \u2014 this is the primary instructions file for Codex users
2026
+ - For CLAUDE.md: update commands, architecture notes, conventions, key files if the diffs affect them. Keep under 150 lines.
2067
2027
  - For README.md: update setup instructions, API docs, or feature descriptions if affected
2068
- - For cursor skills: update skill content if the diffs affect their domains
2028
+ - Only reference file paths that exist in the project
2029
+ - Use backticks for all file paths, commands, and identifiers
2069
2030
 
2070
2031
  Return a JSON object with this exact shape:
2071
2032
  {
2072
2033
  "updatedDocs": {
2073
2034
  "claudeMd": "<updated content or null>",
2074
- "agentsMd": "<updated content or null>",
2075
2035
  "readmeMd": "<updated content or null>",
2036
+ "cursorrules": "<updated content or null>",
2076
2037
  "cursorRules": [{"filename": "name.mdc", "content": "..."}] or null,
2077
- "cursorSkills": [{"slug": "string", "name": "string", "content": "..."}] or null,
2078
2038
  "claudeSkills": [{"filename": "name.md", "content": "..."}] or null
2079
2039
  },
2080
2040
  "changesSummary": "<1-2 sentence summary of what was updated and why>",
2081
- "docsUpdated": ["CLAUDE.md", "AGENTS.md", "README.md"]
2041
+ "docsUpdated": ["CLAUDE.md", "README.md"]
2082
2042
  }
2083
2043
 
2084
2044
  Respond with ONLY the JSON object, no markdown fences or extra text.`;
@@ -2107,7 +2067,7 @@ Rules for the learned section:
2107
2067
  - Be additive: keep all existing learned items, add new ones, remove duplicates
2108
2068
  - Never repeat instructions already present in the main CLAUDE.md
2109
2069
  - Each bullet must be specific and actionable \u2014 no vague advice
2110
- - Maximum ~50 bullet items total
2070
+ - Maximum ~30 bullet items total
2111
2071
  - Group related items under subheadings if there are many
2112
2072
  - If there's nothing meaningful to learn, return null
2113
2073
 
@@ -2142,7 +2102,7 @@ Be thorough \u2014 look for signals in:
2142
2102
  - Configuration files (e.g. next.config.js implies Next.js, .tf files imply Terraform + cloud providers)
2143
2103
  - Infrastructure-as-code files (Terraform, CloudFormation, Pulumi, Dockerfiles, k8s manifests)
2144
2104
  - CI/CD configs (.github/workflows, .gitlab-ci.yml, Jenkinsfile)
2145
- - Environment variable patterns and service references in code
2105
+ - Dockerfile base images (e.g. FROM python:3.11 implies Python, FROM node:20 implies Node.js)
2146
2106
 
2147
2107
  Only include items you're confident about. Return ONLY the JSON object.`;
2148
2108
 
@@ -3449,7 +3409,7 @@ description: ${skill.description}
3449
3409
  `;
3450
3410
  return frontmatter + skill.content;
3451
3411
  }
3452
- function collectSetupFiles(setup) {
3412
+ function collectSetupFiles(setup, targetAgent) {
3453
3413
  const files = [];
3454
3414
  const claude = setup.claude;
3455
3415
  const cursor = setup.cursor;
@@ -3487,7 +3447,8 @@ function collectSetupFiles(setup) {
3487
3447
  }
3488
3448
  }
3489
3449
  }
3490
- if (!fs15.existsSync("AGENTS.md") && !(codex && codex.agentsMd)) {
3450
+ const codexTargeted = targetAgent ? targetAgent.includes("codex") : false;
3451
+ if (codexTargeted && !fs15.existsSync("AGENTS.md") && !(codex && codex.agentsMd)) {
3491
3452
  const agentRefs = [];
3492
3453
  if (claude) agentRefs.push("See `CLAUDE.md` for Claude Code configuration.");
3493
3454
  if (cursor) agentRefs.push("See `.cursor/rules/` for Cursor rules.");
@@ -3812,12 +3773,12 @@ var GENERATION_MESSAGES = [
3812
3773
  "Analyzing your project structure and dependencies...",
3813
3774
  "Mapping out build commands and test workflows...",
3814
3775
  "Reviewing coding patterns and conventions...",
3815
- "Crafting permission rules for safe tool usage...",
3776
+ "Extracting architecture and key file references...",
3816
3777
  "Designing skills tailored to your codebase...",
3817
- "Evaluating MCP server integrations...",
3778
+ "Writing concise, grounded config content...",
3818
3779
  "Optimizing settings for your development workflow...",
3819
3780
  "Building coding guidelines from your project style...",
3820
- "Setting up pre-commit hooks and quality gates...",
3781
+ "Cross-referencing project files for accuracy...",
3821
3782
  "Assembling your complete agent configuration..."
3822
3783
  ];
3823
3784
  var REFINE_MESSAGES = [
@@ -3893,15 +3854,9 @@ var SpinnerMessages = class {
3893
3854
  }
3894
3855
  };
3895
3856
 
3896
- // src/commands/init.ts
3897
- init_config();
3898
-
3899
- // src/commands/interactive-provider-setup.ts
3900
- init_config();
3857
+ // src/utils/prompt.ts
3901
3858
  import chalk4 from "chalk";
3902
3859
  import readline2 from "readline";
3903
- import select3 from "@inquirer/select";
3904
- import confirm from "@inquirer/confirm";
3905
3860
  function promptInput(question) {
3906
3861
  const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
3907
3862
  return new Promise((resolve2) => {
@@ -3911,12 +3866,21 @@ function promptInput(question) {
3911
3866
  });
3912
3867
  });
3913
3868
  }
3869
+
3870
+ // src/commands/init.ts
3871
+ init_config();
3872
+
3873
+ // src/commands/interactive-provider-setup.ts
3874
+ init_config();
3875
+ import chalk5 from "chalk";
3876
+ import select3 from "@inquirer/select";
3877
+ import confirm from "@inquirer/confirm";
3914
3878
  var PROVIDER_CHOICES = [
3915
- { name: "Claude Code \u2014 Use my Claude Code subscription", value: "claude-cli" },
3916
- { name: "Cursor (use my Cursor subscription \u2014 no API key)", value: "cursor" },
3917
- { name: "Anthropic (Claude) \u2014 API key from console.anthropic.com", value: "anthropic" },
3918
- { name: "Google Vertex AI (Claude)", value: "vertex" },
3919
- { name: "OpenAI / OpenAI-compatible", value: "openai" }
3879
+ { name: "Claude Code \u2014 use your existing subscription (no API key)", value: "claude-cli" },
3880
+ { name: "Cursor \u2014 use your existing subscription (no API key)", value: "cursor" },
3881
+ { name: "Anthropic \u2014 API key from console.anthropic.com", value: "anthropic" },
3882
+ { name: "Google Vertex AI \u2014 Claude models via GCP", value: "vertex" },
3883
+ { name: "OpenAI \u2014 or any OpenAI-compatible endpoint", value: "openai" }
3920
3884
  ];
3921
3885
  async function runInteractiveProviderSetup(options) {
3922
3886
  const message = options?.selectMessage ?? "Select LLM provider";
@@ -3929,34 +3893,34 @@ async function runInteractiveProviderSetup(options) {
3929
3893
  case "claude-cli": {
3930
3894
  config.model = "default";
3931
3895
  if (!isClaudeCliAvailable()) {
3932
- console.log(chalk4.yellow("\n Claude Code CLI not found."));
3933
- console.log(chalk4.dim(" Install it: ") + chalk4.hex("#83D1EB")("npm install -g @anthropic-ai/claude-code"));
3934
- console.log(chalk4.dim(" Then run ") + chalk4.hex("#83D1EB")("claude") + chalk4.dim(" once to log in.\n"));
3896
+ console.log(chalk5.yellow("\n Claude Code CLI not found."));
3897
+ console.log(chalk5.dim(" Install it: ") + chalk5.hex("#83D1EB")("npm install -g @anthropic-ai/claude-code"));
3898
+ console.log(chalk5.dim(" Then run ") + chalk5.hex("#83D1EB")("claude") + chalk5.dim(" once to log in.\n"));
3935
3899
  const proceed = await confirm({ message: "Continue anyway?" });
3936
3900
  if (!proceed) throw new Error("__exit__");
3937
3901
  } else {
3938
- console.log(chalk4.dim(" Run `claude` once and log in with your Pro/Max/Team account if you haven't."));
3902
+ console.log(chalk5.dim(" Run `claude` once and log in with your Pro/Max/Team account if you haven't."));
3939
3903
  }
3940
3904
  break;
3941
3905
  }
3942
3906
  case "cursor": {
3943
3907
  config.model = "default";
3944
3908
  if (!isCursorAgentAvailable()) {
3945
- console.log(chalk4.yellow("\n Cursor Agent CLI not found."));
3946
- console.log(chalk4.dim(" Install it: ") + chalk4.hex("#83D1EB")("curl https://cursor.com/install -fsS | bash"));
3947
- console.log(chalk4.dim(" Then run ") + chalk4.hex("#83D1EB")("agent login") + chalk4.dim(" to authenticate.\n"));
3909
+ console.log(chalk5.yellow("\n Cursor Agent CLI not found."));
3910
+ console.log(chalk5.dim(" Install it: ") + chalk5.hex("#83D1EB")("curl https://cursor.com/install -fsS | bash"));
3911
+ console.log(chalk5.dim(" Then run ") + chalk5.hex("#83D1EB")("agent login") + chalk5.dim(" to authenticate.\n"));
3948
3912
  const proceed = await confirm({ message: "Continue anyway?" });
3949
3913
  if (!proceed) throw new Error("__exit__");
3950
3914
  } else {
3951
- console.log(chalk4.dim(" Run `agent login` if you haven't, or set CURSOR_API_KEY."));
3915
+ console.log(chalk5.dim(" Run `agent login` if you haven't, or set CURSOR_API_KEY."));
3952
3916
  }
3953
3917
  break;
3954
3918
  }
3955
3919
  case "anthropic": {
3956
- console.log(chalk4.dim(" Get a key at https://console.anthropic.com (same account as Claude Pro/Team/Max)."));
3920
+ console.log(chalk5.dim(" Get a key at https://console.anthropic.com (same account as Claude Pro/Team/Max)."));
3957
3921
  config.apiKey = await promptInput("Anthropic API key:");
3958
3922
  if (!config.apiKey) {
3959
- console.log(chalk4.red("API key is required."));
3923
+ console.log(chalk5.red("API key is required."));
3960
3924
  throw new Error("__exit__");
3961
3925
  }
3962
3926
  config.model = await promptInput(`Model (default: ${DEFAULT_MODELS.anthropic}):`) || DEFAULT_MODELS.anthropic;
@@ -3965,7 +3929,7 @@ async function runInteractiveProviderSetup(options) {
3965
3929
  case "vertex": {
3966
3930
  config.vertexProjectId = await promptInput("GCP Project ID:");
3967
3931
  if (!config.vertexProjectId) {
3968
- console.log(chalk4.red("Project ID is required."));
3932
+ console.log(chalk5.red("Project ID is required."));
3969
3933
  throw new Error("__exit__");
3970
3934
  }
3971
3935
  config.vertexRegion = await promptInput("Region (default: us-east5):") || "us-east5";
@@ -3976,7 +3940,7 @@ async function runInteractiveProviderSetup(options) {
3976
3940
  case "openai": {
3977
3941
  config.apiKey = await promptInput("API key:");
3978
3942
  if (!config.apiKey) {
3979
- console.log(chalk4.red("API key is required."));
3943
+ console.log(chalk5.red("API key is required."));
3980
3944
  throw new Error("__exit__");
3981
3945
  }
3982
3946
  config.baseUrl = await promptInput("Base URL (leave empty for OpenAI, or enter custom endpoint):") || void 0;
@@ -5214,7 +5178,7 @@ function computeLocalScore(dir, targetAgent) {
5214
5178
  }
5215
5179
 
5216
5180
  // src/scoring/display.ts
5217
- import chalk5 from "chalk";
5181
+ import chalk6 from "chalk";
5218
5182
  var AGENT_DISPLAY_NAMES = {
5219
5183
  claude: "Claude Code",
5220
5184
  cursor: "Cursor",
@@ -5232,31 +5196,31 @@ var CATEGORY_ORDER = ["existence", "quality", "grounding", "accuracy", "freshnes
5232
5196
  function gradeColor(grade) {
5233
5197
  switch (grade) {
5234
5198
  case "A":
5235
- return chalk5.green;
5199
+ return chalk6.green;
5236
5200
  case "B":
5237
- return chalk5.greenBright;
5201
+ return chalk6.greenBright;
5238
5202
  case "C":
5239
- return chalk5.yellow;
5203
+ return chalk6.yellow;
5240
5204
  case "D":
5241
- return chalk5.hex("#f97316");
5205
+ return chalk6.hex("#f97316");
5242
5206
  case "F":
5243
- return chalk5.red;
5207
+ return chalk6.red;
5244
5208
  default:
5245
- return chalk5.white;
5209
+ return chalk6.white;
5246
5210
  }
5247
5211
  }
5248
5212
  function progressBar(score, max, width = 40) {
5249
5213
  const filled = Math.round(score / max * width);
5250
5214
  const empty = width - filled;
5251
- const bar = chalk5.hex("#f97316")("\u2593".repeat(filled)) + chalk5.gray("\u2591".repeat(empty));
5215
+ const bar = chalk6.hex("#f97316")("\u2593".repeat(filled)) + chalk6.gray("\u2591".repeat(empty));
5252
5216
  return bar;
5253
5217
  }
5254
5218
  function formatCheck(check) {
5255
- const icon = check.passed ? chalk5.green("\u2713") : check.earnedPoints < 0 ? chalk5.red("\u2717") : chalk5.gray("\u2717");
5256
- const points = check.passed ? chalk5.green(`+${check.earnedPoints}`.padStart(4)) : check.earnedPoints < 0 ? chalk5.red(`${check.earnedPoints}`.padStart(4)) : chalk5.gray(" \u2014");
5257
- const name = check.passed ? chalk5.white(check.name) : chalk5.gray(check.name);
5258
- const detail = check.detail ? chalk5.gray(` (${check.detail})`) : "";
5259
- const suggestion = !check.passed && check.suggestion ? chalk5.gray(`
5219
+ const icon = check.passed ? chalk6.green("\u2713") : check.earnedPoints < 0 ? chalk6.red("\u2717") : chalk6.gray("\u2717");
5220
+ const points = check.passed ? chalk6.green(`+${check.earnedPoints}`.padStart(4)) : check.earnedPoints < 0 ? chalk6.red(`${check.earnedPoints}`.padStart(4)) : chalk6.gray(" \u2014");
5221
+ const name = check.passed ? chalk6.white(check.name) : chalk6.gray(check.name);
5222
+ const detail = check.detail ? chalk6.gray(` (${check.detail})`) : "";
5223
+ const suggestion = !check.passed && check.suggestion ? chalk6.gray(`
5260
5224
  \u2192 ${check.suggestion}`) : "";
5261
5225
  return ` ${icon} ${name.padEnd(38)}${points}${detail}${suggestion}`;
5262
5226
  }
@@ -5264,19 +5228,19 @@ function displayScore(result) {
5264
5228
  const gc = gradeColor(result.grade);
5265
5229
  const agentLabel = result.targetAgent.map((a) => AGENT_DISPLAY_NAMES[a] || a).join(" + ");
5266
5230
  console.log("");
5267
- console.log(chalk5.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
5231
+ console.log(chalk6.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
5268
5232
  console.log("");
5269
- console.log(` ${chalk5.bold("Agent Config Score")} ${gc(chalk5.bold(`${result.score} / ${result.maxScore}`))} Grade ${gc(chalk5.bold(result.grade))}`);
5233
+ console.log(` ${chalk6.bold("Agent Config Score")} ${gc(chalk6.bold(`${result.score} / ${result.maxScore}`))} Grade ${gc(chalk6.bold(result.grade))}`);
5270
5234
  console.log(` ${progressBar(result.score, result.maxScore)}`);
5271
- console.log(chalk5.dim(` Target: ${agentLabel}`));
5235
+ console.log(chalk6.dim(` Target: ${agentLabel}`));
5272
5236
  console.log("");
5273
- console.log(chalk5.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
5237
+ console.log(chalk6.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
5274
5238
  console.log("");
5275
5239
  for (const category of CATEGORY_ORDER) {
5276
5240
  const summary = result.categories[category];
5277
5241
  const categoryChecks = result.checks.filter((c) => c.category === category);
5278
5242
  console.log(
5279
- chalk5.gray(` ${CATEGORY_LABELS[category]}`) + chalk5.gray(" ".repeat(Math.max(1, 45 - CATEGORY_LABELS[category].length))) + chalk5.white(`${summary.earned}`) + chalk5.gray(` / ${summary.max}`)
5243
+ chalk6.gray(` ${CATEGORY_LABELS[category]}`) + chalk6.gray(" ".repeat(Math.max(1, 45 - CATEGORY_LABELS[category].length))) + chalk6.white(`${summary.earned}`) + chalk6.gray(` / ${summary.max}`)
5280
5244
  );
5281
5245
  for (const check of categoryChecks) {
5282
5246
  console.log(formatCheck(check));
@@ -5289,48 +5253,48 @@ function displayScoreSummary(result) {
5289
5253
  const agentLabel = result.targetAgent.map((a) => AGENT_DISPLAY_NAMES[a] || a).join(" + ");
5290
5254
  console.log("");
5291
5255
  console.log(
5292
- chalk5.gray(" ") + gc(`${result.score}/${result.maxScore}`) + chalk5.gray(` (Grade ${result.grade})`) + chalk5.gray(` \xB7 ${agentLabel}`) + chalk5.gray(` \xB7 ${progressBar(result.score, result.maxScore, 20)}`)
5256
+ chalk6.gray(" ") + gc(`${result.score}/${result.maxScore}`) + chalk6.gray(` (Grade ${result.grade})`) + chalk6.gray(` \xB7 ${agentLabel}`) + chalk6.gray(` \xB7 ${progressBar(result.score, result.maxScore, 20)}`)
5293
5257
  );
5294
5258
  const failing = result.checks.filter((c) => !c.passed);
5295
5259
  if (failing.length > 0) {
5296
5260
  const shown = failing.slice(0, 5);
5297
5261
  for (const check of shown) {
5298
- console.log(chalk5.gray(` \u2717 ${check.name}`));
5262
+ console.log(chalk6.gray(` \u2717 ${check.name}`));
5299
5263
  }
5300
5264
  const remaining = failing.length - shown.length;
5301
5265
  const moreText = remaining > 0 ? ` (+${remaining} more)` : "";
5302
- console.log(chalk5.dim(`
5303
- Run ${chalk5.hex("#83D1EB")("caliber score")} for details.${moreText}`));
5266
+ console.log(chalk6.dim(`
5267
+ Run ${chalk6.hex("#83D1EB")("caliber score")} for details.${moreText}`));
5304
5268
  }
5305
5269
  console.log("");
5306
5270
  }
5307
5271
  function displayScoreDelta(before, after) {
5308
5272
  const delta = after.score - before.score;
5309
5273
  const deltaStr = delta >= 0 ? `+${delta}` : `${delta}`;
5310
- const deltaColor = delta >= 0 ? chalk5.green : chalk5.red;
5274
+ const deltaColor = delta >= 0 ? chalk6.green : chalk6.red;
5311
5275
  const beforeGc = gradeColor(before.grade);
5312
5276
  const afterGc = gradeColor(after.grade);
5313
5277
  console.log("");
5314
- console.log(chalk5.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
5278
+ console.log(chalk6.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
5315
5279
  console.log("");
5316
5280
  console.log(
5317
- ` Score: ${beforeGc(`${before.score}`)} ${chalk5.gray("\u2192")} ${afterGc(`${after.score}`)} ${deltaColor(deltaStr + " pts")} ${beforeGc(before.grade)} ${chalk5.gray("\u2192")} ${afterGc(after.grade)}`
5281
+ ` Score: ${beforeGc(`${before.score}`)} ${chalk6.gray("\u2192")} ${afterGc(`${after.score}`)} ${deltaColor(deltaStr + " pts")} ${beforeGc(before.grade)} ${chalk6.gray("\u2192")} ${afterGc(after.grade)}`
5318
5282
  );
5319
- console.log(` ${progressBar(before.score, before.maxScore, 19)} ${chalk5.gray("\u2192")} ${progressBar(after.score, after.maxScore, 19)}`);
5283
+ console.log(` ${progressBar(before.score, before.maxScore, 19)} ${chalk6.gray("\u2192")} ${progressBar(after.score, after.maxScore, 19)}`);
5320
5284
  console.log("");
5321
- console.log(chalk5.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
5285
+ console.log(chalk6.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
5322
5286
  console.log("");
5323
5287
  const improved = after.checks.filter((ac) => {
5324
5288
  const bc = before.checks.find((b) => b.id === ac.id);
5325
5289
  return bc && ac.earnedPoints > bc.earnedPoints;
5326
5290
  });
5327
5291
  if (improved.length > 0) {
5328
- console.log(chalk5.gray(" What improved:"));
5292
+ console.log(chalk6.gray(" What improved:"));
5329
5293
  for (const check of improved) {
5330
5294
  const bc = before.checks.find((b) => b.id === check.id);
5331
5295
  const gain = check.earnedPoints - bc.earnedPoints;
5332
5296
  console.log(
5333
- chalk5.green(" +") + chalk5.white(` ${check.name.padEnd(50)}`) + chalk5.green(`+${gain}`)
5297
+ chalk6.green(" +") + chalk6.white(` ${check.name.padEnd(50)}`) + chalk6.green(`+${gain}`)
5334
5298
  );
5335
5299
  }
5336
5300
  console.log("");
@@ -5338,7 +5302,7 @@ function displayScoreDelta(before, after) {
5338
5302
  }
5339
5303
 
5340
5304
  // src/commands/recommend.ts
5341
- import chalk7 from "chalk";
5305
+ import chalk8 from "chalk";
5342
5306
  import ora from "ora";
5343
5307
  import select4 from "@inquirer/select";
5344
5308
  import { mkdirSync, readFileSync as readFileSync4, readdirSync as readdirSync4, existsSync as existsSync8, writeFileSync } from "fs";
@@ -5493,7 +5457,7 @@ init_config();
5493
5457
 
5494
5458
  // src/telemetry/index.ts
5495
5459
  import { PostHog } from "posthog-node";
5496
- import chalk6 from "chalk";
5460
+ import chalk7 from "chalk";
5497
5461
 
5498
5462
  // src/telemetry/config.ts
5499
5463
  import fs22 from "fs";
@@ -5565,7 +5529,7 @@ function initTelemetry() {
5565
5529
  });
5566
5530
  if (!wasNoticeShown()) {
5567
5531
  console.log(
5568
- chalk6.dim(" Caliber collects anonymous usage data to improve the product.") + "\n" + chalk6.dim(" Disable with --no-traces or CALIBER_TELEMETRY_DISABLED=1\n")
5532
+ chalk7.dim(" Caliber collects anonymous usage data to improve the product.") + "\n" + chalk7.dim(" Disable with --no-traces or CALIBER_TELEMETRY_DISABLED=1\n")
5569
5533
  );
5570
5534
  markNoticeShown();
5571
5535
  }
@@ -5925,7 +5889,7 @@ async function recommendCommand() {
5925
5889
  ]
5926
5890
  });
5927
5891
  if (!proceed) {
5928
- console.log(chalk7.dim(" Cancelled.\n"));
5892
+ console.log(chalk8.dim(" Cancelled.\n"));
5929
5893
  return;
5930
5894
  }
5931
5895
  await searchAndInstallSkills();
@@ -5940,7 +5904,7 @@ async function searchAndInstallSkills() {
5940
5904
  ...extractTopDeps()
5941
5905
  ].filter(Boolean))];
5942
5906
  if (technologies.length === 0) {
5943
- console.log(chalk7.yellow("Could not detect any languages or dependencies. Try running from a project root."));
5907
+ console.log(chalk8.yellow("Could not detect any languages or dependencies. Try running from a project root."));
5944
5908
  throw new Error("__exit__");
5945
5909
  }
5946
5910
  const primaryPlatform = platforms.includes("claude") ? "claude" : platforms[0];
@@ -5957,7 +5921,7 @@ async function searchAndInstallSkills() {
5957
5921
  return;
5958
5922
  }
5959
5923
  searchSpinner.succeed(
5960
- `Found ${allCandidates.length} skills` + (filteredCount > 0 ? chalk7.dim(` (${filteredCount} already installed)`) : "")
5924
+ `Found ${allCandidates.length} skills` + (filteredCount > 0 ? chalk8.dim(` (${filteredCount} already installed)`) : "")
5961
5925
  );
5962
5926
  let results;
5963
5927
  const config = loadConfig();
@@ -5991,7 +5955,7 @@ async function searchAndInstallSkills() {
5991
5955
  }
5992
5956
  const unavailableCount = results.length - available.length;
5993
5957
  fetchSpinner.succeed(
5994
- `${available.length} installable skill${available.length > 1 ? "s" : ""}` + (unavailableCount > 0 ? chalk7.dim(` (${unavailableCount} unavailable)`) : "")
5958
+ `${available.length} installable skill${available.length > 1 ? "s" : ""}` + (unavailableCount > 0 ? chalk8.dim(` (${unavailableCount} unavailable)`) : "")
5995
5959
  );
5996
5960
  const selected = await interactiveSelect(available);
5997
5961
  if (selected?.length) {
@@ -6014,30 +5978,30 @@ async function interactiveSelect(recs) {
6014
5978
  const nameWidth = Math.max(...recs.map((r) => r.name.length), 4) + 2;
6015
5979
  const prefixWidth = 8;
6016
5980
  const scoreWidth = 6;
6017
- lines.push(chalk7.bold(" Skills"));
5981
+ lines.push(chalk8.bold(" Skills"));
6018
5982
  lines.push("");
6019
5983
  if (hasScores) {
6020
- const header = " ".repeat(prefixWidth) + chalk7.dim("Score".padEnd(scoreWidth)) + chalk7.dim("Name".padEnd(nameWidth)) + chalk7.dim("Why");
5984
+ const header = " ".repeat(prefixWidth) + chalk8.dim("Score".padEnd(scoreWidth)) + chalk8.dim("Name".padEnd(nameWidth)) + chalk8.dim("Why");
6021
5985
  lines.push(header);
6022
5986
  } else {
6023
- const header = " ".repeat(prefixWidth) + chalk7.dim("Name".padEnd(nameWidth)) + chalk7.dim("Technology".padEnd(18)) + chalk7.dim("Source");
5987
+ const header = " ".repeat(prefixWidth) + chalk8.dim("Name".padEnd(nameWidth)) + chalk8.dim("Technology".padEnd(18)) + chalk8.dim("Source");
6024
5988
  lines.push(header);
6025
5989
  }
6026
- lines.push(chalk7.dim(" " + "\u2500".repeat(Math.min(cols - 4, 90))));
5990
+ lines.push(chalk8.dim(" " + "\u2500".repeat(Math.min(cols - 4, 90))));
6027
5991
  for (let i = 0; i < recs.length; i++) {
6028
5992
  const rec = recs[i];
6029
- const check = selected.has(i) ? chalk7.green("[x]") : "[ ]";
6030
- const ptr = i === cursor ? chalk7.cyan(">") : " ";
5993
+ const check = selected.has(i) ? chalk8.green("[x]") : "[ ]";
5994
+ const ptr = i === cursor ? chalk8.cyan(">") : " ";
6031
5995
  if (hasScores) {
6032
- const scoreColor = rec.score >= 90 ? chalk7.green : rec.score >= 70 ? chalk7.yellow : chalk7.dim;
5996
+ const scoreColor = rec.score >= 90 ? chalk8.green : rec.score >= 70 ? chalk8.yellow : chalk8.dim;
6033
5997
  const reasonMax = Math.max(cols - prefixWidth - scoreWidth - nameWidth - 2, 20);
6034
- lines.push(` ${ptr} ${check} ${scoreColor(String(rec.score).padStart(3))} ${rec.name.padEnd(nameWidth)}${chalk7.dim(rec.reason.slice(0, reasonMax))}`);
5998
+ lines.push(` ${ptr} ${check} ${scoreColor(String(rec.score).padStart(3))} ${rec.name.padEnd(nameWidth)}${chalk8.dim(rec.reason.slice(0, reasonMax))}`);
6035
5999
  } else {
6036
- lines.push(` ${ptr} ${check} ${rec.name.padEnd(nameWidth)}${rec.detected_technology.padEnd(16)} ${chalk7.dim(rec.source_url || "")}`);
6000
+ lines.push(` ${ptr} ${check} ${rec.name.padEnd(nameWidth)}${rec.detected_technology.padEnd(16)} ${chalk8.dim(rec.source_url || "")}`);
6037
6001
  }
6038
6002
  }
6039
6003
  lines.push("");
6040
- lines.push(chalk7.dim(" \u2191\u2193 navigate \u23B5 toggle a all n none \u23CE install q cancel"));
6004
+ lines.push(chalk8.dim(" \u2191\u2193 navigate \u23B5 toggle a all n none \u23CE install q cancel"));
6041
6005
  return lines.join("\n");
6042
6006
  }
6043
6007
  function draw(initial) {
@@ -6086,7 +6050,7 @@ async function interactiveSelect(recs) {
6086
6050
  case "\n":
6087
6051
  cleanup();
6088
6052
  if (selected.size === 0) {
6089
- console.log(chalk7.dim("\n No skills selected.\n"));
6053
+ console.log(chalk8.dim("\n No skills selected.\n"));
6090
6054
  resolve2(null);
6091
6055
  } else {
6092
6056
  resolve2(Array.from(selected).sort().map((i) => recs[i]));
@@ -6096,7 +6060,7 @@ async function interactiveSelect(recs) {
6096
6060
  case "\x1B":
6097
6061
  case "":
6098
6062
  cleanup();
6099
- console.log(chalk7.dim("\n Cancelled.\n"));
6063
+ console.log(chalk8.dim("\n Cancelled.\n"));
6100
6064
  resolve2(null);
6101
6065
  break;
6102
6066
  }
@@ -6160,7 +6124,7 @@ async function installSkills(recs, platforms, contentMap) {
6160
6124
  trackSkillsInstalled(installed.length);
6161
6125
  spinner.succeed(`Installed ${installed.length} file${installed.length > 1 ? "s" : ""}`);
6162
6126
  for (const p of installed) {
6163
- console.log(chalk7.green(` \u2713 ${p}`));
6127
+ console.log(chalk8.green(` \u2713 ${p}`));
6164
6128
  }
6165
6129
  } else {
6166
6130
  spinner.fail("No skills were installed");
@@ -6173,19 +6137,19 @@ function printSkills(recs) {
6173
6137
  const nameWidth = Math.max(...recs.map((r) => r.name.length), 4) + 2;
6174
6138
  const scoreWidth = 6;
6175
6139
  const prefixWidth = 2;
6176
- console.log(chalk7.bold("\n Skills\n"));
6140
+ console.log(chalk8.bold("\n Skills\n"));
6177
6141
  if (hasScores) {
6178
- console.log(" ".repeat(prefixWidth) + chalk7.dim("Score".padEnd(scoreWidth)) + chalk7.dim("Name".padEnd(nameWidth)) + chalk7.dim("Why"));
6142
+ console.log(" ".repeat(prefixWidth) + chalk8.dim("Score".padEnd(scoreWidth)) + chalk8.dim("Name".padEnd(nameWidth)) + chalk8.dim("Why"));
6179
6143
  } else {
6180
- console.log(" ".repeat(prefixWidth) + chalk7.dim("Name".padEnd(nameWidth)) + chalk7.dim("Technology".padEnd(18)) + chalk7.dim("Source"));
6144
+ console.log(" ".repeat(prefixWidth) + chalk8.dim("Name".padEnd(nameWidth)) + chalk8.dim("Technology".padEnd(18)) + chalk8.dim("Source"));
6181
6145
  }
6182
- console.log(chalk7.dim(" " + "\u2500".repeat(Math.min(cols - 4, 90))));
6146
+ console.log(chalk8.dim(" " + "\u2500".repeat(Math.min(cols - 4, 90))));
6183
6147
  for (const rec of recs) {
6184
6148
  if (hasScores) {
6185
6149
  const reasonMax = Math.max(cols - prefixWidth - scoreWidth - nameWidth - 2, 20);
6186
- console.log(` ${String(rec.score).padStart(3)} ${rec.name.padEnd(nameWidth)}${chalk7.dim(rec.reason.slice(0, reasonMax))}`);
6150
+ console.log(` ${String(rec.score).padStart(3)} ${rec.name.padEnd(nameWidth)}${chalk8.dim(rec.reason.slice(0, reasonMax))}`);
6187
6151
  } else {
6188
- console.log(` ${rec.name.padEnd(nameWidth)}${rec.detected_technology.padEnd(16)} ${chalk7.dim(rec.source_url || "")}`);
6152
+ console.log(` ${rec.name.padEnd(nameWidth)}${rec.detected_technology.padEnd(16)} ${chalk8.dim(rec.source_url || "")}`);
6189
6153
  }
6190
6154
  }
6191
6155
  console.log("");
@@ -6280,11 +6244,11 @@ function formatMs(ms) {
6280
6244
 
6281
6245
  // src/commands/init.ts
6282
6246
  function log(verbose, ...args) {
6283
- if (verbose) console.log(chalk8.dim(` [verbose] ${args.map(String).join(" ")}`));
6247
+ if (verbose) console.log(chalk9.dim(` [verbose] ${args.map(String).join(" ")}`));
6284
6248
  }
6285
6249
  async function initCommand(options) {
6286
- const brand = chalk8.hex("#EB9D83");
6287
- const title = chalk8.hex("#83D1EB");
6250
+ const brand = chalk9.hex("#EB9D83");
6251
+ const title = chalk9.hex("#83D1EB");
6288
6252
  console.log(brand.bold(`
6289
6253
  \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
6290
6254
  \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
@@ -6293,41 +6257,34 @@ async function initCommand(options) {
6293
6257
  \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
6294
6258
  \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
6295
6259
  `));
6296
- console.log(chalk8.dim(" Initialize your project for AI-assisted development\n"));
6297
- console.log(title.bold(" Welcome to Caliber\n"));
6298
- console.log(chalk8.dim(" Caliber analyzes your codebase and creates tailored config files"));
6299
- console.log(chalk8.dim(" so your AI coding agents understand your project from day one.\n"));
6260
+ console.log(chalk9.dim(" Scan your project and generate tailored config files for"));
6261
+ console.log(chalk9.dim(" Claude Code, Cursor, and Codex.\n"));
6300
6262
  const report = options.debugReport ? new DebugReport() : null;
6301
6263
  console.log(title.bold(" How it works:\n"));
6302
- console.log(chalk8.dim(" 1. Connect Set up your LLM provider"));
6303
- console.log(chalk8.dim(" 2. Discover Analyze your code, dependencies, and structure"));
6304
- console.log(chalk8.dim(" 3. Generate Create config files tailored to your project"));
6305
- console.log(chalk8.dim(" 4. Review Preview, refine, and apply the changes"));
6306
- console.log(chalk8.dim(" 5. Skills Browse community skills for your stack\n"));
6307
- console.log(title.bold(" Step 1/5 \u2014 Connect your LLM\n"));
6264
+ console.log(chalk9.dim(" 1. Connect Choose your LLM provider"));
6265
+ console.log(chalk9.dim(" 2. Discover Scan code, dependencies, and existing configs"));
6266
+ console.log(chalk9.dim(" 3. Generate Build CLAUDE.md, rules, and skills for your codebase"));
6267
+ console.log(chalk9.dim(" 4. Review See a diff \u2014 accept, refine via chat, or decline"));
6268
+ console.log(chalk9.dim(" 5. Skills Search community registries and install skills\n"));
6269
+ console.log(title.bold(" Step 1/5 \u2014 Connect\n"));
6308
6270
  let config = loadConfig();
6309
6271
  if (!config) {
6310
- console.log(chalk8.dim(" No LLM provider set yet. Choose how to run Caliber:\n"));
6311
- try {
6312
- await runInteractiveProviderSetup({
6313
- selectMessage: "How do you want to use Caliber? (choose LLM provider)"
6314
- });
6315
- } catch (err) {
6316
- if (err.message === "__exit__") throw err;
6317
- throw err;
6318
- }
6272
+ console.log(chalk9.dim(" No LLM provider set yet. Choose how to run Caliber:\n"));
6273
+ await runInteractiveProviderSetup({
6274
+ selectMessage: "How do you want to use Caliber? (choose LLM provider)"
6275
+ });
6319
6276
  config = loadConfig();
6320
6277
  if (!config) {
6321
- console.log(chalk8.red(" Setup was cancelled or failed.\n"));
6278
+ console.log(chalk9.red(" Setup was cancelled or failed.\n"));
6322
6279
  throw new Error("__exit__");
6323
6280
  }
6324
- console.log(chalk8.green(" \u2713 Provider saved. Let's continue.\n"));
6281
+ console.log(chalk9.green(" \u2713 Provider saved. Let's continue.\n"));
6325
6282
  }
6326
6283
  trackInitProviderSelected(config.provider, config.model);
6327
- const displayModel = config.model === "default" && config.provider === "claude-cli" ? process.env.ANTHROPIC_MODEL || "default (inherited from Claude Code)" : config.model;
6284
+ const displayModel = getDisplayModel(config);
6328
6285
  const fastModel = getFastModel();
6329
6286
  const modelLine = fastModel ? ` Provider: ${config.provider} | Model: ${displayModel} | Scan: ${fastModel}` : ` Provider: ${config.provider} | Model: ${displayModel}`;
6330
- console.log(chalk8.dim(modelLine + "\n"));
6287
+ console.log(chalk9.dim(modelLine + "\n"));
6331
6288
  if (report) {
6332
6289
  report.markStep("Provider setup");
6333
6290
  report.addSection("LLM Provider", `- **Provider**: ${config.provider}
@@ -6335,18 +6292,19 @@ async function initCommand(options) {
6335
6292
  - **Fast model**: ${fastModel || "none"}`);
6336
6293
  }
6337
6294
  await validateModel({ fast: true });
6338
- console.log(title.bold(" Step 2/5 \u2014 Discover your project\n"));
6339
- console.log(chalk8.dim(" Learning about your languages, dependencies, structure, and existing configs.\n"));
6340
- const spinner = ora2("Analyzing project...").start();
6295
+ console.log(title.bold(" Step 2/5 \u2014 Discover\n"));
6296
+ const spinner = ora2("Scanning code, dependencies, and existing configs...").start();
6341
6297
  const fingerprint = await collectFingerprint(process.cwd());
6342
- spinner.succeed("Project analyzed");
6298
+ spinner.succeed("Project scanned");
6343
6299
  log(options.verbose, `Fingerprint: ${fingerprint.languages.length} languages, ${fingerprint.frameworks.length} frameworks, ${fingerprint.fileTree.length} files`);
6344
6300
  if (options.verbose && fingerprint.codeAnalysis) {
6345
6301
  log(options.verbose, `Code analysis: ${fingerprint.codeAnalysis.filesIncluded}/${fingerprint.codeAnalysis.filesAnalyzed} files, ~${fingerprint.codeAnalysis.includedTokens.toLocaleString()} tokens, ${fingerprint.codeAnalysis.duplicateGroups} dedup groups`);
6346
6302
  }
6347
6303
  trackInitProjectDiscovered(fingerprint.languages.length, fingerprint.frameworks.length, fingerprint.fileTree.length);
6348
- console.log(chalk8.dim(` Languages: ${fingerprint.languages.join(", ") || "none detected"}`));
6349
- console.log(chalk8.dim(` Files: ${fingerprint.fileTree.length} found
6304
+ const langDisplay = fingerprint.languages.join(", ") || "none detected";
6305
+ const frameworkDisplay = fingerprint.frameworks.length > 0 ? ` (${fingerprint.frameworks.join(", ")})` : "";
6306
+ console.log(chalk9.dim(` Languages: ${langDisplay}${frameworkDisplay}`));
6307
+ console.log(chalk9.dim(` Files: ${fingerprint.fileTree.length} found
6350
6308
  `));
6351
6309
  if (report) {
6352
6310
  report.markStep("Fingerprint");
@@ -6367,6 +6325,8 @@ async function initCommand(options) {
6367
6325
  } else {
6368
6326
  targetAgent = await promptAgent();
6369
6327
  }
6328
+ console.log(chalk9.dim(` Target: ${targetAgent.join(", ")}
6329
+ `));
6370
6330
  trackInitAgentSelected(targetAgent);
6371
6331
  const preScore = computeLocalScore(process.cwd(), targetAgent);
6372
6332
  const failingForDismissal = preScore.checks.filter((c) => !c.passed && c.maxPoints > 0);
@@ -6380,6 +6340,7 @@ async function initCommand(options) {
6380
6340
  }
6381
6341
  }
6382
6342
  const baselineScore = computeLocalScore(process.cwd(), targetAgent);
6343
+ console.log(chalk9.dim(" Current setup score:"));
6383
6344
  displayScoreSummary(baselineScore);
6384
6345
  if (options.verbose) {
6385
6346
  for (const c of baselineScore.checks) {
@@ -6408,29 +6369,29 @@ async function initCommand(options) {
6408
6369
  ]);
6409
6370
  if (hasExistingConfig && baselineScore.score === 100) {
6410
6371
  trackInitScoreComputed(baselineScore.score, passingCount, failingCount, true);
6411
- console.log(chalk8.bold.green(" Your setup is already optimal \u2014 nothing to change.\n"));
6412
- console.log(chalk8.dim(" Run ") + chalk8.hex("#83D1EB")("caliber init --force") + chalk8.dim(" to regenerate anyway.\n"));
6372
+ console.log(chalk9.bold.green(" Your setup is already optimal \u2014 nothing to change.\n"));
6373
+ console.log(chalk9.dim(" Run ") + chalk9.hex("#83D1EB")("caliber init --force") + chalk9.dim(" to regenerate anyway.\n"));
6413
6374
  if (!options.force) return;
6414
6375
  }
6415
6376
  const allFailingChecks = baselineScore.checks.filter((c) => !c.passed && c.maxPoints > 0);
6416
6377
  const llmFixableChecks = allFailingChecks.filter((c) => !NON_LLM_CHECKS.has(c.id));
6417
6378
  trackInitScoreComputed(baselineScore.score, passingCount, failingCount, false);
6418
6379
  if (hasExistingConfig && llmFixableChecks.length === 0 && allFailingChecks.length > 0 && !options.force) {
6419
- console.log(chalk8.bold.green("\n Your config is fully optimized for LLM generation.\n"));
6420
- console.log(chalk8.dim(" Remaining items need CLI actions:\n"));
6380
+ console.log(chalk9.bold.green("\n Your config is fully optimized for LLM generation.\n"));
6381
+ console.log(chalk9.dim(" Remaining items need CLI actions:\n"));
6421
6382
  for (const check of allFailingChecks) {
6422
- console.log(chalk8.dim(` \u2022 ${check.name}`));
6383
+ console.log(chalk9.dim(` \u2022 ${check.name}`));
6423
6384
  if (check.suggestion) {
6424
- console.log(` ${chalk8.hex("#83D1EB")(check.suggestion)}`);
6385
+ console.log(` ${chalk9.hex("#83D1EB")(check.suggestion)}`);
6425
6386
  }
6426
6387
  }
6427
6388
  console.log("");
6428
- console.log(chalk8.dim(" Run ") + chalk8.hex("#83D1EB")("caliber init --force") + chalk8.dim(" to regenerate anyway.\n"));
6389
+ console.log(chalk9.dim(" Run ") + chalk9.hex("#83D1EB")("caliber init --force") + chalk9.dim(" to regenerate anyway.\n"));
6429
6390
  return;
6430
6391
  }
6431
6392
  const isEmpty = fingerprint.fileTree.length < 3;
6432
6393
  if (isEmpty) {
6433
- fingerprint.description = await promptInput2("What will you build in this project?");
6394
+ fingerprint.description = await promptInput("What will you build in this project?");
6434
6395
  }
6435
6396
  let failingChecks;
6436
6397
  let passingChecks;
@@ -6440,23 +6401,24 @@ async function initCommand(options) {
6440
6401
  passingChecks = baselineScore.checks.filter((c) => c.passed).map((c) => ({ name: c.name }));
6441
6402
  currentScore = baselineScore.score;
6442
6403
  if (failingChecks.length > 0) {
6443
- console.log(title.bold(" Step 3/5 \u2014 Fine-tuning\n"));
6444
- console.log(chalk8.dim(` Your setup scores ${baselineScore.score}/100 \u2014 fixing ${failingChecks.length} remaining issue${failingChecks.length === 1 ? "" : "s"}:
6404
+ console.log(title.bold(" Step 3/5 \u2014 Generate\n"));
6405
+ console.log(chalk9.dim(` Score is ${baselineScore.score}/100 \u2014 fine-tuning ${failingChecks.length} remaining issue${failingChecks.length === 1 ? "" : "s"}:
6445
6406
  `));
6446
6407
  for (const check of failingChecks) {
6447
- console.log(chalk8.dim(` \u2022 ${check.name}`));
6408
+ console.log(chalk9.dim(` \u2022 ${check.name}`));
6448
6409
  }
6449
6410
  console.log("");
6450
6411
  }
6451
6412
  } else if (hasExistingConfig) {
6452
- console.log(title.bold(" Step 3/5 \u2014 Improve your setup\n"));
6453
- console.log(chalk8.dim(" Reviewing your existing configs against your codebase"));
6454
- console.log(chalk8.dim(" and preparing improvements.\n"));
6413
+ console.log(title.bold(" Step 3/5 \u2014 Generate\n"));
6414
+ console.log(chalk9.dim(" Auditing your existing configs against your codebase and improving them.\n"));
6455
6415
  } else {
6456
- console.log(title.bold(" Step 3/5 \u2014 Build your agent setup\n"));
6457
- console.log(chalk8.dim(" Creating config files tailored to your project.\n"));
6416
+ console.log(title.bold(" Step 3/5 \u2014 Generate\n"));
6417
+ console.log(chalk9.dim(" Building CLAUDE.md, rules, and skills tailored to your project.\n"));
6458
6418
  }
6459
- console.log(chalk8.dim(" This can take a couple of minutes depending on your model and provider.\n"));
6419
+ const genModelInfo = fastModel ? ` Using ${displayModel} for docs, ${fastModel} for skills` : ` Using ${displayModel}`;
6420
+ console.log(chalk9.dim(genModelInfo));
6421
+ console.log(chalk9.dim(" This can take a couple of minutes depending on your model and provider.\n"));
6460
6422
  if (report) {
6461
6423
  report.markStep("Generation");
6462
6424
  const fullPrompt = buildGeneratePrompt(fingerprint, targetAgent, fingerprint.description, failingChecks, currentScore, passingChecks);
@@ -6508,8 +6470,8 @@ async function initCommand(options) {
6508
6470
  genSpinner.fail("Failed to generate setup.");
6509
6471
  writeErrorLog(config, rawOutput, void 0, genStopReason);
6510
6472
  if (rawOutput) {
6511
- console.log(chalk8.dim("\nRaw LLM output (JSON parse failed):"));
6512
- console.log(chalk8.dim(rawOutput.slice(0, 500)));
6473
+ console.log(chalk9.dim("\nRaw LLM output (JSON parse failed):"));
6474
+ console.log(chalk9.dim(rawOutput.slice(0, 500)));
6513
6475
  }
6514
6476
  throw new Error("__exit__");
6515
6477
  }
@@ -6522,7 +6484,7 @@ async function initCommand(options) {
6522
6484
  const mins = Math.floor(elapsedMs / 6e4);
6523
6485
  const secs = Math.floor(elapsedMs % 6e4 / 1e3);
6524
6486
  const timeStr = mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;
6525
- genSpinner.succeed(`Setup generated ${chalk8.dim(`in ${timeStr}`)}`);
6487
+ genSpinner.succeed(`Setup generated ${chalk9.dim(`in ${timeStr}`)}`);
6526
6488
  log(options.verbose, `Generation completed: ${elapsedMs}ms, stopReason: ${genStopReason || "end_turn"}`);
6527
6489
  printSetupSummary(generatedSetup);
6528
6490
  const sessionHistory = [];
@@ -6530,15 +6492,15 @@ async function initCommand(options) {
6530
6492
  role: "assistant",
6531
6493
  content: summarizeSetup("Initial generation", generatedSetup)
6532
6494
  });
6533
- console.log(title.bold(" Step 4/5 \u2014 Review and apply\n"));
6534
- const setupFiles = collectSetupFiles(generatedSetup);
6495
+ console.log(title.bold(" Step 4/5 \u2014 Review\n"));
6496
+ const setupFiles = collectSetupFiles(generatedSetup, targetAgent);
6535
6497
  const staged = stageFiles(setupFiles, process.cwd());
6536
6498
  const totalChanges = staged.newFiles + staged.modifiedFiles;
6537
- console.log(chalk8.dim(` ${chalk8.green(`${staged.newFiles} new`)} / ${chalk8.yellow(`${staged.modifiedFiles} modified`)} file${totalChanges !== 1 ? "s" : ""}
6499
+ console.log(chalk9.dim(` ${chalk9.green(`${staged.newFiles} new`)} / ${chalk9.yellow(`${staged.modifiedFiles} modified`)} file${totalChanges !== 1 ? "s" : ""}
6538
6500
  `));
6539
6501
  let action;
6540
6502
  if (totalChanges === 0) {
6541
- console.log(chalk8.dim(" No changes needed \u2014 your configs are already up to date.\n"));
6503
+ console.log(chalk9.dim(" No changes needed \u2014 your configs are already up to date.\n"));
6542
6504
  cleanupStaging();
6543
6505
  action = "accept";
6544
6506
  } else if (options.autoApprove) {
@@ -6561,12 +6523,12 @@ async function initCommand(options) {
6561
6523
  trackInitRefinementRound(refinementRound, !!generatedSetup);
6562
6524
  if (!generatedSetup) {
6563
6525
  cleanupStaging();
6564
- console.log(chalk8.dim("Refinement cancelled. No files were modified."));
6526
+ console.log(chalk9.dim("Refinement cancelled. No files were modified."));
6565
6527
  return;
6566
6528
  }
6567
- const updatedFiles = collectSetupFiles(generatedSetup);
6529
+ const updatedFiles = collectSetupFiles(generatedSetup, targetAgent);
6568
6530
  const restaged = stageFiles(updatedFiles, process.cwd());
6569
- console.log(chalk8.dim(` ${chalk8.green(`${restaged.newFiles} new`)} / ${chalk8.yellow(`${restaged.modifiedFiles} modified`)} file${restaged.newFiles + restaged.modifiedFiles !== 1 ? "s" : ""}
6531
+ console.log(chalk9.dim(` ${chalk9.green(`${restaged.newFiles} new`)} / ${chalk9.yellow(`${restaged.modifiedFiles} modified`)} file${restaged.newFiles + restaged.modifiedFiles !== 1 ? "s" : ""}
6570
6532
  `));
6571
6533
  printSetupSummary(generatedSetup);
6572
6534
  await openReview("terminal", restaged.stagedFiles);
@@ -6575,28 +6537,30 @@ async function initCommand(options) {
6575
6537
  }
6576
6538
  cleanupStaging();
6577
6539
  if (action === "decline") {
6578
- console.log(chalk8.dim("Setup declined. No files were modified."));
6540
+ console.log(chalk9.dim("Setup declined. No files were modified."));
6579
6541
  return;
6580
6542
  }
6581
6543
  if (options.dryRun) {
6582
- console.log(chalk8.yellow("\n[Dry run] Would write the following files:"));
6544
+ console.log(chalk9.yellow("\n[Dry run] Would write the following files:"));
6583
6545
  console.log(JSON.stringify(generatedSetup, null, 2));
6584
6546
  return;
6585
6547
  }
6586
6548
  const writeSpinner = ora2("Writing config files...").start();
6587
6549
  try {
6588
- if (!fs24.existsSync("AGENTS.md") && !generatedSetup.codex) {
6589
- const setupFiles2 = collectSetupFiles(generatedSetup);
6590
- const agentsStub = setupFiles2.find((f) => f.path === "AGENTS.md");
6591
- if (agentsStub) {
6592
- const setup = generatedSetup;
6593
- setup.codex = { agentsMd: agentsStub.content };
6594
- if (!setup.targetAgent) {
6595
- setup.targetAgent = ["codex"];
6596
- } else if (Array.isArray(setup.targetAgent) && !setup.targetAgent.includes("codex")) {
6597
- setup.targetAgent.push("codex");
6598
- }
6599
- }
6550
+ if (targetAgent.includes("codex") && !fs24.existsSync("AGENTS.md") && !generatedSetup.codex) {
6551
+ const claude = generatedSetup.claude;
6552
+ const cursor = generatedSetup.cursor;
6553
+ const agentRefs = [];
6554
+ if (claude) agentRefs.push("See `CLAUDE.md` for Claude Code configuration.");
6555
+ if (cursor) agentRefs.push("See `.cursor/rules/` for Cursor rules.");
6556
+ if (agentRefs.length === 0) agentRefs.push("See CLAUDE.md and .cursor/rules/ for agent configurations.");
6557
+ const stubContent = `# AGENTS.md
6558
+
6559
+ This project uses AI coding agents configured by [Caliber](https://github.com/rely-ai-org/caliber).
6560
+
6561
+ ${agentRefs.join(" ")}
6562
+ `;
6563
+ generatedSetup.codex = { agentsMd: stubContent };
6600
6564
  }
6601
6565
  const result = writeSetup(generatedSetup);
6602
6566
  writeSpinner.succeed("Config files written");
@@ -6606,26 +6570,26 @@ async function initCommand(options) {
6606
6570
  0,
6607
6571
  result.deleted.length
6608
6572
  );
6609
- console.log(chalk8.bold("\nFiles created/updated:"));
6573
+ console.log(chalk9.bold("\nFiles created/updated:"));
6610
6574
  for (const file of result.written) {
6611
- console.log(` ${chalk8.green("\u2713")} ${file}`);
6575
+ console.log(` ${chalk9.green("\u2713")} ${file}`);
6612
6576
  }
6613
6577
  if (result.deleted.length > 0) {
6614
- console.log(chalk8.bold("\nFiles removed:"));
6578
+ console.log(chalk9.bold("\nFiles removed:"));
6615
6579
  for (const file of result.deleted) {
6616
- console.log(` ${chalk8.red("\u2717")} ${file}`);
6580
+ console.log(` ${chalk9.red("\u2717")} ${file}`);
6617
6581
  }
6618
6582
  }
6619
6583
  if (result.backupDir) {
6620
- console.log(chalk8.dim(`
6584
+ console.log(chalk9.dim(`
6621
6585
  Backups saved to ${result.backupDir}`));
6622
6586
  }
6623
6587
  } catch (err) {
6624
6588
  writeSpinner.fail("Failed to write files");
6625
- console.error(chalk8.red(err instanceof Error ? err.message : "Unknown error"));
6589
+ console.error(chalk9.red(err instanceof Error ? err.message : "Unknown error"));
6626
6590
  throw new Error("__exit__");
6627
6591
  }
6628
- ensurePermissions();
6592
+ ensurePermissions(fingerprint);
6629
6593
  const sha = getCurrentHeadSha();
6630
6594
  writeState({
6631
6595
  lastRefreshSha: sha ?? "",
@@ -6633,8 +6597,7 @@ async function initCommand(options) {
6633
6597
  targetAgent
6634
6598
  });
6635
6599
  console.log("");
6636
- console.log(title.bold(" Keep your setup up-to-date as your code evolve\n"));
6637
- console.log(chalk8.dim(" Caliber can automatically update your agent configs when your code changes.\n"));
6600
+ console.log(chalk9.dim(" Auto-refresh: keep your configs in sync as your code changes.\n"));
6638
6601
  let hookChoice;
6639
6602
  if (options.autoApprove) {
6640
6603
  hookChoice = "skip";
@@ -6646,46 +6609,46 @@ async function initCommand(options) {
6646
6609
  if (hookChoice === "claude" || hookChoice === "both") {
6647
6610
  const hookResult = installHook();
6648
6611
  if (hookResult.installed) {
6649
- console.log(` ${chalk8.green("\u2713")} Claude Code hook installed \u2014 docs update on session end`);
6650
- console.log(chalk8.dim(" Run ") + chalk8.hex("#83D1EB")("caliber hooks --remove") + chalk8.dim(" to disable"));
6612
+ console.log(` ${chalk9.green("\u2713")} Claude Code hook installed \u2014 docs update on session end`);
6613
+ console.log(chalk9.dim(" Run ") + chalk9.hex("#83D1EB")("caliber hooks --remove") + chalk9.dim(" to disable"));
6651
6614
  } else if (hookResult.alreadyInstalled) {
6652
- console.log(chalk8.dim(" Claude Code hook already installed"));
6615
+ console.log(chalk9.dim(" Claude Code hook already installed"));
6653
6616
  }
6654
6617
  const learnResult = installLearningHooks();
6655
6618
  if (learnResult.installed) {
6656
- console.log(` ${chalk8.green("\u2713")} Learning hooks installed \u2014 session insights captured automatically`);
6657
- console.log(chalk8.dim(" Run ") + chalk8.hex("#83D1EB")("caliber learn remove") + chalk8.dim(" to disable"));
6619
+ console.log(` ${chalk9.green("\u2713")} Learning hooks installed \u2014 session insights captured automatically`);
6620
+ console.log(chalk9.dim(" Run ") + chalk9.hex("#83D1EB")("caliber learn remove") + chalk9.dim(" to disable"));
6658
6621
  } else if (learnResult.alreadyInstalled) {
6659
- console.log(chalk8.dim(" Learning hooks already installed"));
6622
+ console.log(chalk9.dim(" Learning hooks already installed"));
6660
6623
  }
6661
6624
  }
6662
6625
  if (hookChoice === "precommit" || hookChoice === "both") {
6663
6626
  const precommitResult = installPreCommitHook();
6664
6627
  if (precommitResult.installed) {
6665
- console.log(` ${chalk8.green("\u2713")} Pre-commit hook installed \u2014 docs refresh before each commit`);
6666
- console.log(chalk8.dim(" Run ") + chalk8.hex("#83D1EB")("caliber hooks --remove") + chalk8.dim(" to disable"));
6628
+ console.log(` ${chalk9.green("\u2713")} Pre-commit hook installed \u2014 docs refresh before each commit`);
6629
+ console.log(chalk9.dim(" Run ") + chalk9.hex("#83D1EB")("caliber hooks --remove") + chalk9.dim(" to disable"));
6667
6630
  } else if (precommitResult.alreadyInstalled) {
6668
- console.log(chalk8.dim(" Pre-commit hook already installed"));
6631
+ console.log(chalk9.dim(" Pre-commit hook already installed"));
6669
6632
  } else {
6670
- console.log(chalk8.yellow(" Could not install pre-commit hook (not a git repository?)"));
6633
+ console.log(chalk9.yellow(" Could not install pre-commit hook (not a git repository?)"));
6671
6634
  }
6672
6635
  }
6673
6636
  if (hookChoice === "skip") {
6674
- console.log(chalk8.dim(" Skipped auto-refresh hooks. Run ") + chalk8.hex("#83D1EB")("caliber hooks --install") + chalk8.dim(" later to enable."));
6637
+ console.log(chalk9.dim(" Skipped auto-refresh hooks. Run ") + chalk9.hex("#83D1EB")("caliber hooks --install") + chalk9.dim(" later to enable."));
6675
6638
  }
6676
6639
  const afterScore = computeLocalScore(process.cwd(), targetAgent);
6677
6640
  if (afterScore.score < baselineScore.score) {
6678
6641
  trackInitScoreRegression(baselineScore.score, afterScore.score);
6679
6642
  console.log("");
6680
- console.log(chalk8.yellow(` Score would drop from ${baselineScore.score} to ${afterScore.score} \u2014 reverting changes.`));
6643
+ console.log(chalk9.yellow(` Score would drop from ${baselineScore.score} to ${afterScore.score} \u2014 reverting changes.`));
6681
6644
  try {
6682
6645
  const { restored, removed } = undoSetup();
6683
6646
  if (restored.length > 0 || removed.length > 0) {
6684
- console.log(chalk8.dim(` Reverted ${restored.length + removed.length} file${restored.length + removed.length === 1 ? "" : "s"} from backup.`));
6647
+ console.log(chalk9.dim(` Reverted ${restored.length + removed.length} file${restored.length + removed.length === 1 ? "" : "s"} from backup.`));
6685
6648
  }
6686
6649
  } catch {
6687
6650
  }
6688
- console.log(chalk8.dim(" Run ") + chalk8.hex("#83D1EB")("caliber init --force") + chalk8.dim(" to override.\n"));
6651
+ console.log(chalk9.dim(" Run ") + chalk9.hex("#83D1EB")("caliber init --force") + chalk9.dim(" to override.\n"));
6689
6652
  return;
6690
6653
  }
6691
6654
  if (report) {
@@ -6703,8 +6666,8 @@ async function initCommand(options) {
6703
6666
  log(options.verbose, ` Still failing: ${c.name} (${c.earnedPoints}/${c.maxPoints})${c.suggestion ? ` \u2014 ${c.suggestion}` : ""}`);
6704
6667
  }
6705
6668
  }
6706
- console.log(title.bold("\n Step 5/5 \u2014 Community skills\n"));
6707
- console.log(chalk8.dim(" Search public skill registries for skills that match your tech stack.\n"));
6669
+ console.log(title.bold("\n Step 5/5 \u2014 Skills\n"));
6670
+ console.log(chalk9.dim(" Search community registries for skills that match your tech stack.\n"));
6708
6671
  let wantsSkills;
6709
6672
  if (options.autoApprove) {
6710
6673
  wantsSkills = false;
@@ -6724,19 +6687,22 @@ async function initCommand(options) {
6724
6687
  await searchAndInstallSkills();
6725
6688
  } catch (err) {
6726
6689
  if (err.message !== "__exit__") {
6727
- console.log(chalk8.dim(" Skills search failed: " + (err.message || "unknown error")));
6690
+ console.log(chalk9.dim(" Skills search failed: " + (err.message || "unknown error")));
6728
6691
  }
6729
- console.log(chalk8.dim(" Run ") + chalk8.hex("#83D1EB")("caliber skills") + chalk8.dim(" later to try again.\n"));
6692
+ console.log(chalk9.dim(" Run ") + chalk9.hex("#83D1EB")("caliber skills") + chalk9.dim(" later to try again.\n"));
6730
6693
  }
6731
6694
  } else {
6732
6695
  trackInitSkillsSearch(false, 0);
6733
- console.log(chalk8.dim(" Skipped. Run ") + chalk8.hex("#83D1EB")("caliber skills") + chalk8.dim(" later to browse.\n"));
6696
+ console.log(chalk9.dim(" Skipped. Run ") + chalk9.hex("#83D1EB")("caliber skills") + chalk9.dim(" later to browse.\n"));
6734
6697
  }
6735
- console.log(chalk8.bold.green(" Setup complete! Your project is ready for AI-assisted development."));
6736
- console.log(chalk8.dim(" Run ") + chalk8.hex("#83D1EB")("caliber undo") + chalk8.dim(" to revert changes.\n"));
6737
- console.log(chalk8.bold(" Next steps:\n"));
6698
+ console.log(chalk9.bold.green(" Setup complete!"));
6699
+ console.log(chalk9.dim(" Your AI agents now understand your project's architecture, build commands,"));
6700
+ console.log(chalk9.dim(" testing patterns, and conventions. All changes are backed up automatically.\n"));
6701
+ console.log(chalk9.bold(" Next steps:\n"));
6738
6702
  console.log(` ${title("caliber score")} See your full config breakdown`);
6739
- console.log(` ${title("caliber skills")} Discover community skills for your stack`);
6703
+ console.log(` ${title("caliber refresh")} Update docs after code changes`);
6704
+ console.log(` ${title("caliber hooks")} Toggle auto-refresh hooks`);
6705
+ console.log(` ${title("caliber skills")} Discover community skills for your stack`);
6740
6706
  console.log(` ${title("caliber undo")} Revert all changes from this run`);
6741
6707
  console.log("");
6742
6708
  if (options.showTokens) {
@@ -6746,13 +6712,13 @@ async function initCommand(options) {
6746
6712
  report.markStep("Finished");
6747
6713
  const reportPath = path19.join(process.cwd(), ".caliber", "debug-report.md");
6748
6714
  report.write(reportPath);
6749
- console.log(chalk8.dim(` Debug report written to ${path19.relative(process.cwd(), reportPath)}
6715
+ console.log(chalk9.dim(` Debug report written to ${path19.relative(process.cwd(), reportPath)}
6750
6716
  `));
6751
6717
  }
6752
6718
  }
6753
6719
  async function refineLoop(currentSetup, _targetAgent, sessionHistory) {
6754
6720
  while (true) {
6755
- const message = await promptInput2("\nWhat would you like to change?");
6721
+ const message = await promptInput("\nWhat would you like to change?");
6756
6722
  if (!message || message.toLowerCase() === "done" || message.toLowerCase() === "accept") {
6757
6723
  return currentSetup;
6758
6724
  }
@@ -6761,9 +6727,9 @@ async function refineLoop(currentSetup, _targetAgent, sessionHistory) {
6761
6727
  }
6762
6728
  const isValid = await classifyRefineIntent(message);
6763
6729
  if (!isValid) {
6764
- console.log(chalk8.dim(" This doesn't look like a config change request."));
6765
- console.log(chalk8.dim(" Describe what to add, remove, or modify in your configs."));
6766
- console.log(chalk8.dim(' Type "done" to accept the current setup.\n'));
6730
+ console.log(chalk9.dim(" This doesn't look like a config change request."));
6731
+ console.log(chalk9.dim(" Describe what to add, remove, or modify in your configs."));
6732
+ console.log(chalk9.dim(' Type "done" to accept the current setup.\n'));
6767
6733
  continue;
6768
6734
  }
6769
6735
  const refineSpinner = ora2("Refining setup...").start();
@@ -6784,10 +6750,10 @@ async function refineLoop(currentSetup, _targetAgent, sessionHistory) {
6784
6750
  });
6785
6751
  refineSpinner.succeed("Setup updated");
6786
6752
  printSetupSummary(refined);
6787
- console.log(chalk8.dim('Type "done" to accept, or describe more changes.'));
6753
+ console.log(chalk9.dim('Type "done" to accept, or describe more changes.'));
6788
6754
  } else {
6789
6755
  refineSpinner.fail("Refinement failed \u2014 could not parse AI response.");
6790
- console.log(chalk8.dim('Try rephrasing your request, or type "done" to keep the current setup.'));
6756
+ console.log(chalk9.dim('Try rephrasing your request, or type "done" to keep the current setup.'));
6791
6757
  }
6792
6758
  }
6793
6759
  }
@@ -6855,15 +6821,6 @@ ${JSON.stringify(checkList, null, 2)}`,
6855
6821
  return [];
6856
6822
  }
6857
6823
  }
6858
- function promptInput2(question) {
6859
- const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
6860
- return new Promise((resolve2) => {
6861
- rl.question(chalk8.cyan(`${question} `), (answer) => {
6862
- rl.close();
6863
- resolve2(answer.trim());
6864
- });
6865
- });
6866
- }
6867
6824
  async function promptAgent() {
6868
6825
  const selected = await checkbox({
6869
6826
  message: "Which coding agents do you use? (toggle with space)",
@@ -6911,26 +6868,26 @@ function printSetupSummary(setup) {
6911
6868
  const fileDescriptions = setup.fileDescriptions;
6912
6869
  const deletions = setup.deletions;
6913
6870
  console.log("");
6914
- console.log(chalk8.bold(" Proposed changes:\n"));
6871
+ console.log(chalk9.bold(" Proposed changes:\n"));
6915
6872
  const getDescription = (filePath) => {
6916
6873
  return fileDescriptions?.[filePath];
6917
6874
  };
6918
6875
  if (claude) {
6919
6876
  if (claude.claudeMd) {
6920
- const icon = fs24.existsSync("CLAUDE.md") ? chalk8.yellow("~") : chalk8.green("+");
6877
+ const icon = fs24.existsSync("CLAUDE.md") ? chalk9.yellow("~") : chalk9.green("+");
6921
6878
  const desc = getDescription("CLAUDE.md");
6922
- console.log(` ${icon} ${chalk8.bold("CLAUDE.md")}`);
6923
- if (desc) console.log(chalk8.dim(` ${desc}`));
6879
+ console.log(` ${icon} ${chalk9.bold("CLAUDE.md")}`);
6880
+ if (desc) console.log(chalk9.dim(` ${desc}`));
6924
6881
  console.log("");
6925
6882
  }
6926
6883
  const skills = claude.skills;
6927
6884
  if (Array.isArray(skills) && skills.length > 0) {
6928
6885
  for (const skill of skills) {
6929
6886
  const skillPath = `.claude/skills/${skill.name}/SKILL.md`;
6930
- const icon = fs24.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
6887
+ const icon = fs24.existsSync(skillPath) ? chalk9.yellow("~") : chalk9.green("+");
6931
6888
  const desc = getDescription(skillPath);
6932
- console.log(` ${icon} ${chalk8.bold(skillPath)}`);
6933
- console.log(chalk8.dim(` ${desc || skill.description || skill.name}`));
6889
+ console.log(` ${icon} ${chalk9.bold(skillPath)}`);
6890
+ console.log(chalk9.dim(` ${desc || skill.description || skill.name}`));
6934
6891
  console.log("");
6935
6892
  }
6936
6893
  }
@@ -6938,40 +6895,40 @@ function printSetupSummary(setup) {
6938
6895
  const codex = setup.codex;
6939
6896
  if (codex) {
6940
6897
  if (codex.agentsMd) {
6941
- const icon = fs24.existsSync("AGENTS.md") ? chalk8.yellow("~") : chalk8.green("+");
6898
+ const icon = fs24.existsSync("AGENTS.md") ? chalk9.yellow("~") : chalk9.green("+");
6942
6899
  const desc = getDescription("AGENTS.md");
6943
- console.log(` ${icon} ${chalk8.bold("AGENTS.md")}`);
6944
- if (desc) console.log(chalk8.dim(` ${desc}`));
6900
+ console.log(` ${icon} ${chalk9.bold("AGENTS.md")}`);
6901
+ if (desc) console.log(chalk9.dim(` ${desc}`));
6945
6902
  console.log("");
6946
6903
  }
6947
6904
  const codexSkills = codex.skills;
6948
6905
  if (Array.isArray(codexSkills) && codexSkills.length > 0) {
6949
6906
  for (const skill of codexSkills) {
6950
6907
  const skillPath = `.agents/skills/${skill.name}/SKILL.md`;
6951
- const icon = fs24.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
6908
+ const icon = fs24.existsSync(skillPath) ? chalk9.yellow("~") : chalk9.green("+");
6952
6909
  const desc = getDescription(skillPath);
6953
- console.log(` ${icon} ${chalk8.bold(skillPath)}`);
6954
- console.log(chalk8.dim(` ${desc || skill.description || skill.name}`));
6910
+ console.log(` ${icon} ${chalk9.bold(skillPath)}`);
6911
+ console.log(chalk9.dim(` ${desc || skill.description || skill.name}`));
6955
6912
  console.log("");
6956
6913
  }
6957
6914
  }
6958
6915
  }
6959
6916
  if (cursor) {
6960
6917
  if (cursor.cursorrules) {
6961
- const icon = fs24.existsSync(".cursorrules") ? chalk8.yellow("~") : chalk8.green("+");
6918
+ const icon = fs24.existsSync(".cursorrules") ? chalk9.yellow("~") : chalk9.green("+");
6962
6919
  const desc = getDescription(".cursorrules");
6963
- console.log(` ${icon} ${chalk8.bold(".cursorrules")}`);
6964
- if (desc) console.log(chalk8.dim(` ${desc}`));
6920
+ console.log(` ${icon} ${chalk9.bold(".cursorrules")}`);
6921
+ if (desc) console.log(chalk9.dim(` ${desc}`));
6965
6922
  console.log("");
6966
6923
  }
6967
6924
  const cursorSkills = cursor.skills;
6968
6925
  if (Array.isArray(cursorSkills) && cursorSkills.length > 0) {
6969
6926
  for (const skill of cursorSkills) {
6970
6927
  const skillPath = `.cursor/skills/${skill.name}/SKILL.md`;
6971
- const icon = fs24.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
6928
+ const icon = fs24.existsSync(skillPath) ? chalk9.yellow("~") : chalk9.green("+");
6972
6929
  const desc = getDescription(skillPath);
6973
- console.log(` ${icon} ${chalk8.bold(skillPath)}`);
6974
- console.log(chalk8.dim(` ${desc || skill.description || skill.name}`));
6930
+ console.log(` ${icon} ${chalk9.bold(skillPath)}`);
6931
+ console.log(chalk9.dim(` ${desc || skill.description || skill.name}`));
6975
6932
  console.log("");
6976
6933
  }
6977
6934
  }
@@ -6979,35 +6936,67 @@ function printSetupSummary(setup) {
6979
6936
  if (Array.isArray(rules) && rules.length > 0) {
6980
6937
  for (const rule of rules) {
6981
6938
  const rulePath = `.cursor/rules/${rule.filename}`;
6982
- const icon = fs24.existsSync(rulePath) ? chalk8.yellow("~") : chalk8.green("+");
6939
+ const icon = fs24.existsSync(rulePath) ? chalk9.yellow("~") : chalk9.green("+");
6983
6940
  const desc = getDescription(rulePath);
6984
- console.log(` ${icon} ${chalk8.bold(rulePath)}`);
6941
+ console.log(` ${icon} ${chalk9.bold(rulePath)}`);
6985
6942
  if (desc) {
6986
- console.log(chalk8.dim(` ${desc}`));
6943
+ console.log(chalk9.dim(` ${desc}`));
6987
6944
  } else {
6988
6945
  const firstLine = rule.content.split("\n").filter((l) => l.trim() && !l.trim().startsWith("#"))[0];
6989
- if (firstLine) console.log(chalk8.dim(` ${firstLine.trim().slice(0, 80)}`));
6946
+ if (firstLine) console.log(chalk9.dim(` ${firstLine.trim().slice(0, 80)}`));
6990
6947
  }
6991
6948
  console.log("");
6992
6949
  }
6993
6950
  }
6994
6951
  }
6995
- if (!codex && !fs24.existsSync("AGENTS.md")) {
6996
- console.log(` ${chalk8.green("+")} ${chalk8.bold("AGENTS.md")}`);
6997
- console.log(chalk8.dim(" Cross-agent coordination file"));
6998
- console.log("");
6999
- }
7000
6952
  if (Array.isArray(deletions) && deletions.length > 0) {
7001
6953
  for (const del of deletions) {
7002
- console.log(` ${chalk8.red("-")} ${chalk8.bold(del.filePath)}`);
7003
- console.log(chalk8.dim(` ${del.reason}`));
6954
+ console.log(` ${chalk9.red("-")} ${chalk9.bold(del.filePath)}`);
6955
+ console.log(chalk9.dim(` ${del.reason}`));
7004
6956
  console.log("");
7005
6957
  }
7006
6958
  }
7007
- console.log(` ${chalk8.green("+")} ${chalk8.dim("new")} ${chalk8.yellow("~")} ${chalk8.dim("modified")} ${chalk8.red("-")} ${chalk8.dim("removed")}`);
6959
+ console.log(` ${chalk9.green("+")} ${chalk9.dim("new")} ${chalk9.yellow("~")} ${chalk9.dim("modified")} ${chalk9.red("-")} ${chalk9.dim("removed")}`);
7008
6960
  console.log("");
7009
6961
  }
7010
- function ensurePermissions() {
6962
+ function derivePermissions(fingerprint) {
6963
+ const perms = ["Bash(git *)"];
6964
+ const langs = new Set(fingerprint.languages.map((l) => l.toLowerCase()));
6965
+ const tools = new Set(fingerprint.tools.map((t) => t.toLowerCase()));
6966
+ const hasFile = (name) => fingerprint.fileTree.some((f) => f === name || f === `./${name}`);
6967
+ if (langs.has("typescript") || langs.has("javascript") || hasFile("package.json")) {
6968
+ perms.push("Bash(npm run *)", "Bash(npx *)");
6969
+ }
6970
+ if (langs.has("python") || hasFile("pyproject.toml") || hasFile("requirements.txt")) {
6971
+ perms.push("Bash(python *)", "Bash(pip *)", "Bash(pytest *)");
6972
+ }
6973
+ if (langs.has("go") || hasFile("go.mod")) {
6974
+ perms.push("Bash(go *)");
6975
+ }
6976
+ if (langs.has("rust") || hasFile("Cargo.toml")) {
6977
+ perms.push("Bash(cargo *)");
6978
+ }
6979
+ if (langs.has("java") || langs.has("kotlin")) {
6980
+ if (hasFile("gradlew")) perms.push("Bash(./gradlew *)");
6981
+ if (hasFile("mvnw")) perms.push("Bash(./mvnw *)");
6982
+ if (hasFile("pom.xml")) perms.push("Bash(mvn *)");
6983
+ if (hasFile("build.gradle") || hasFile("build.gradle.kts")) perms.push("Bash(gradle *)");
6984
+ }
6985
+ if (langs.has("ruby") || hasFile("Gemfile")) {
6986
+ perms.push("Bash(bundle *)", "Bash(rake *)");
6987
+ }
6988
+ if (tools.has("terraform") || hasFile("main.tf")) {
6989
+ perms.push("Bash(terraform *)");
6990
+ }
6991
+ if (tools.has("docker") || hasFile("Dockerfile") || hasFile("docker-compose.yml")) {
6992
+ perms.push("Bash(docker *)");
6993
+ }
6994
+ if (hasFile("Makefile")) {
6995
+ perms.push("Bash(make *)");
6996
+ }
6997
+ return [...new Set(perms)];
6998
+ }
6999
+ function ensurePermissions(fingerprint) {
7011
7000
  const settingsPath = ".claude/settings.json";
7012
7001
  let settings = {};
7013
7002
  try {
@@ -7019,12 +7008,7 @@ function ensurePermissions() {
7019
7008
  const permissions = settings.permissions ?? {};
7020
7009
  const allow = permissions.allow;
7021
7010
  if (Array.isArray(allow) && allow.length > 0) return;
7022
- permissions.allow = [
7023
- "Bash(npm run *)",
7024
- "Bash(npx vitest *)",
7025
- "Bash(npx tsc *)",
7026
- "Bash(git *)"
7027
- ];
7011
+ permissions.allow = derivePermissions(fingerprint);
7028
7012
  settings.permissions = permissions;
7029
7013
  if (!fs24.existsSync(".claude")) fs24.mkdirSync(".claude", { recursive: true });
7030
7014
  fs24.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
@@ -7032,20 +7016,20 @@ function ensurePermissions() {
7032
7016
  function displayTokenUsage() {
7033
7017
  const summary = getUsageSummary();
7034
7018
  if (summary.length === 0) {
7035
- console.log(chalk8.dim(" Token tracking not available for this provider.\n"));
7019
+ console.log(chalk9.dim(" Token tracking not available for this provider.\n"));
7036
7020
  return;
7037
7021
  }
7038
- console.log(chalk8.bold(" Token usage:\n"));
7022
+ console.log(chalk9.bold(" Token usage:\n"));
7039
7023
  let totalIn = 0;
7040
7024
  let totalOut = 0;
7041
7025
  for (const m of summary) {
7042
7026
  totalIn += m.inputTokens;
7043
7027
  totalOut += m.outputTokens;
7044
- const cacheInfo = m.cacheReadTokens > 0 || m.cacheWriteTokens > 0 ? chalk8.dim(` (cache: ${m.cacheReadTokens.toLocaleString()} read, ${m.cacheWriteTokens.toLocaleString()} write)`) : "";
7045
- console.log(` ${chalk8.dim(m.model)}: ${m.inputTokens.toLocaleString()} in / ${m.outputTokens.toLocaleString()} out (${m.calls} call${m.calls === 1 ? "" : "s"})${cacheInfo}`);
7028
+ const cacheInfo = m.cacheReadTokens > 0 || m.cacheWriteTokens > 0 ? chalk9.dim(` (cache: ${m.cacheReadTokens.toLocaleString()} read, ${m.cacheWriteTokens.toLocaleString()} write)`) : "";
7029
+ console.log(` ${chalk9.dim(m.model)}: ${m.inputTokens.toLocaleString()} in / ${m.outputTokens.toLocaleString()} out (${m.calls} call${m.calls === 1 ? "" : "s"})${cacheInfo}`);
7046
7030
  }
7047
7031
  if (summary.length > 1) {
7048
- console.log(` ${chalk8.dim("Total")}: ${totalIn.toLocaleString()} in / ${totalOut.toLocaleString()} out`);
7032
+ console.log(` ${chalk9.dim("Total")}: ${totalIn.toLocaleString()} in / ${totalOut.toLocaleString()} out`);
7049
7033
  }
7050
7034
  console.log("");
7051
7035
  }
@@ -7066,14 +7050,14 @@ function writeErrorLog(config, rawOutput, error, stopReason) {
7066
7050
  lines.push("## Raw LLM Output", "```", rawOutput || "(empty)", "```");
7067
7051
  fs24.mkdirSync(path19.join(process.cwd(), ".caliber"), { recursive: true });
7068
7052
  fs24.writeFileSync(logPath, lines.join("\n"));
7069
- console.log(chalk8.dim(`
7053
+ console.log(chalk9.dim(`
7070
7054
  Error log written to .caliber/error-log.md`));
7071
7055
  } catch {
7072
7056
  }
7073
7057
  }
7074
7058
 
7075
7059
  // src/commands/undo.ts
7076
- import chalk9 from "chalk";
7060
+ import chalk10 from "chalk";
7077
7061
  import ora3 from "ora";
7078
7062
  function undoCommand() {
7079
7063
  const spinner = ora3("Reverting setup...").start();
@@ -7086,26 +7070,26 @@ function undoCommand() {
7086
7070
  trackUndoExecuted();
7087
7071
  spinner.succeed("Setup reverted successfully.\n");
7088
7072
  if (restored.length > 0) {
7089
- console.log(chalk9.cyan(" Restored from backup:"));
7073
+ console.log(chalk10.cyan(" Restored from backup:"));
7090
7074
  for (const file of restored) {
7091
- console.log(` ${chalk9.green("\u21A9")} ${file}`);
7075
+ console.log(` ${chalk10.green("\u21A9")} ${file}`);
7092
7076
  }
7093
7077
  }
7094
7078
  if (removed.length > 0) {
7095
- console.log(chalk9.cyan(" Removed:"));
7079
+ console.log(chalk10.cyan(" Removed:"));
7096
7080
  for (const file of removed) {
7097
- console.log(` ${chalk9.red("\u2717")} ${file}`);
7081
+ console.log(` ${chalk10.red("\u2717")} ${file}`);
7098
7082
  }
7099
7083
  }
7100
7084
  console.log("");
7101
7085
  } catch (err) {
7102
- spinner.fail(chalk9.red(err instanceof Error ? err.message : "Undo failed"));
7086
+ spinner.fail(chalk10.red(err instanceof Error ? err.message : "Undo failed"));
7103
7087
  throw new Error("__exit__");
7104
7088
  }
7105
7089
  }
7106
7090
 
7107
7091
  // src/commands/status.ts
7108
- import chalk10 from "chalk";
7092
+ import chalk11 from "chalk";
7109
7093
  import fs25 from "fs";
7110
7094
  init_config();
7111
7095
  async function statusCommand(options) {
@@ -7120,40 +7104,40 @@ async function statusCommand(options) {
7120
7104
  }, null, 2));
7121
7105
  return;
7122
7106
  }
7123
- console.log(chalk10.bold("\nCaliber Status\n"));
7107
+ console.log(chalk11.bold("\nCaliber Status\n"));
7124
7108
  if (config) {
7125
- console.log(` LLM: ${chalk10.green(config.provider)} (${config.model})`);
7109
+ console.log(` LLM: ${chalk11.green(config.provider)} (${config.model})`);
7126
7110
  } else {
7127
- console.log(` LLM: ${chalk10.yellow("Not configured")} \u2014 run ${chalk10.hex("#83D1EB")("caliber config")}`);
7111
+ console.log(` LLM: ${chalk11.yellow("Not configured")} \u2014 run ${chalk11.hex("#83D1EB")("caliber config")}`);
7128
7112
  }
7129
7113
  if (!manifest) {
7130
- console.log(` Setup: ${chalk10.dim("No setup applied")}`);
7131
- console.log(chalk10.dim("\n Run ") + chalk10.hex("#83D1EB")("caliber init") + chalk10.dim(" to get started.\n"));
7114
+ console.log(` Setup: ${chalk11.dim("No setup applied")}`);
7115
+ console.log(chalk11.dim("\n Run ") + chalk11.hex("#83D1EB")("caliber init") + chalk11.dim(" to get started.\n"));
7132
7116
  return;
7133
7117
  }
7134
- console.log(` Files managed: ${chalk10.cyan(manifest.entries.length.toString())}`);
7118
+ console.log(` Files managed: ${chalk11.cyan(manifest.entries.length.toString())}`);
7135
7119
  for (const entry of manifest.entries) {
7136
7120
  const exists = fs25.existsSync(entry.path);
7137
- const icon = exists ? chalk10.green("\u2713") : chalk10.red("\u2717");
7121
+ const icon = exists ? chalk11.green("\u2713") : chalk11.red("\u2717");
7138
7122
  console.log(` ${icon} ${entry.path} (${entry.action})`);
7139
7123
  }
7140
7124
  console.log("");
7141
7125
  }
7142
7126
 
7143
7127
  // src/commands/regenerate.ts
7144
- import chalk11 from "chalk";
7128
+ import chalk12 from "chalk";
7145
7129
  import ora4 from "ora";
7146
7130
  import select6 from "@inquirer/select";
7147
7131
  init_config();
7148
7132
  async function regenerateCommand(options) {
7149
7133
  const config = loadConfig();
7150
7134
  if (!config) {
7151
- console.log(chalk11.red("No LLM provider configured. Run ") + chalk11.hex("#83D1EB")("caliber config") + chalk11.red(" first."));
7135
+ console.log(chalk12.red("No LLM provider configured. Run ") + chalk12.hex("#83D1EB")("caliber config") + chalk12.red(" first."));
7152
7136
  throw new Error("__exit__");
7153
7137
  }
7154
7138
  const manifest = readManifest();
7155
7139
  if (!manifest) {
7156
- console.log(chalk11.yellow("No existing setup found. Run ") + chalk11.hex("#83D1EB")("caliber init") + chalk11.yellow(" first."));
7140
+ console.log(chalk12.yellow("No existing setup found. Run ") + chalk12.hex("#83D1EB")("caliber init") + chalk12.yellow(" first."));
7157
7141
  throw new Error("__exit__");
7158
7142
  }
7159
7143
  const targetAgent = readState()?.targetAgent ?? ["claude", "cursor"];
@@ -7164,7 +7148,7 @@ async function regenerateCommand(options) {
7164
7148
  const baselineScore = computeLocalScore(process.cwd(), targetAgent);
7165
7149
  displayScoreSummary(baselineScore);
7166
7150
  if (baselineScore.score === 100) {
7167
- console.log(chalk11.green(" Your setup is already at 100/100 \u2014 nothing to regenerate.\n"));
7151
+ console.log(chalk12.green(" Your setup is already at 100/100 \u2014 nothing to regenerate.\n"));
7168
7152
  return;
7169
7153
  }
7170
7154
  const genSpinner = ora4("Regenerating setup...").start();
@@ -7202,21 +7186,21 @@ async function regenerateCommand(options) {
7202
7186
  throw new Error("__exit__");
7203
7187
  }
7204
7188
  genSpinner.succeed("Setup regenerated");
7205
- const setupFiles = collectSetupFiles(generatedSetup);
7189
+ const setupFiles = collectSetupFiles(generatedSetup, targetAgent);
7206
7190
  const staged = stageFiles(setupFiles, process.cwd());
7207
7191
  const totalChanges = staged.newFiles + staged.modifiedFiles;
7208
- console.log(chalk11.dim(`
7209
- ${chalk11.green(`${staged.newFiles} new`)} / ${chalk11.yellow(`${staged.modifiedFiles} modified`)} file${totalChanges !== 1 ? "s" : ""}
7192
+ console.log(chalk12.dim(`
7193
+ ${chalk12.green(`${staged.newFiles} new`)} / ${chalk12.yellow(`${staged.modifiedFiles} modified`)} file${totalChanges !== 1 ? "s" : ""}
7210
7194
  `));
7211
7195
  if (totalChanges === 0) {
7212
- console.log(chalk11.dim(" No changes needed \u2014 your configs are already up to date.\n"));
7196
+ console.log(chalk12.dim(" No changes needed \u2014 your configs are already up to date.\n"));
7213
7197
  cleanupStaging();
7214
7198
  return;
7215
7199
  }
7216
7200
  if (options.dryRun) {
7217
- console.log(chalk11.yellow("[Dry run] Would write:"));
7201
+ console.log(chalk12.yellow("[Dry run] Would write:"));
7218
7202
  for (const f of staged.stagedFiles) {
7219
- console.log(` ${f.isNew ? chalk11.green("+") : chalk11.yellow("~")} ${f.relativePath}`);
7203
+ console.log(` ${f.isNew ? chalk12.green("+") : chalk12.yellow("~")} ${f.relativePath}`);
7220
7204
  }
7221
7205
  cleanupStaging();
7222
7206
  return;
@@ -7235,7 +7219,7 @@ async function regenerateCommand(options) {
7235
7219
  });
7236
7220
  cleanupStaging();
7237
7221
  if (action === "decline") {
7238
- console.log(chalk11.dim("Regeneration cancelled. No files were modified."));
7222
+ console.log(chalk12.dim("Regeneration cancelled. No files were modified."));
7239
7223
  return;
7240
7224
  }
7241
7225
  const writeSpinner = ora4("Writing config files...").start();
@@ -7243,20 +7227,20 @@ async function regenerateCommand(options) {
7243
7227
  const result = writeSetup(generatedSetup);
7244
7228
  writeSpinner.succeed("Config files written");
7245
7229
  for (const file of result.written) {
7246
- console.log(` ${chalk11.green("\u2713")} ${file}`);
7230
+ console.log(` ${chalk12.green("\u2713")} ${file}`);
7247
7231
  }
7248
7232
  if (result.deleted.length > 0) {
7249
7233
  for (const file of result.deleted) {
7250
- console.log(` ${chalk11.red("\u2717")} ${file}`);
7234
+ console.log(` ${chalk12.red("\u2717")} ${file}`);
7251
7235
  }
7252
7236
  }
7253
7237
  if (result.backupDir) {
7254
- console.log(chalk11.dim(`
7238
+ console.log(chalk12.dim(`
7255
7239
  Backups saved to ${result.backupDir}`));
7256
7240
  }
7257
7241
  } catch (err) {
7258
7242
  writeSpinner.fail("Failed to write files");
7259
- console.error(chalk11.red(err instanceof Error ? err.message : "Unknown error"));
7243
+ console.error(chalk12.red(err instanceof Error ? err.message : "Unknown error"));
7260
7244
  throw new Error("__exit__");
7261
7245
  }
7262
7246
  const sha = getCurrentHeadSha();
@@ -7268,25 +7252,25 @@ async function regenerateCommand(options) {
7268
7252
  const afterScore = computeLocalScore(process.cwd(), targetAgent);
7269
7253
  if (afterScore.score < baselineScore.score) {
7270
7254
  console.log("");
7271
- console.log(chalk11.yellow(` Score would drop from ${baselineScore.score} to ${afterScore.score} \u2014 reverting changes.`));
7255
+ console.log(chalk12.yellow(` Score would drop from ${baselineScore.score} to ${afterScore.score} \u2014 reverting changes.`));
7272
7256
  try {
7273
7257
  const { restored, removed } = undoSetup();
7274
7258
  if (restored.length > 0 || removed.length > 0) {
7275
- console.log(chalk11.dim(` Reverted ${restored.length + removed.length} file${restored.length + removed.length === 1 ? "" : "s"} from backup.`));
7259
+ console.log(chalk12.dim(` Reverted ${restored.length + removed.length} file${restored.length + removed.length === 1 ? "" : "s"} from backup.`));
7276
7260
  }
7277
7261
  } catch {
7278
7262
  }
7279
- console.log(chalk11.dim(" Run ") + chalk11.hex("#83D1EB")("caliber init --force") + chalk11.dim(" to override.\n"));
7263
+ console.log(chalk12.dim(" Run ") + chalk12.hex("#83D1EB")("caliber init --force") + chalk12.dim(" to override.\n"));
7280
7264
  return;
7281
7265
  }
7282
7266
  displayScoreDelta(baselineScore, afterScore);
7283
7267
  trackRegenerateCompleted(action, Date.now());
7284
- console.log(chalk11.bold.green(" Regeneration complete!"));
7285
- console.log(chalk11.dim(" Run ") + chalk11.hex("#83D1EB")("caliber undo") + chalk11.dim(" to revert changes.\n"));
7268
+ console.log(chalk12.bold.green(" Regeneration complete!"));
7269
+ console.log(chalk12.dim(" Run ") + chalk12.hex("#83D1EB")("caliber undo") + chalk12.dim(" to revert changes.\n"));
7286
7270
  }
7287
7271
 
7288
7272
  // src/commands/score.ts
7289
- import chalk12 from "chalk";
7273
+ import chalk13 from "chalk";
7290
7274
  async function scoreCommand(options) {
7291
7275
  const dir = process.cwd();
7292
7276
  const target = options.agent ?? readState()?.targetAgent;
@@ -7301,14 +7285,14 @@ async function scoreCommand(options) {
7301
7285
  return;
7302
7286
  }
7303
7287
  displayScore(result);
7304
- const separator = chalk12.gray(" " + "\u2500".repeat(53));
7288
+ const separator = chalk13.gray(" " + "\u2500".repeat(53));
7305
7289
  console.log(separator);
7306
7290
  if (result.score < 40) {
7307
- console.log(chalk12.gray(" Run ") + chalk12.hex("#83D1EB")("caliber init") + chalk12.gray(" to generate a complete, optimized setup."));
7291
+ console.log(chalk13.gray(" Run ") + chalk13.hex("#83D1EB")("caliber init") + chalk13.gray(" to generate a complete, optimized setup."));
7308
7292
  } else if (result.score < 70) {
7309
- console.log(chalk12.gray(" Run ") + chalk12.hex("#83D1EB")("caliber init") + chalk12.gray(" to improve your setup."));
7293
+ console.log(chalk13.gray(" Run ") + chalk13.hex("#83D1EB")("caliber init") + chalk13.gray(" to improve your setup."));
7310
7294
  } else {
7311
- console.log(chalk12.green(" Looking good!") + chalk12.gray(" Run ") + chalk12.hex("#83D1EB")("caliber regenerate") + chalk12.gray(" to rebuild from scratch."));
7295
+ console.log(chalk13.green(" Looking good!") + chalk13.gray(" Run ") + chalk13.hex("#83D1EB")("caliber regenerate") + chalk13.gray(" to rebuild from scratch."));
7312
7296
  }
7313
7297
  console.log("");
7314
7298
  }
@@ -7316,7 +7300,7 @@ async function scoreCommand(options) {
7316
7300
  // src/commands/refresh.ts
7317
7301
  import fs28 from "fs";
7318
7302
  import path22 from "path";
7319
- import chalk13 from "chalk";
7303
+ import chalk14 from "chalk";
7320
7304
  import ora5 from "ora";
7321
7305
 
7322
7306
  // src/lib/git-diff.ts
@@ -7515,7 +7499,7 @@ function discoverGitRepos(parentDir) {
7515
7499
  }
7516
7500
  async function refreshSingleRepo(repoDir, options) {
7517
7501
  const quiet = !!options.quiet;
7518
- const prefix = options.label ? `${chalk13.bold(options.label)} ` : "";
7502
+ const prefix = options.label ? `${chalk14.bold(options.label)} ` : "";
7519
7503
  const state = readState();
7520
7504
  const lastSha = state?.lastRefreshSha ?? null;
7521
7505
  const diff = collectDiff(lastSha);
@@ -7524,7 +7508,7 @@ async function refreshSingleRepo(repoDir, options) {
7524
7508
  if (currentSha) {
7525
7509
  writeState({ lastRefreshSha: currentSha, lastRefreshTimestamp: (/* @__PURE__ */ new Date()).toISOString() });
7526
7510
  }
7527
- log2(quiet, chalk13.dim(`${prefix}No changes since last refresh.`));
7511
+ log2(quiet, chalk14.dim(`${prefix}No changes since last refresh.`));
7528
7512
  return;
7529
7513
  }
7530
7514
  const spinner = quiet ? null : ora5(`${prefix}Analyzing changes...`).start();
@@ -7556,10 +7540,10 @@ async function refreshSingleRepo(repoDir, options) {
7556
7540
  if (options.dryRun) {
7557
7541
  spinner?.info(`${prefix}Dry run \u2014 would update:`);
7558
7542
  for (const doc of response.docsUpdated) {
7559
- console.log(` ${chalk13.yellow("~")} ${doc}`);
7543
+ console.log(` ${chalk14.yellow("~")} ${doc}`);
7560
7544
  }
7561
7545
  if (response.changesSummary) {
7562
- console.log(chalk13.dim(`
7546
+ console.log(chalk14.dim(`
7563
7547
  ${response.changesSummary}`));
7564
7548
  }
7565
7549
  return;
@@ -7568,10 +7552,10 @@ async function refreshSingleRepo(repoDir, options) {
7568
7552
  trackRefreshCompleted(written.length, Date.now());
7569
7553
  spinner?.succeed(`${prefix}Updated ${written.length} doc${written.length === 1 ? "" : "s"}`);
7570
7554
  for (const file of written) {
7571
- log2(quiet, ` ${chalk13.green("\u2713")} ${file}`);
7555
+ log2(quiet, ` ${chalk14.green("\u2713")} ${file}`);
7572
7556
  }
7573
7557
  if (response.changesSummary) {
7574
- log2(quiet, chalk13.dim(`
7558
+ log2(quiet, chalk14.dim(`
7575
7559
  ${response.changesSummary}`));
7576
7560
  }
7577
7561
  if (currentSha) {
@@ -7588,7 +7572,7 @@ async function refreshCommand(options) {
7588
7572
  const config = loadConfig();
7589
7573
  if (!config) {
7590
7574
  if (quiet) return;
7591
- console.log(chalk13.red("No LLM provider configured. Run ") + chalk13.hex("#83D1EB")("caliber config") + chalk13.red(" (e.g. choose Cursor) or set an API key."));
7575
+ console.log(chalk14.red("No LLM provider configured. Run ") + chalk14.hex("#83D1EB")("caliber config") + chalk14.red(" (e.g. choose Cursor) or set an API key."));
7592
7576
  throw new Error("__exit__");
7593
7577
  }
7594
7578
  await validateModel({ fast: true });
@@ -7599,10 +7583,10 @@ async function refreshCommand(options) {
7599
7583
  const repos = discoverGitRepos(process.cwd());
7600
7584
  if (repos.length === 0) {
7601
7585
  if (quiet) return;
7602
- console.log(chalk13.red("Not inside a git repository and no git repos found in child directories."));
7586
+ console.log(chalk14.red("Not inside a git repository and no git repos found in child directories."));
7603
7587
  throw new Error("__exit__");
7604
7588
  }
7605
- log2(quiet, chalk13.dim(`Found ${repos.length} git repo${repos.length === 1 ? "" : "s"}
7589
+ log2(quiet, chalk14.dim(`Found ${repos.length} git repo${repos.length === 1 ? "" : "s"}
7606
7590
  `));
7607
7591
  const originalDir = process.cwd();
7608
7592
  for (const repo of repos) {
@@ -7612,7 +7596,7 @@ async function refreshCommand(options) {
7612
7596
  await refreshSingleRepo(repo, { ...options, label: repoName });
7613
7597
  } catch (err) {
7614
7598
  if (err instanceof Error && err.message === "__exit__") continue;
7615
- log2(quiet, chalk13.yellow(`${repoName}: refresh failed \u2014 ${err instanceof Error ? err.message : "unknown error"}`));
7599
+ log2(quiet, chalk14.yellow(`${repoName}: refresh failed \u2014 ${err instanceof Error ? err.message : "unknown error"}`));
7616
7600
  }
7617
7601
  }
7618
7602
  process.chdir(originalDir);
@@ -7620,13 +7604,13 @@ async function refreshCommand(options) {
7620
7604
  if (err instanceof Error && err.message === "__exit__") throw err;
7621
7605
  if (quiet) return;
7622
7606
  const msg = err instanceof Error ? err.message : "Unknown error";
7623
- console.log(chalk13.red(`Refresh failed: ${msg}`));
7607
+ console.log(chalk14.red(`Refresh failed: ${msg}`));
7624
7608
  throw new Error("__exit__");
7625
7609
  }
7626
7610
  }
7627
7611
 
7628
7612
  // src/commands/hooks.ts
7629
- import chalk14 from "chalk";
7613
+ import chalk15 from "chalk";
7630
7614
  var HOOKS = [
7631
7615
  {
7632
7616
  id: "session-end",
@@ -7646,13 +7630,13 @@ var HOOKS = [
7646
7630
  }
7647
7631
  ];
7648
7632
  function printStatus() {
7649
- console.log(chalk14.bold("\n Hooks\n"));
7633
+ console.log(chalk15.bold("\n Hooks\n"));
7650
7634
  for (const hook of HOOKS) {
7651
7635
  const installed = hook.isInstalled();
7652
- const icon = installed ? chalk14.green("\u2713") : chalk14.dim("\u2717");
7653
- const state = installed ? chalk14.green("enabled") : chalk14.dim("disabled");
7636
+ const icon = installed ? chalk15.green("\u2713") : chalk15.dim("\u2717");
7637
+ const state = installed ? chalk15.green("enabled") : chalk15.dim("disabled");
7654
7638
  console.log(` ${icon} ${hook.label.padEnd(26)} ${state}`);
7655
- console.log(chalk14.dim(` ${hook.description}`));
7639
+ console.log(chalk15.dim(` ${hook.description}`));
7656
7640
  }
7657
7641
  console.log("");
7658
7642
  }
@@ -7661,9 +7645,9 @@ async function hooksCommand(options) {
7661
7645
  for (const hook of HOOKS) {
7662
7646
  const result = hook.install();
7663
7647
  if (result.alreadyInstalled) {
7664
- console.log(chalk14.dim(` ${hook.label} already enabled.`));
7648
+ console.log(chalk15.dim(` ${hook.label} already enabled.`));
7665
7649
  } else {
7666
- console.log(chalk14.green(" \u2713") + ` ${hook.label} enabled`);
7650
+ console.log(chalk15.green(" \u2713") + ` ${hook.label} enabled`);
7667
7651
  }
7668
7652
  }
7669
7653
  return;
@@ -7672,9 +7656,9 @@ async function hooksCommand(options) {
7672
7656
  for (const hook of HOOKS) {
7673
7657
  const result = hook.remove();
7674
7658
  if (result.notFound) {
7675
- console.log(chalk14.dim(` ${hook.label} already disabled.`));
7659
+ console.log(chalk15.dim(` ${hook.label} already disabled.`));
7676
7660
  } else {
7677
- console.log(chalk14.green(" \u2713") + ` ${hook.label} removed`);
7661
+ console.log(chalk15.green(" \u2713") + ` ${hook.label} removed`);
7678
7662
  }
7679
7663
  }
7680
7664
  return;
@@ -7689,18 +7673,18 @@ async function hooksCommand(options) {
7689
7673
  const states = HOOKS.map((h) => h.isInstalled());
7690
7674
  function render() {
7691
7675
  const lines = [];
7692
- lines.push(chalk14.bold(" Hooks"));
7676
+ lines.push(chalk15.bold(" Hooks"));
7693
7677
  lines.push("");
7694
7678
  for (let i = 0; i < HOOKS.length; i++) {
7695
7679
  const hook = HOOKS[i];
7696
7680
  const enabled = states[i];
7697
- const toggle = enabled ? chalk14.green("[on] ") : chalk14.dim("[off]");
7698
- const ptr = i === cursor ? chalk14.cyan(">") : " ";
7681
+ const toggle = enabled ? chalk15.green("[on] ") : chalk15.dim("[off]");
7682
+ const ptr = i === cursor ? chalk15.cyan(">") : " ";
7699
7683
  lines.push(` ${ptr} ${toggle} ${hook.label}`);
7700
- lines.push(chalk14.dim(` ${hook.description}`));
7684
+ lines.push(chalk15.dim(` ${hook.description}`));
7701
7685
  }
7702
7686
  lines.push("");
7703
- lines.push(chalk14.dim(" \u2191\u2193 navigate \u23B5 toggle a all on n all off \u23CE apply q cancel"));
7687
+ lines.push(chalk15.dim(" \u2191\u2193 navigate \u23B5 toggle a all on n all off \u23CE apply q cancel"));
7704
7688
  return lines.join("\n");
7705
7689
  }
7706
7690
  function draw(initial) {
@@ -7731,16 +7715,16 @@ async function hooksCommand(options) {
7731
7715
  const wantEnabled = states[i];
7732
7716
  if (wantEnabled && !wasInstalled) {
7733
7717
  hook.install();
7734
- console.log(chalk14.green(" \u2713") + ` ${hook.label} enabled`);
7718
+ console.log(chalk15.green(" \u2713") + ` ${hook.label} enabled`);
7735
7719
  changed++;
7736
7720
  } else if (!wantEnabled && wasInstalled) {
7737
7721
  hook.remove();
7738
- console.log(chalk14.green(" \u2713") + ` ${hook.label} disabled`);
7722
+ console.log(chalk15.green(" \u2713") + ` ${hook.label} disabled`);
7739
7723
  changed++;
7740
7724
  }
7741
7725
  }
7742
7726
  if (changed === 0) {
7743
- console.log(chalk14.dim(" No changes."));
7727
+ console.log(chalk15.dim(" No changes."));
7744
7728
  }
7745
7729
  console.log("");
7746
7730
  }
@@ -7776,7 +7760,7 @@ async function hooksCommand(options) {
7776
7760
  case "\x1B":
7777
7761
  case "":
7778
7762
  cleanup();
7779
- console.log(chalk14.dim("\n Cancelled.\n"));
7763
+ console.log(chalk15.dim("\n Cancelled.\n"));
7780
7764
  resolve2();
7781
7765
  break;
7782
7766
  }
@@ -7787,50 +7771,50 @@ async function hooksCommand(options) {
7787
7771
 
7788
7772
  // src/commands/config.ts
7789
7773
  init_config();
7790
- import chalk15 from "chalk";
7774
+ import chalk16 from "chalk";
7791
7775
  async function configCommand() {
7792
7776
  const existing = loadConfig();
7793
7777
  if (existing) {
7794
- const displayModel = existing.model === "default" && existing.provider === "claude-cli" ? process.env.ANTHROPIC_MODEL || "default (inherited from Claude Code)" : existing.model;
7778
+ const displayModel = getDisplayModel(existing);
7795
7779
  const fastModel = getFastModel();
7796
- console.log(chalk15.bold("\nCurrent Configuration\n"));
7797
- console.log(` Provider: ${chalk15.cyan(existing.provider)}`);
7798
- console.log(` Model: ${chalk15.cyan(displayModel)}`);
7780
+ console.log(chalk16.bold("\nCurrent Configuration\n"));
7781
+ console.log(` Provider: ${chalk16.cyan(existing.provider)}`);
7782
+ console.log(` Model: ${chalk16.cyan(displayModel)}`);
7799
7783
  if (fastModel) {
7800
- console.log(` Scan: ${chalk15.cyan(fastModel)}`);
7784
+ console.log(` Scan: ${chalk16.cyan(fastModel)}`);
7801
7785
  }
7802
7786
  if (existing.apiKey) {
7803
7787
  const masked = existing.apiKey.slice(0, 8) + "..." + existing.apiKey.slice(-4);
7804
- console.log(` API Key: ${chalk15.dim(masked)}`);
7788
+ console.log(` API Key: ${chalk16.dim(masked)}`);
7805
7789
  }
7806
7790
  if (existing.provider === "cursor") {
7807
- console.log(` Seat: ${chalk15.dim("Cursor (agent acp)")}`);
7791
+ console.log(` Seat: ${chalk16.dim("Cursor (agent acp)")}`);
7808
7792
  }
7809
7793
  if (existing.provider === "claude-cli") {
7810
- console.log(` Seat: ${chalk15.dim("Claude Code (claude -p)")}`);
7794
+ console.log(` Seat: ${chalk16.dim("Claude Code (claude -p)")}`);
7811
7795
  }
7812
7796
  if (existing.baseUrl) {
7813
- console.log(` Base URL: ${chalk15.dim(existing.baseUrl)}`);
7797
+ console.log(` Base URL: ${chalk16.dim(existing.baseUrl)}`);
7814
7798
  }
7815
7799
  if (existing.vertexProjectId) {
7816
- console.log(` Vertex Project: ${chalk15.dim(existing.vertexProjectId)}`);
7817
- console.log(` Vertex Region: ${chalk15.dim(existing.vertexRegion || "us-east5")}`);
7800
+ console.log(` Vertex Project: ${chalk16.dim(existing.vertexProjectId)}`);
7801
+ console.log(` Vertex Region: ${chalk16.dim(existing.vertexRegion || "us-east5")}`);
7818
7802
  }
7819
- console.log(` Source: ${chalk15.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())}`);
7803
+ console.log(` Source: ${chalk16.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())}`);
7820
7804
  console.log("");
7821
7805
  }
7822
7806
  await runInteractiveProviderSetup();
7823
7807
  const updated = loadConfig();
7824
7808
  if (updated) trackConfigProviderSet(updated.provider);
7825
- console.log(chalk15.green("\n\u2713 Configuration saved"));
7826
- console.log(chalk15.dim(` ${getConfigFilePath()}
7809
+ console.log(chalk16.green("\n\u2713 Configuration saved"));
7810
+ console.log(chalk16.dim(` ${getConfigFilePath()}
7827
7811
  `));
7828
- console.log(chalk15.dim(" You can also set environment variables instead:"));
7829
- console.log(chalk15.dim(" ANTHROPIC_API_KEY, OPENAI_API_KEY, VERTEX_PROJECT_ID, CALIBER_USE_CURSOR_SEAT=1, or CALIBER_USE_CLAUDE_CLI=1\n"));
7812
+ console.log(chalk16.dim(" You can also set environment variables instead:"));
7813
+ console.log(chalk16.dim(" ANTHROPIC_API_KEY, OPENAI_API_KEY, VERTEX_PROJECT_ID, CALIBER_USE_CURSOR_SEAT=1, or CALIBER_USE_CLAUDE_CLI=1\n"));
7830
7814
  }
7831
7815
 
7832
7816
  // src/commands/learn.ts
7833
- import chalk16 from "chalk";
7817
+ import chalk17 from "chalk";
7834
7818
 
7835
7819
  // src/learner/stdin.ts
7836
7820
  var STDIN_TIMEOUT_MS = 5e3;
@@ -8138,46 +8122,46 @@ async function learnFinalizeCommand() {
8138
8122
  async function learnInstallCommand() {
8139
8123
  const result = installLearningHooks();
8140
8124
  if (result.alreadyInstalled) {
8141
- console.log(chalk16.dim("Learning hooks already installed."));
8125
+ console.log(chalk17.dim("Learning hooks already installed."));
8142
8126
  return;
8143
8127
  }
8144
- console.log(chalk16.green("\u2713") + " Learning hooks installed in .claude/settings.json");
8145
- console.log(chalk16.dim(" PostToolUse, PostToolUseFailure, and SessionEnd hooks active."));
8146
- console.log(chalk16.dim(" Session learnings will be written to CLAUDE.md and skills."));
8128
+ console.log(chalk17.green("\u2713") + " Learning hooks installed in .claude/settings.json");
8129
+ console.log(chalk17.dim(" PostToolUse, PostToolUseFailure, and SessionEnd hooks active."));
8130
+ console.log(chalk17.dim(" Session learnings will be written to CLAUDE.md and skills."));
8147
8131
  }
8148
8132
  async function learnRemoveCommand() {
8149
8133
  const result = removeLearningHooks();
8150
8134
  if (result.notFound) {
8151
- console.log(chalk16.dim("Learning hooks not found."));
8135
+ console.log(chalk17.dim("Learning hooks not found."));
8152
8136
  return;
8153
8137
  }
8154
- console.log(chalk16.green("\u2713") + " Learning hooks removed from .claude/settings.json");
8138
+ console.log(chalk17.green("\u2713") + " Learning hooks removed from .claude/settings.json");
8155
8139
  }
8156
8140
  async function learnStatusCommand() {
8157
8141
  const installed = areLearningHooksInstalled();
8158
8142
  const state = readState2();
8159
8143
  const eventCount = getEventCount();
8160
- console.log(chalk16.bold("Session Learning Status"));
8144
+ console.log(chalk17.bold("Session Learning Status"));
8161
8145
  console.log();
8162
8146
  if (installed) {
8163
- console.log(chalk16.green("\u2713") + " Learning hooks are " + chalk16.green("installed"));
8147
+ console.log(chalk17.green("\u2713") + " Learning hooks are " + chalk17.green("installed"));
8164
8148
  } else {
8165
- console.log(chalk16.dim("\u2717") + " Learning hooks are " + chalk16.yellow("not installed"));
8166
- console.log(chalk16.dim(" Run `caliber learn install` to enable session learning."));
8149
+ console.log(chalk17.dim("\u2717") + " Learning hooks are " + chalk17.yellow("not installed"));
8150
+ console.log(chalk17.dim(" Run `caliber learn install` to enable session learning."));
8167
8151
  }
8168
8152
  console.log();
8169
- console.log(`Events recorded: ${chalk16.cyan(String(eventCount))}`);
8170
- console.log(`Total this session: ${chalk16.cyan(String(state.eventCount))}`);
8153
+ console.log(`Events recorded: ${chalk17.cyan(String(eventCount))}`);
8154
+ console.log(`Total this session: ${chalk17.cyan(String(state.eventCount))}`);
8171
8155
  if (state.lastAnalysisTimestamp) {
8172
- console.log(`Last analysis: ${chalk16.cyan(state.lastAnalysisTimestamp)}`);
8156
+ console.log(`Last analysis: ${chalk17.cyan(state.lastAnalysisTimestamp)}`);
8173
8157
  } else {
8174
- console.log(`Last analysis: ${chalk16.dim("none")}`);
8158
+ console.log(`Last analysis: ${chalk17.dim("none")}`);
8175
8159
  }
8176
8160
  const learnedSection = readLearnedSection();
8177
8161
  if (learnedSection) {
8178
8162
  const lineCount = learnedSection.split("\n").filter(Boolean).length;
8179
8163
  console.log(`
8180
- Learned items in CLAUDE.md: ${chalk16.cyan(String(lineCount))}`);
8164
+ Learned items in CLAUDE.md: ${chalk17.cyan(String(lineCount))}`);
8181
8165
  }
8182
8166
  }
8183
8167
 
@@ -8262,7 +8246,7 @@ import fs32 from "fs";
8262
8246
  import path26 from "path";
8263
8247
  import { fileURLToPath as fileURLToPath2 } from "url";
8264
8248
  import { execSync as execSync14 } from "child_process";
8265
- import chalk17 from "chalk";
8249
+ import chalk18 from "chalk";
8266
8250
  import ora6 from "ora";
8267
8251
  import confirm2 from "@inquirer/confirm";
8268
8252
  var __dirname_vc = path26.dirname(fileURLToPath2(import.meta.url));
@@ -8296,17 +8280,17 @@ async function checkForUpdates() {
8296
8280
  const isInteractive = process.stdin.isTTY === true;
8297
8281
  if (!isInteractive) {
8298
8282
  console.log(
8299
- chalk17.yellow(
8283
+ chalk18.yellow(
8300
8284
  `
8301
8285
  Update available: ${current} -> ${latest}
8302
- Run ${chalk17.bold("npm install -g @rely-ai/caliber")} to upgrade.
8286
+ Run ${chalk18.bold("npm install -g @rely-ai/caliber")} to upgrade.
8303
8287
  `
8304
8288
  )
8305
8289
  );
8306
8290
  return;
8307
8291
  }
8308
8292
  console.log(
8309
- chalk17.yellow(`
8293
+ chalk18.yellow(`
8310
8294
  Update available: ${current} -> ${latest}`)
8311
8295
  );
8312
8296
  const shouldUpdate = await confirm2({ message: "Would you like to update now? (Y/n)", default: true });
@@ -8324,13 +8308,13 @@ Update available: ${current} -> ${latest}`)
8324
8308
  const installed = getInstalledVersion();
8325
8309
  if (installed !== latest) {
8326
8310
  spinner.fail(`Update incomplete \u2014 got ${installed ?? "unknown"}, expected ${latest}`);
8327
- console.log(chalk17.yellow(`Run ${chalk17.bold(`npm install -g @rely-ai/caliber@${latest}`)} manually.
8311
+ console.log(chalk18.yellow(`Run ${chalk18.bold(`npm install -g @rely-ai/caliber@${latest}`)} manually.
8328
8312
  `));
8329
8313
  return;
8330
8314
  }
8331
- spinner.succeed(chalk17.green(`Updated to ${latest}`));
8315
+ spinner.succeed(chalk18.green(`Updated to ${latest}`));
8332
8316
  const args = process.argv.slice(2);
8333
- console.log(chalk17.dim(`
8317
+ console.log(chalk18.dim(`
8334
8318
  Restarting: caliber ${args.join(" ")}
8335
8319
  `));
8336
8320
  execSync14(`caliber ${args.map((a) => JSON.stringify(a)).join(" ")}`, {
@@ -8343,11 +8327,11 @@ Restarting: caliber ${args.join(" ")}
8343
8327
  if (err instanceof Error) {
8344
8328
  const stderr = err.stderr;
8345
8329
  const errMsg = stderr ? String(stderr).trim().split("\n").pop() : err.message.split("\n")[0];
8346
- if (errMsg && !errMsg.includes("SIGTERM")) console.log(chalk17.dim(` ${errMsg}`));
8330
+ if (errMsg && !errMsg.includes("SIGTERM")) console.log(chalk18.dim(` ${errMsg}`));
8347
8331
  }
8348
8332
  console.log(
8349
- chalk17.yellow(
8350
- `Run ${chalk17.bold(`npm install -g @rely-ai/caliber@${latest}`)} manually to upgrade.
8333
+ chalk18.yellow(
8334
+ `Run ${chalk18.bold(`npm install -g @rely-ai/caliber@${latest}`)} manually to upgrade.
8351
8335
  `
8352
8336
  )
8353
8337
  );