@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.
- package/dist/bin.js +47 -23
- 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
|
|
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
|
|
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
|
|
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:
|
|
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
|
|
3117
|
-
let
|
|
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
|
-
|
|
3125
|
-
|
|
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 : "
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
5259
|
-
|
|
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