@rely-ai/caliber 0.9.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -14
- package/dist/bin.js +57 -39
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/social-preview.svg" alt="Caliber" width="640">
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://www.npmjs.com/package/@rely-ai/caliber"><img src="https://img.shields.io/npm/v/@rely-ai/caliber" alt="npm version"></a>
|
|
7
|
+
<a href="./LICENSE"><img src="https://img.shields.io/npm/l/@rely-ai/caliber" alt="license"></a>
|
|
8
|
+
<a href="https://nodejs.org"><img src="https://img.shields.io/node/v/@rely-ai/caliber" alt="node"></a>
|
|
9
|
+
</p>
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
<p align="center"><strong>Analyze your codebase. Generate optimized AI agent configs. One command.</strong></p>
|
|
8
12
|
|
|
9
13
|
Caliber scans your project — languages, frameworks, dependencies, file structure — and generates tailored config files for Claude Code and Cursor. If configs already exist, it audits them and suggests improvements.
|
|
10
14
|
|
|
@@ -13,7 +17,7 @@ Caliber scans your project — languages, frameworks, dependencies, file structu
|
|
|
13
17
|
## Quick Start
|
|
14
18
|
|
|
15
19
|
```bash
|
|
16
|
-
npx @rely-ai/caliber
|
|
20
|
+
npx @rely-ai/caliber onboard
|
|
17
21
|
```
|
|
18
22
|
|
|
19
23
|
That's it. On first run, Caliber walks you through provider setup interactively.
|
|
@@ -22,19 +26,19 @@ Or install globally:
|
|
|
22
26
|
|
|
23
27
|
```bash
|
|
24
28
|
npm install -g @rely-ai/caliber
|
|
25
|
-
caliber
|
|
29
|
+
caliber onboard
|
|
26
30
|
```
|
|
27
31
|
|
|
28
32
|
> **Already have an API key?** Skip the interactive setup:
|
|
29
33
|
> ```bash
|
|
30
34
|
> export ANTHROPIC_API_KEY=sk-ant-...
|
|
31
|
-
> npx @rely-ai/caliber
|
|
35
|
+
> npx @rely-ai/caliber onboard
|
|
32
36
|
> ```
|
|
33
37
|
|
|
34
38
|
## How It Works
|
|
35
39
|
|
|
36
40
|
```
|
|
37
|
-
caliber
|
|
41
|
+
caliber onboard
|
|
38
42
|
│
|
|
39
43
|
├─ 1. Scan Analyze languages, frameworks, dependencies, file structure,
|
|
40
44
|
│ and existing agent configs in your project
|
|
@@ -64,16 +68,16 @@ If these files already exist, Caliber audits them against your actual codebase a
|
|
|
64
68
|
|
|
65
69
|
| Command | Description |
|
|
66
70
|
|---------|-------------|
|
|
67
|
-
| `caliber
|
|
71
|
+
| `caliber onboard` | Onboard your project for AI-assisted development |
|
|
68
72
|
| `caliber score` | Score your config quality (deterministic, no LLM needed) |
|
|
69
73
|
| `caliber recommend` | Discover and install skills from [skills.sh](https://skills.sh) |
|
|
70
74
|
| `caliber config` | Configure LLM provider, API key, and model |
|
|
71
75
|
|
|
72
76
|
```bash
|
|
73
|
-
caliber
|
|
74
|
-
caliber
|
|
75
|
-
caliber
|
|
76
|
-
caliber
|
|
77
|
+
caliber onboard --agent claude # Target Claude Code only
|
|
78
|
+
caliber onboard --agent cursor # Target Cursor only
|
|
79
|
+
caliber onboard --agent both # Target both
|
|
80
|
+
caliber onboard --dry-run # Preview without writing files
|
|
77
81
|
caliber score --json # Machine-readable output
|
|
78
82
|
```
|
|
79
83
|
|
package/dist/bin.js
CHANGED
|
@@ -55,7 +55,7 @@ import fs24 from "fs";
|
|
|
55
55
|
import path21 from "path";
|
|
56
56
|
import { fileURLToPath } from "url";
|
|
57
57
|
|
|
58
|
-
// src/commands/
|
|
58
|
+
// src/commands/onboard.ts
|
|
59
59
|
import chalk4 from "chalk";
|
|
60
60
|
import ora from "ora";
|
|
61
61
|
import readline3 from "readline";
|
|
@@ -2194,7 +2194,7 @@ function openDiffsInEditor(editor, files) {
|
|
|
2194
2194
|
}
|
|
2195
2195
|
}
|
|
2196
2196
|
|
|
2197
|
-
// src/commands/
|
|
2197
|
+
// src/commands/onboard.ts
|
|
2198
2198
|
import { createTwoFilesPatch } from "diff";
|
|
2199
2199
|
|
|
2200
2200
|
// src/lib/hooks.ts
|
|
@@ -3820,7 +3820,7 @@ function displayScoreDelta(before, after) {
|
|
|
3820
3820
|
}
|
|
3821
3821
|
}
|
|
3822
3822
|
|
|
3823
|
-
// src/commands/
|
|
3823
|
+
// src/commands/onboard.ts
|
|
3824
3824
|
async function initCommand(options) {
|
|
3825
3825
|
const brand = chalk4.hex("#EB9D83");
|
|
3826
3826
|
const title = chalk4.hex("#83D1EB");
|
|
@@ -3832,18 +3832,16 @@ async function initCommand(options) {
|
|
|
3832
3832
|
\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
|
|
3833
3833
|
\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
|
|
3834
3834
|
`));
|
|
3835
|
-
console.log(chalk4.dim("
|
|
3836
|
-
console.log(title.bold("
|
|
3837
|
-
console.log(chalk4.dim(" Caliber
|
|
3838
|
-
console.log(chalk4.dim("
|
|
3839
|
-
console.log(
|
|
3840
|
-
console.log(chalk4.dim("
|
|
3841
|
-
console.log(
|
|
3842
|
-
console.log(chalk4.dim("
|
|
3843
|
-
console.log(chalk4.dim("
|
|
3844
|
-
console.log(
|
|
3845
|
-
console.log(chalk4.dim(" 4. Apply Config files are written with backups\n"));
|
|
3846
|
-
console.log(title.bold(" Step 1/4 \u2014 How do you want to use Caliber?\n"));
|
|
3835
|
+
console.log(chalk4.dim(" Onboard your project for AI-assisted development\n"));
|
|
3836
|
+
console.log(title.bold(" Welcome to Caliber\n"));
|
|
3837
|
+
console.log(chalk4.dim(" Caliber analyzes your codebase and creates tailored config files"));
|
|
3838
|
+
console.log(chalk4.dim(" so your AI coding agents understand your project from day one.\n"));
|
|
3839
|
+
console.log(title.bold(" How onboarding works:\n"));
|
|
3840
|
+
console.log(chalk4.dim(" 1. Connect Set up your LLM provider"));
|
|
3841
|
+
console.log(chalk4.dim(" 2. Discover Analyze your code, dependencies, and structure"));
|
|
3842
|
+
console.log(chalk4.dim(" 3. Generate Create config files tailored to your project"));
|
|
3843
|
+
console.log(chalk4.dim(" 4. Review Preview, refine, and apply the changes\n"));
|
|
3844
|
+
console.log(title.bold(" Step 1/4 \u2014 Connect your LLM\n"));
|
|
3847
3845
|
let config = loadConfig();
|
|
3848
3846
|
if (!config) {
|
|
3849
3847
|
console.log(chalk4.dim(" No LLM provider set yet. Choose how to run Caliber:\n"));
|
|
@@ -3860,14 +3858,14 @@ async function initCommand(options) {
|
|
|
3860
3858
|
console.log(chalk4.red(" Setup was cancelled or failed.\n"));
|
|
3861
3859
|
throw new Error("__exit__");
|
|
3862
3860
|
}
|
|
3863
|
-
console.log(chalk4.green(" \u2713 Provider saved.
|
|
3861
|
+
console.log(chalk4.green(" \u2713 Provider saved. Let's continue.\n"));
|
|
3864
3862
|
}
|
|
3865
3863
|
const displayModel = config.model === "default" && config.provider === "claude-cli" ? process.env.ANTHROPIC_MODEL || "default (inherited from Claude Code)" : config.model;
|
|
3866
3864
|
const fastModel = process.env.ANTHROPIC_SMALL_FAST_MODEL;
|
|
3867
3865
|
const modelLine = fastModel ? ` Provider: ${config.provider} | Model: ${displayModel} | Scan: ${fastModel}` : ` Provider: ${config.provider} | Model: ${displayModel}`;
|
|
3868
3866
|
console.log(chalk4.dim(modelLine + "\n"));
|
|
3869
|
-
console.log(title.bold(" Step 2/4 \u2014
|
|
3870
|
-
console.log(chalk4.dim("
|
|
3867
|
+
console.log(title.bold(" Step 2/4 \u2014 Discover your project\n"));
|
|
3868
|
+
console.log(chalk4.dim(" Learning about your languages, dependencies, structure, and existing configs.\n"));
|
|
3871
3869
|
const spinner = ora("Analyzing project...").start();
|
|
3872
3870
|
const fingerprint = collectFingerprint(process.cwd());
|
|
3873
3871
|
await enrichFingerprintWithLLM(fingerprint, process.cwd());
|
|
@@ -3881,7 +3879,7 @@ async function initCommand(options) {
|
|
|
3881
3879
|
const hasExistingConfig = !!(fingerprint.existingConfigs.claudeMd || fingerprint.existingConfigs.claudeSettings || fingerprint.existingConfigs.claudeSkills?.length || fingerprint.existingConfigs.cursorrules || fingerprint.existingConfigs.cursorRules?.length);
|
|
3882
3880
|
if (hasExistingConfig && baselineScore.score === 100) {
|
|
3883
3881
|
console.log(chalk4.bold.green(" Your setup is already optimal \u2014 nothing to change.\n"));
|
|
3884
|
-
console.log(chalk4.dim(" Run `caliber
|
|
3882
|
+
console.log(chalk4.dim(" Run `caliber onboard --force` to regenerate anyway.\n"));
|
|
3885
3883
|
if (!options.force) return;
|
|
3886
3884
|
}
|
|
3887
3885
|
const isEmpty = fingerprint.fileTree.length < 3;
|
|
@@ -3896,8 +3894,8 @@ async function initCommand(options) {
|
|
|
3896
3894
|
passingChecks = baselineScore.checks.filter((c) => c.passed).map((c) => ({ name: c.name }));
|
|
3897
3895
|
currentScore = baselineScore.score;
|
|
3898
3896
|
if (failingChecks.length > 0) {
|
|
3899
|
-
console.log(title.bold(" Step 3/4 \u2014
|
|
3900
|
-
console.log(chalk4.dim(`
|
|
3897
|
+
console.log(title.bold(" Step 3/4 \u2014 Fine-tuning\n"));
|
|
3898
|
+
console.log(chalk4.dim(` Your setup scores ${baselineScore.score}/100 \u2014 fixing ${failingChecks.length} remaining issue${failingChecks.length === 1 ? "" : "s"}:
|
|
3901
3899
|
`));
|
|
3902
3900
|
for (const check of failingChecks) {
|
|
3903
3901
|
console.log(chalk4.dim(` \u2022 ${check.name}`));
|
|
@@ -3905,12 +3903,12 @@ async function initCommand(options) {
|
|
|
3905
3903
|
console.log("");
|
|
3906
3904
|
}
|
|
3907
3905
|
} else if (hasExistingConfig) {
|
|
3908
|
-
console.log(title.bold(" Step 3/4 \u2014
|
|
3909
|
-
console.log(chalk4.dim("
|
|
3910
|
-
console.log(chalk4.dim(" and
|
|
3906
|
+
console.log(title.bold(" Step 3/4 \u2014 Improve your setup\n"));
|
|
3907
|
+
console.log(chalk4.dim(" Reviewing your existing configs against your codebase"));
|
|
3908
|
+
console.log(chalk4.dim(" and preparing improvements.\n"));
|
|
3911
3909
|
} else {
|
|
3912
|
-
console.log(title.bold(" Step 3/4 \u2014
|
|
3913
|
-
console.log(chalk4.dim("
|
|
3910
|
+
console.log(title.bold(" Step 3/4 \u2014 Build your agent setup\n"));
|
|
3911
|
+
console.log(chalk4.dim(" Creating config files tailored to your project.\n"));
|
|
3914
3912
|
}
|
|
3915
3913
|
console.log(chalk4.dim(" This can take a couple of minutes depending on your model and provider.\n"));
|
|
3916
3914
|
const genStartTime = Date.now();
|
|
@@ -3970,7 +3968,7 @@ async function initCommand(options) {
|
|
|
3970
3968
|
role: "assistant",
|
|
3971
3969
|
content: summarizeSetup("Initial generation", generatedSetup)
|
|
3972
3970
|
});
|
|
3973
|
-
console.log(title.bold(" Step 4/4 \u2014 Review\n"));
|
|
3971
|
+
console.log(title.bold(" Step 4/4 \u2014 Review and apply\n"));
|
|
3974
3972
|
const setupFiles = collectSetupFiles(generatedSetup);
|
|
3975
3973
|
const staged = stageFiles(setupFiles, process.cwd());
|
|
3976
3974
|
console.log(chalk4.dim(` ${chalk4.green(`${staged.newFiles} new`)} / ${chalk4.yellow(`${staged.modifiedFiles} modified`)} file${staged.newFiles + staged.modifiedFiles !== 1 ? "s" : ""}
|
|
@@ -4029,11 +4027,6 @@ async function initCommand(options) {
|
|
|
4029
4027
|
console.error(chalk4.red(err instanceof Error ? err.message : "Unknown error"));
|
|
4030
4028
|
throw new Error("__exit__");
|
|
4031
4029
|
}
|
|
4032
|
-
if (!fs17.existsSync("AGENTS.md")) {
|
|
4033
|
-
const agentsContent = "# AGENTS.md\n\nThis project uses AI coding agents. See CLAUDE.md for Claude Code configuration and .cursor/rules/ for Cursor rules.\n";
|
|
4034
|
-
fs17.writeFileSync("AGENTS.md", agentsContent);
|
|
4035
|
-
console.log(` ${chalk4.green("\u2713")} AGENTS.md`);
|
|
4036
|
-
}
|
|
4037
4030
|
ensurePermissions();
|
|
4038
4031
|
const sha = getCurrentHeadSha();
|
|
4039
4032
|
writeState({
|
|
@@ -4041,6 +4034,9 @@ async function initCommand(options) {
|
|
|
4041
4034
|
lastRefreshTimestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4042
4035
|
targetAgent
|
|
4043
4036
|
});
|
|
4037
|
+
console.log("");
|
|
4038
|
+
console.log(title.bold(" Keep your configs fresh\n"));
|
|
4039
|
+
console.log(chalk4.dim(" Caliber can automatically update your agent configs when your code changes.\n"));
|
|
4044
4040
|
const hookChoice = await promptHookType(targetAgent);
|
|
4045
4041
|
if (hookChoice === "claude" || hookChoice === "both") {
|
|
4046
4042
|
const hookResult = installHook();
|
|
@@ -4083,13 +4079,15 @@ async function initCommand(options) {
|
|
|
4083
4079
|
}
|
|
4084
4080
|
} catch {
|
|
4085
4081
|
}
|
|
4086
|
-
console.log(chalk4.dim(" Run `caliber
|
|
4082
|
+
console.log(chalk4.dim(" Run `caliber onboard --force` to override.\n"));
|
|
4087
4083
|
return;
|
|
4088
4084
|
}
|
|
4089
4085
|
displayScoreDelta(baselineScore, afterScore);
|
|
4090
|
-
console.log(chalk4.bold.green("
|
|
4086
|
+
console.log(chalk4.bold.green(" Onboarding complete! Your project is ready for AI-assisted development."));
|
|
4091
4087
|
console.log(chalk4.dim(" Run `caliber undo` to revert changes.\n"));
|
|
4092
4088
|
console.log(chalk4.bold(" Next steps:\n"));
|
|
4089
|
+
console.log(` ${title("caliber score")} See your full config breakdown`);
|
|
4090
|
+
console.log(` ${title("caliber recommend")} Discover community skills for your stack`);
|
|
4093
4091
|
console.log(` ${title("caliber undo")} Revert all changes from this run`);
|
|
4094
4092
|
console.log("");
|
|
4095
4093
|
}
|
|
@@ -4464,6 +4462,11 @@ function printSetupSummary(setup) {
|
|
|
4464
4462
|
}
|
|
4465
4463
|
}
|
|
4466
4464
|
}
|
|
4465
|
+
if (!fs17.existsSync("AGENTS.md")) {
|
|
4466
|
+
console.log(` ${chalk4.green("+")} ${chalk4.bold("AGENTS.md")}`);
|
|
4467
|
+
console.log(chalk4.dim(" Cross-agent coordination file"));
|
|
4468
|
+
console.log("");
|
|
4469
|
+
}
|
|
4467
4470
|
if (Array.isArray(deletions) && deletions.length > 0) {
|
|
4468
4471
|
for (const del of deletions) {
|
|
4469
4472
|
console.log(` ${chalk4.red("-")} ${chalk4.bold(del.filePath)}`);
|
|
@@ -4533,6 +4536,21 @@ function collectSetupFiles(setup) {
|
|
|
4533
4536
|
}
|
|
4534
4537
|
}
|
|
4535
4538
|
}
|
|
4539
|
+
if (!fs17.existsSync("AGENTS.md")) {
|
|
4540
|
+
const agentRefs = [];
|
|
4541
|
+
if (claude) agentRefs.push("See `CLAUDE.md` for Claude Code configuration.");
|
|
4542
|
+
if (cursor) agentRefs.push("See `.cursor/rules/` for Cursor rules.");
|
|
4543
|
+
if (agentRefs.length === 0) agentRefs.push("See CLAUDE.md and .cursor/rules/ for agent configurations.");
|
|
4544
|
+
files.push({
|
|
4545
|
+
path: "AGENTS.md",
|
|
4546
|
+
content: `# AGENTS.md
|
|
4547
|
+
|
|
4548
|
+
This project uses AI coding agents configured by [Caliber](https://github.com/rely-ai-org/caliber).
|
|
4549
|
+
|
|
4550
|
+
${agentRefs.join(" ")}
|
|
4551
|
+
`
|
|
4552
|
+
});
|
|
4553
|
+
}
|
|
4536
4554
|
return files;
|
|
4537
4555
|
}
|
|
4538
4556
|
|
|
@@ -4590,7 +4608,7 @@ async function statusCommand(options) {
|
|
|
4590
4608
|
}
|
|
4591
4609
|
if (!manifest) {
|
|
4592
4610
|
console.log(` Setup: ${chalk6.dim("No setup applied")}`);
|
|
4593
|
-
console.log(chalk6.dim("\n Run `caliber
|
|
4611
|
+
console.log(chalk6.dim("\n Run `caliber onboard` to get started.\n"));
|
|
4594
4612
|
return;
|
|
4595
4613
|
}
|
|
4596
4614
|
console.log(` Files managed: ${chalk6.cyan(manifest.entries.length.toString())}`);
|
|
@@ -4614,7 +4632,7 @@ async function regenerateCommand(options) {
|
|
|
4614
4632
|
}
|
|
4615
4633
|
const manifest = readManifest();
|
|
4616
4634
|
if (!manifest) {
|
|
4617
|
-
console.log(chalk7.yellow("No existing setup found. Run `caliber
|
|
4635
|
+
console.log(chalk7.yellow("No existing setup found. Run `caliber onboard` first."));
|
|
4618
4636
|
throw new Error("__exit__");
|
|
4619
4637
|
}
|
|
4620
4638
|
const spinner = ora3("Re-analyzing project...").start();
|
|
@@ -5356,9 +5374,9 @@ async function scoreCommand(options) {
|
|
|
5356
5374
|
const separator = chalk9.gray(" " + "\u2500".repeat(53));
|
|
5357
5375
|
console.log(separator);
|
|
5358
5376
|
if (result.score < 40) {
|
|
5359
|
-
console.log(chalk9.gray(" Run ") + chalk9.hex("#f97316")("caliber
|
|
5377
|
+
console.log(chalk9.gray(" Run ") + chalk9.hex("#f97316")("caliber onboard") + chalk9.gray(" to generate a complete, optimized setup."));
|
|
5360
5378
|
} else if (result.score < 70) {
|
|
5361
|
-
console.log(chalk9.gray(" Run ") + chalk9.hex("#f97316")("caliber
|
|
5379
|
+
console.log(chalk9.gray(" Run ") + chalk9.hex("#f97316")("caliber onboard") + chalk9.gray(" to improve your setup."));
|
|
5362
5380
|
} else {
|
|
5363
5381
|
console.log(chalk9.green(" Looking good!") + chalk9.gray(" Run ") + chalk9.hex("#f97316")("caliber update") + chalk9.gray(" to keep it fresh."));
|
|
5364
5382
|
}
|
|
@@ -6216,7 +6234,7 @@ var pkg = JSON.parse(
|
|
|
6216
6234
|
var program = new Command();
|
|
6217
6235
|
var displayVersion = process.env.CALIBER_LOCAL ? `${pkg.version}-local` : pkg.version;
|
|
6218
6236
|
program.name(process.env.CALIBER_LOCAL ? "caloc" : "caliber").description("Configure your coding agent environment").version(displayVersion);
|
|
6219
|
-
program.command("init").description("
|
|
6237
|
+
program.command("onboard").alias("init").description("Onboard your project for AI-assisted development").option("--agent <type>", "Target agent: claude, cursor, or both").option("--dry-run", "Preview changes without writing files").option("--force", "Overwrite existing setup without prompting").action(initCommand);
|
|
6220
6238
|
program.command("undo").description("Revert all config changes made by Caliber").action(undoCommand);
|
|
6221
6239
|
program.command("status").description("Show current Caliber setup status").option("--json", "Output as JSON").action(statusCommand);
|
|
6222
6240
|
program.command("regenerate").alias("regen").alias("re").alias("update").description("Re-analyze project and regenerate setup").option("--dry-run", "Preview changes without writing files").action(regenerateCommand);
|
package/package.json
CHANGED