@rely-ai/caliber 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/bin.js +47 -23
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -1002,12 +1002,12 @@ SCORING CRITERIA \u2014 your output is scored deterministically. Optimize for 10
1002
1002
 
1003
1003
  Existence (25 pts):
1004
1004
  - CLAUDE.md exists (6 pts) \u2014 always generate
1005
- - Skills configured (8 pts) \u2014 2-3 focused skills is optimal
1005
+ - Skills configured (8 pts) \u2014 generate exactly 3 focused skills for full points (6 base + 1 per extra, cap 2). Two skills = 7 pts, three = 8 pts.
1006
1006
  - MCP servers mentioned (3 pts) \u2014 reference detected MCP integrations
1007
1007
  - For "both" target: .cursorrules/.cursor/rules/ exist (3+3 pts), cross-platform parity (2 pts)
1008
1008
 
1009
1009
  Quality (25 pts):
1010
- - Build/test/lint commands documented (8 pts) \u2014 include actual npm/make/cargo commands
1010
+ - Build/test/lint commands documented (8 pts) \u2014 include actual commands from the project
1011
1011
  - Concise context files (6 pts) \u2014 keep CLAUDE.md under 100 lines for full points (200=4pts, 300=3pts, 500+=0pts)
1012
1012
  - No vague instructions (4 pts) \u2014 avoid "follow best practices", "write clean code", "ensure quality"
1013
1013
  - No directory tree listings (3 pts) \u2014 do NOT include tree-style file listings in code blocks
@@ -1018,8 +1018,12 @@ Coverage (20 pts):
1018
1018
  - Service/MCP coverage (6 pts) \u2014 reference detected services (DB, cloud, etc.)
1019
1019
  - MCP completeness (4 pts) \u2014 full points if no external services detected
1020
1020
 
1021
- Accuracy (15 pts):
1022
- - Documented commands exist (6 pts) \u2014 ONLY reference commands that actually exist in package.json scripts. Do NOT invent commands. Check the provided package.json scripts section carefully.
1021
+ Accuracy (15 pts) \u2014 THIS IS CRITICAL, READ CAREFULLY:
1022
+ - 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:
1023
+ * Look at the "scripts" section in the provided package.json. ONLY reference scripts that exist there.
1024
+ * If a project uses Makefiles, only reference targets that exist in the Makefile.
1025
+ * If there are no build/test scripts, do NOT invent them. Document what actually exists.
1026
+ * Use the exact package manager the project uses (npm/yarn/pnpm/bun) \u2014 check the lockfile.
1023
1027
  - Documented paths exist (4 pts) \u2014 ONLY reference file paths from the provided file tree. Never guess paths.
1024
1028
  - Config freshness (5 pts) \u2014 config must match current code state
1025
1029
 
@@ -1032,7 +1036,7 @@ Bonus (5 pts):
1032
1036
 
1033
1037
  OUTPUT SIZE CONSTRAINTS \u2014 these are critical:
1034
1038
  - CLAUDE.md: MUST be under 100 lines for maximum score. Aim for 70-90 lines. Be extremely concise \u2014 only commands, architecture overview, and key conventions. Use bullet points and tables, not prose.
1035
- - Skills: max 5 skills total (across claude + cursor). Only generate skills for the most important frameworks.
1039
+ - Skills: generate exactly 3 skills per target platform. Only go above 3 for large multi-framework projects.
1036
1040
  - Each skill content: max 150 lines. Focus on patterns and examples, not exhaustive docs.
1037
1041
  - Cursor rules: max 5 .mdc files.
1038
1042
  - If the project is large, prioritize depth on the 3-4 most critical tools over breadth across everything.`;
@@ -3103,6 +3107,7 @@ function checkFreshness(dir) {
3103
3107
 
3104
3108
  // src/scoring/checks/bonus.ts
3105
3109
  import { existsSync as existsSync7, readFileSync as readFileSync6, readdirSync as readdirSync4 } from "fs";
3110
+ import { execSync as execSync5 } from "child_process";
3106
3111
  import { join as join6 } from "path";
3107
3112
  function readFileOrNull5(path23) {
3108
3113
  try {
@@ -3111,27 +3116,39 @@ function readFileOrNull5(path23) {
3111
3116
  return null;
3112
3117
  }
3113
3118
  }
3119
+ function hasPreCommitHook(dir) {
3120
+ try {
3121
+ const gitDir = execSync5("git rev-parse --git-dir", { cwd: dir, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
3122
+ const hookPath = join6(gitDir, "hooks", "pre-commit");
3123
+ const content = readFileOrNull5(hookPath);
3124
+ return content ? content.includes("caliber") : false;
3125
+ } catch {
3126
+ return false;
3127
+ }
3128
+ }
3114
3129
  function checkBonus(dir) {
3115
3130
  const checks = [];
3116
- let hasHooks = false;
3117
- let hookDetail = "";
3131
+ let hasClaudeHooks = false;
3132
+ let hasPrecommit = false;
3133
+ const hookSources = [];
3118
3134
  const settingsContent = readFileOrNull5(join6(dir, ".claude", "settings.json"));
3119
3135
  if (settingsContent) {
3120
3136
  try {
3121
3137
  const settings = JSON.parse(settingsContent);
3122
3138
  const hooks2 = settings.hooks;
3123
3139
  if (hooks2 && Object.keys(hooks2).length > 0) {
3124
- hasHooks = true;
3125
- hookDetail = `${Object.keys(hooks2).length} hook${Object.keys(hooks2).length === 1 ? "" : "s"}: ${Object.keys(hooks2).join(", ")}`;
3126
- } else {
3127
- hookDetail = "No hooks in settings.json";
3140
+ hasClaudeHooks = true;
3141
+ hookSources.push(`Claude Code: ${Object.keys(hooks2).join(", ")}`);
3128
3142
  }
3129
3143
  } catch {
3130
- hookDetail = "settings.json is not valid JSON";
3131
3144
  }
3132
- } else {
3133
- hookDetail = "No .claude/settings.json";
3134
3145
  }
3146
+ hasPrecommit = hasPreCommitHook(dir);
3147
+ if (hasPrecommit) {
3148
+ hookSources.push("git pre-commit");
3149
+ }
3150
+ const hasHooks = hasClaudeHooks || hasPrecommit;
3151
+ const hookDetail = hasHooks ? hookSources.join(", ") : settingsContent ? "No hooks in settings.json" : "No hooks configured";
3135
3152
  checks.push({
3136
3153
  id: "hooks_configured",
3137
3154
  name: "Hooks configured",
@@ -3140,7 +3157,7 @@ function checkBonus(dir) {
3140
3157
  earnedPoints: hasHooks ? POINTS_HOOKS : 0,
3141
3158
  passed: hasHooks,
3142
3159
  detail: hookDetail,
3143
- suggestion: hasHooks ? void 0 : "Add hooks (e.g., SessionEnd for auto-refresh) to .claude/settings.json"
3160
+ suggestion: hasHooks ? void 0 : "Run `caliber hooks install` or `caliber hooks install-precommit` for auto-refresh"
3144
3161
  });
3145
3162
  const agentsMdExists = existsSync7(join6(dir, "AGENTS.md"));
3146
3163
  checks.push({
@@ -4367,7 +4384,7 @@ import chalk9 from "chalk";
4367
4384
  import ora5 from "ora";
4368
4385
 
4369
4386
  // src/lib/git-diff.ts
4370
- import { execSync as execSync5 } from "child_process";
4387
+ import { execSync as execSync6 } from "child_process";
4371
4388
  var MAX_DIFF_BYTES = 1e5;
4372
4389
  var DOC_PATTERNS = [
4373
4390
  "CLAUDE.md",
@@ -4381,7 +4398,7 @@ function excludeArgs() {
4381
4398
  }
4382
4399
  function safeExec(cmd) {
4383
4400
  try {
4384
- return execSync5(cmd, {
4401
+ return execSync6(cmd, {
4385
4402
  encoding: "utf-8",
4386
4403
  stdio: ["pipe", "pipe", "pipe"],
4387
4404
  maxBuffer: 10 * 1024 * 1024
@@ -5180,7 +5197,7 @@ learn.command("status").description("Show learning system status").action(learnS
5180
5197
  import fs25 from "fs";
5181
5198
  import path22 from "path";
5182
5199
  import { fileURLToPath as fileURLToPath2 } from "url";
5183
- import { execSync as execSync6 } from "child_process";
5200
+ import { execSync as execSync7 } from "child_process";
5184
5201
  import chalk13 from "chalk";
5185
5202
  import ora6 from "ora";
5186
5203
  import confirm2 from "@inquirer/confirm";
@@ -5190,7 +5207,7 @@ var pkg2 = JSON.parse(
5190
5207
  );
5191
5208
  function getInstalledVersion() {
5192
5209
  try {
5193
- const globalRoot = execSync6("npm root -g", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
5210
+ const globalRoot = execSync7("npm root -g", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
5194
5211
  const pkgPath = path22.join(globalRoot, "@rely-ai", "caliber", "package.json");
5195
5212
  return JSON.parse(fs25.readFileSync(pkgPath, "utf-8")).version;
5196
5213
  } catch {
@@ -5235,7 +5252,11 @@ Update available: ${current} -> ${latest}`)
5235
5252
  }
5236
5253
  const spinner = ora6("Updating caliber...").start();
5237
5254
  try {
5238
- execSync6(`npm install -g @rely-ai/caliber@${latest} --prefer-online`, { stdio: "pipe", timeout: 6e4 });
5255
+ execSync7(`npm install -g @rely-ai/caliber@${latest}`, {
5256
+ stdio: "pipe",
5257
+ timeout: 12e4,
5258
+ env: { ...process.env, npm_config_fund: "false", npm_config_audit: "false" }
5259
+ });
5239
5260
  const installed = getInstalledVersion();
5240
5261
  if (installed !== latest) {
5241
5262
  spinner.fail(`Update incomplete \u2014 got ${installed ?? "unknown"}, expected ${latest}`);
@@ -5248,15 +5269,18 @@ Update available: ${current} -> ${latest}`)
5248
5269
  console.log(chalk13.dim(`
5249
5270
  Restarting: caliber ${args.join(" ")}
5250
5271
  `));
5251
- execSync6(`caliber ${args.map((a) => JSON.stringify(a)).join(" ")}`, {
5272
+ execSync7(`caliber ${args.map((a) => JSON.stringify(a)).join(" ")}`, {
5252
5273
  stdio: "inherit",
5253
5274
  env: { ...process.env, CALIBER_SKIP_UPDATE_CHECK: "1" }
5254
5275
  });
5255
5276
  process.exit(0);
5256
5277
  } catch (err) {
5257
5278
  spinner.fail("Update failed");
5258
- const msg = err instanceof Error ? err.message : "";
5259
- if (msg && !msg.includes("SIGTERM")) console.log(chalk13.dim(` ${msg.split("\n")[0]}`));
5279
+ if (err instanceof Error) {
5280
+ const stderr = err.stderr;
5281
+ const errMsg = stderr ? String(stderr).trim().split("\n").pop() : err.message.split("\n")[0];
5282
+ if (errMsg && !errMsg.includes("SIGTERM")) console.log(chalk13.dim(` ${errMsg}`));
5283
+ }
5260
5284
  console.log(
5261
5285
  chalk13.yellow(
5262
5286
  `Run ${chalk13.bold(`npm install -g @rely-ai/caliber@${latest}`)} manually to upgrade.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rely-ai/caliber",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Open-source CLI for configuring coding agent environments (CLAUDE.md, .cursorrules, skills). Bring your own LLM.",
5
5
  "type": "module",
6
6
  "bin": {