edsger 0.79.2 → 0.81.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 +2 -2
- package/dist/index.js +74 -35
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -125,8 +125,8 @@ standards. Open Claude Code and run `/benchmark`, `/pr-review`, or `/pr-resolve`
|
|
|
125
125
|
| `--standard <path>` | custom standards dir or file |
|
|
126
126
|
| `--assets <path>` | override the entire assets root |
|
|
127
127
|
| `--lang <id>` | force a language, skipping detection |
|
|
128
|
-
| `--max-turns <n>` |
|
|
129
|
-
| `--timeout <minutes>` | hard wall-clock limit per agent run (default
|
|
128
|
+
| `--max-turns <n>` | cap on agentic turns (default: unlimited) |
|
|
129
|
+
| `--timeout <minutes>` | hard wall-clock limit per agent run (default: no limit) |
|
|
130
130
|
| `--json` | machine-readable JSON on stdout |
|
|
131
131
|
| `--dry-run` | run the agent but make no persistent/external changes |
|
|
132
132
|
| `-v, --verbose` | verbose logging |
|
package/dist/index.js
CHANGED
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
import { readFileSync as readFileSync3 } from "fs";
|
|
5
5
|
import { resolve as resolve2 } from "path";
|
|
6
6
|
import { Command, Option } from "commander";
|
|
7
|
-
import
|
|
7
|
+
import pc7 from "picocolors";
|
|
8
8
|
|
|
9
9
|
// src/commands/benchmark.ts
|
|
10
10
|
import { mkdirSync, writeFileSync } from "fs";
|
|
11
11
|
import { basename, join as join3 } from "path";
|
|
12
|
-
import
|
|
12
|
+
import pc3 from "picocolors";
|
|
13
13
|
|
|
14
14
|
// src/core/assets.ts
|
|
15
15
|
import { execFileSync } from "child_process";
|
|
@@ -366,6 +366,7 @@ import {
|
|
|
366
366
|
query,
|
|
367
367
|
tool
|
|
368
368
|
} from "@anthropic-ai/claude-agent-sdk";
|
|
369
|
+
import pc2 from "picocolors";
|
|
369
370
|
var READ_ONLY_DISALLOWED = ["Edit", "Write", "NotebookEdit"];
|
|
370
371
|
async function runAgent(opts) {
|
|
371
372
|
let captured;
|
|
@@ -405,7 +406,9 @@ async function runAgent(opts) {
|
|
|
405
406
|
options: {
|
|
406
407
|
model: opts.model,
|
|
407
408
|
cwd: opts.cwd,
|
|
408
|
-
|
|
409
|
+
// Only impose a turn cap when the user explicitly set one; otherwise let the
|
|
410
|
+
// agent run to completion (no max-turns stop).
|
|
411
|
+
...opts.maxTurns ? { maxTurns: opts.maxTurns } : {},
|
|
409
412
|
// Reproducible runs: do not load the target repo's settings/CLAUDE.md.
|
|
410
413
|
settingSources: [],
|
|
411
414
|
systemPrompt: {
|
|
@@ -423,14 +426,19 @@ async function runAgent(opts) {
|
|
|
423
426
|
abortController: controller
|
|
424
427
|
}
|
|
425
428
|
});
|
|
429
|
+
let turn = 0;
|
|
426
430
|
try {
|
|
427
431
|
for await (const message of stream) {
|
|
428
432
|
if (message.type === "assistant") {
|
|
433
|
+
turn += 1;
|
|
429
434
|
for (const block of message.message?.content ?? []) {
|
|
430
435
|
if (block.type === "tool_use") {
|
|
431
|
-
|
|
436
|
+
const counter = opts.maxTurns ? `${turn}/${opts.maxTurns}` : `${turn}`;
|
|
437
|
+
log.step(`[${counter}] ${summarizeTool(block.name, block.input)}`);
|
|
432
438
|
} else if (block.type === "text" && opts.verbose && block.text?.trim()) {
|
|
433
|
-
|
|
439
|
+
for (const line of block.text.trim().split("\n").slice(0, 4)) {
|
|
440
|
+
if (line.trim()) log.debug(line.trim());
|
|
441
|
+
}
|
|
434
442
|
}
|
|
435
443
|
}
|
|
436
444
|
} else if (message.type === "result") {
|
|
@@ -451,6 +459,36 @@ async function runAgent(opts) {
|
|
|
451
459
|
}
|
|
452
460
|
return { result: captured, costUsd, numTurns };
|
|
453
461
|
}
|
|
462
|
+
function summarizeTool(name = "tool", input = {}) {
|
|
463
|
+
const str = (v) => typeof v === "string" ? v : "";
|
|
464
|
+
const oneLine = (v, max = 80) => {
|
|
465
|
+
const s = v.replace(/\s+/g, " ").trim();
|
|
466
|
+
return s.length > max ? s.slice(0, max - 1) + "\u2026" : s;
|
|
467
|
+
};
|
|
468
|
+
const base = (p) => p.split("/").filter(Boolean).pop() ?? p;
|
|
469
|
+
switch (name) {
|
|
470
|
+
case "Read":
|
|
471
|
+
case "Edit":
|
|
472
|
+
case "Write":
|
|
473
|
+
case "MultiEdit":
|
|
474
|
+
case "NotebookEdit":
|
|
475
|
+
return `${name} ${base(str(input.file_path))}`;
|
|
476
|
+
case "Bash": {
|
|
477
|
+
const cmd = oneLine(str(input.command));
|
|
478
|
+
return `Bash ${cmd ? pc2.dim(`$ ${cmd}`) : ""}`.trimEnd();
|
|
479
|
+
}
|
|
480
|
+
case "Grep": {
|
|
481
|
+
const where = str(input.path) || str(input.glob);
|
|
482
|
+
return `Grep /${oneLine(str(input.pattern), 40)}/${where ? ` in ${base(where)}` : ""}`;
|
|
483
|
+
}
|
|
484
|
+
case "Glob":
|
|
485
|
+
return `Glob ${oneLine(str(input.pattern), 60)}`;
|
|
486
|
+
case "mcp__edsger_out__submit_result":
|
|
487
|
+
return "recording result";
|
|
488
|
+
default:
|
|
489
|
+
return name;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
454
492
|
|
|
455
493
|
// src/core/report.ts
|
|
456
494
|
function scoreBenchmark(standard, result) {
|
|
@@ -642,7 +680,7 @@ async function runBenchmark(opts) {
|
|
|
642
680
|
const resolved = resolveStandard("benchmark", opts, config, configDir);
|
|
643
681
|
const standard = resolved.standard;
|
|
644
682
|
log.info(
|
|
645
|
-
`Benchmarking ${
|
|
683
|
+
`Benchmarking ${pc3.bold(basename(opts.cwd))} against ${pc3.bold(standard.name)} (languages: ${resolved.languages.join(", ") || "generic"})`
|
|
646
684
|
);
|
|
647
685
|
log.debug(`standard layers: ${resolved.layers.join(" \u2192 ")}`);
|
|
648
686
|
const prompt = buildPrompt(standard, opts.cwd);
|
|
@@ -701,7 +739,7 @@ async function runBenchmark(opts) {
|
|
|
701
739
|
writeFileSync(join3(baseDir, "report.md"), mdOut, "utf8");
|
|
702
740
|
writeFileSync(join3(baseDir, "report.json"), jsonOut, "utf8");
|
|
703
741
|
log.success(
|
|
704
|
-
`Report written to ${
|
|
742
|
+
`Report written to ${pc3.bold(join3(opts.out, "report.md"))} ${pc3.dim(`(run archived at ${join3(opts.out, "runs", runId)})`)}`
|
|
705
743
|
);
|
|
706
744
|
}
|
|
707
745
|
printSummary(scored, numTurns, costUsd);
|
|
@@ -720,8 +758,8 @@ function printSummary(scored, numTurns, costUsd) {
|
|
|
720
758
|
function bar(pct) {
|
|
721
759
|
const width = 20;
|
|
722
760
|
const filled = Math.round(pct / 100 * width);
|
|
723
|
-
const color = pct >= 80 ?
|
|
724
|
-
return color("\u2588".repeat(filled)) +
|
|
761
|
+
const color = pct >= 80 ? pc3.green : pct >= 60 ? pc3.yellow : pc3.red;
|
|
762
|
+
return color("\u2588".repeat(filled)) + pc3.dim("\u2591".repeat(width - filled));
|
|
725
763
|
}
|
|
726
764
|
function buildPrompt(standard, cwd) {
|
|
727
765
|
const rubric = standard.categories.map((cat) => {
|
|
@@ -756,7 +794,7 @@ ${crits}`;
|
|
|
756
794
|
}
|
|
757
795
|
|
|
758
796
|
// src/commands/pr-review.ts
|
|
759
|
-
import
|
|
797
|
+
import pc4 from "picocolors";
|
|
760
798
|
|
|
761
799
|
// src/core/gh.ts
|
|
762
800
|
import { execFile } from "child_process";
|
|
@@ -875,7 +913,7 @@ var SEVERITY_RANK = {
|
|
|
875
913
|
};
|
|
876
914
|
async function runPrReview(opts) {
|
|
877
915
|
await ensureGhReady();
|
|
878
|
-
log.info(`Fetching PR ${
|
|
916
|
+
log.info(`Fetching PR ${pc4.bold(opts.pr)}${opts.repo ? ` from ${opts.repo}` : ""}`);
|
|
879
917
|
const ctx = await getPrContext(opts.pr, opts.repo, opts.cwd);
|
|
880
918
|
const { config, path: configPath } = loadConfig(opts.cwd);
|
|
881
919
|
const configDir = configPath ? `${configPath}/..` : opts.cwd;
|
|
@@ -886,7 +924,7 @@ async function runPrReview(opts) {
|
|
|
886
924
|
const resolved = resolveStandard("review", opts, config, configDir, fileHint);
|
|
887
925
|
const standard = resolved.standard;
|
|
888
926
|
log.info(
|
|
889
|
-
`Reviewing "${
|
|
927
|
+
`Reviewing "${pc4.bold(ctx.title)}" (#${ctx.number}, ${ctx.files.length} files) against ${pc4.bold(standard.name)}`
|
|
890
928
|
);
|
|
891
929
|
const { result, costUsd, numTurns } = await runAgent({
|
|
892
930
|
prompt: buildPrompt2(standard, ctx),
|
|
@@ -920,7 +958,7 @@ async function runPrReview(opts) {
|
|
|
920
958
|
await postReview(ctx, opts.repo, event, body, inline, opts.cwd);
|
|
921
959
|
log.success(`Posted review (${event}) to ${ctx.url}`);
|
|
922
960
|
} else {
|
|
923
|
-
log.warn(`Preview only. Re-run with ${
|
|
961
|
+
log.warn(`Preview only. Re-run with ${pc4.bold("--post")} to submit this review to GitHub.`);
|
|
924
962
|
process.stderr.write("\n" + body + "\n");
|
|
925
963
|
}
|
|
926
964
|
return 0;
|
|
@@ -996,9 +1034,9 @@ function countBySeverity(findings) {
|
|
|
996
1034
|
return c;
|
|
997
1035
|
}
|
|
998
1036
|
function sevColor(s) {
|
|
999
|
-
if (s === "critical" || s === "high") return
|
|
1000
|
-
if (s === "medium") return
|
|
1001
|
-
return
|
|
1037
|
+
if (s === "critical" || s === "high") return pc4.red;
|
|
1038
|
+
if (s === "medium") return pc4.yellow;
|
|
1039
|
+
return pc4.dim;
|
|
1002
1040
|
}
|
|
1003
1041
|
function verdictLabel(v) {
|
|
1004
1042
|
return v === "approve" ? "Approve" : v === "request_changes" ? "Request changes" : "Comment";
|
|
@@ -1050,11 +1088,11 @@ function truncate(s, max) {
|
|
|
1050
1088
|
// src/commands/pr-resolve.ts
|
|
1051
1089
|
import { execFile as execFile2 } from "child_process";
|
|
1052
1090
|
import { promisify as promisify2 } from "util";
|
|
1053
|
-
import
|
|
1091
|
+
import pc5 from "picocolors";
|
|
1054
1092
|
var exec2 = promisify2(execFile2);
|
|
1055
1093
|
async function runPrResolve(opts) {
|
|
1056
1094
|
await ensureGhReady();
|
|
1057
|
-
log.info(`Fetching PR ${
|
|
1095
|
+
log.info(`Fetching PR ${pc5.bold(opts.pr)}${opts.repo ? ` from ${opts.repo}` : ""}`);
|
|
1058
1096
|
const ctx = await getPrContext(opts.pr, opts.repo, opts.cwd);
|
|
1059
1097
|
const feedback = await getPrFeedback(ctx, opts.repo, opts.cwd).catch(() => ({
|
|
1060
1098
|
reviewComments: [],
|
|
@@ -1065,14 +1103,14 @@ async function runPrResolve(opts) {
|
|
|
1065
1103
|
await checkoutPr(opts.pr, opts.repo, opts.cwd);
|
|
1066
1104
|
}
|
|
1067
1105
|
log.info(
|
|
1068
|
-
`Resolving "${
|
|
1106
|
+
`Resolving "${pc5.bold(ctx.title)}" (#${ctx.number}) \u2014 ${feedback.reviewComments.length} review comments`
|
|
1069
1107
|
);
|
|
1070
1108
|
const { result, costUsd, numTurns } = await runAgent({
|
|
1071
1109
|
prompt: buildPrompt3(ctx, feedback, opts.instruction),
|
|
1072
1110
|
cwd: opts.cwd,
|
|
1073
1111
|
model: opts.model,
|
|
1074
|
-
maxTurns:
|
|
1075
|
-
timeoutMs:
|
|
1112
|
+
maxTurns: opts.maxTurns,
|
|
1113
|
+
timeoutMs: opts.timeoutMs,
|
|
1076
1114
|
allowWrite: true,
|
|
1077
1115
|
verbose: opts.verbose,
|
|
1078
1116
|
resultShape: ResolveResultSchema.shape,
|
|
@@ -1090,7 +1128,7 @@ async function runPrResolve(opts) {
|
|
|
1090
1128
|
else log.warn("Nothing to commit \u2014 working tree is clean.");
|
|
1091
1129
|
} else {
|
|
1092
1130
|
log.warn(
|
|
1093
|
-
`Changes left in the working tree. Review them, then commit/push (or re-run with ${
|
|
1131
|
+
`Changes left in the working tree. Review them, then commit/push (or re-run with ${pc5.bold("--push")}).`
|
|
1094
1132
|
);
|
|
1095
1133
|
}
|
|
1096
1134
|
return 0;
|
|
@@ -1134,7 +1172,7 @@ function printSummary2(result, numTurns, costUsd) {
|
|
|
1134
1172
|
`);
|
|
1135
1173
|
if (result.changes.length) {
|
|
1136
1174
|
for (const c of result.changes)
|
|
1137
|
-
process.stderr.write(` ${
|
|
1175
|
+
process.stderr.write(` ${pc5.green("~")} ${c.file} \u2014 ${c.description}
|
|
1138
1176
|
`);
|
|
1139
1177
|
}
|
|
1140
1178
|
if (result.testsRun) log.step(`verification: ${result.testsRun}`);
|
|
@@ -1185,7 +1223,7 @@ import {
|
|
|
1185
1223
|
} from "fs";
|
|
1186
1224
|
import { homedir as homedir2 } from "os";
|
|
1187
1225
|
import { join as join5 } from "path";
|
|
1188
|
-
import
|
|
1226
|
+
import pc6 from "picocolors";
|
|
1189
1227
|
var MANAGED = ["benchmark", "pr-review", "pr-resolve"];
|
|
1190
1228
|
function targetSkillsDir(scope) {
|
|
1191
1229
|
return scope.global ? join5(homedir2(), ".claude", "skills") : join5(scope.cwd, ".claude", "skills");
|
|
@@ -1222,7 +1260,7 @@ async function runSkillsInstall(opts) {
|
|
|
1222
1260
|
log.info("Nothing installed.");
|
|
1223
1261
|
return 0;
|
|
1224
1262
|
}
|
|
1225
|
-
log.heading(`Installed ${installed} skill(s) into ${
|
|
1263
|
+
log.heading(`Installed ${installed} skill(s) into ${pc6.bold(dest)}`);
|
|
1226
1264
|
log.step(`scope: ${opts.global ? "user (all projects)" : "this project"}`);
|
|
1227
1265
|
log.step(`standards: ${assetsDir}`);
|
|
1228
1266
|
log.step("Open Claude Code and run /benchmark, /pr-review, or /pr-resolve.");
|
|
@@ -1253,9 +1291,9 @@ async function runSkillsList(opts) {
|
|
|
1253
1291
|
return existsSync3(p) && statSync2(p).isFile();
|
|
1254
1292
|
});
|
|
1255
1293
|
log.heading(`${label}: ${dir}`);
|
|
1256
|
-
if (present.length) for (const n of present) process.stderr.write(` ${
|
|
1294
|
+
if (present.length) for (const n of present) process.stderr.write(` ${pc6.green("\u2713")} /${n}
|
|
1257
1295
|
`);
|
|
1258
|
-
else process.stderr.write(` ${
|
|
1296
|
+
else process.stderr.write(` ${pc6.dim("(none installed)")}
|
|
1259
1297
|
`);
|
|
1260
1298
|
}
|
|
1261
1299
|
return 0;
|
|
@@ -1276,12 +1314,13 @@ function toGlobal(raw) {
|
|
|
1276
1314
|
json: Boolean(raw.json),
|
|
1277
1315
|
verbose: Boolean(raw.verbose),
|
|
1278
1316
|
dryRun: Boolean(raw.dryRun),
|
|
1279
|
-
|
|
1280
|
-
|
|
1317
|
+
// Unlimited by default — only cap turns / wall-clock when explicitly asked.
|
|
1318
|
+
maxTurns: raw.maxTurns ? Number.parseInt(raw.maxTurns, 10) : void 0,
|
|
1319
|
+
timeoutMs: raw.timeout ? Number.parseFloat(raw.timeout) * 6e4 : void 0
|
|
1281
1320
|
};
|
|
1282
1321
|
}
|
|
1283
1322
|
function addGlobalOptions(cmd) {
|
|
1284
|
-
return cmd.option("-C, --cwd <dir>", "directory of the repository to operate on").addOption(new Option("-m, --model <model>", "model id for the agent").default(void 0)).option("--standard <path>", "path to a custom standards dir or file (overrides bundled)").option("--assets <path>", "override the entire assets root").option("--lang <id>", "force a language id, skipping detection").option("--max-turns <n>", "
|
|
1323
|
+
return cmd.option("-C, --cwd <dir>", "directory of the repository to operate on").addOption(new Option("-m, --model <model>", "model id for the agent").default(void 0)).option("--standard <path>", "path to a custom standards dir or file (overrides bundled)").option("--assets <path>", "override the entire assets root").option("--lang <id>", "force a language id, skipping detection").option("--max-turns <n>", "cap on agentic turns (default: unlimited)").option("--timeout <minutes>", "hard wall-clock limit per agent run (default: no limit)").option("--json", "print machine-readable JSON to stdout").option("-v, --verbose", "verbose logging").option("--dry-run", "run the agent but make no persistent/external changes");
|
|
1285
1324
|
}
|
|
1286
1325
|
async function guard(fn) {
|
|
1287
1326
|
try {
|
|
@@ -1353,11 +1392,11 @@ program.addHelpText(
|
|
|
1353
1392
|
"after",
|
|
1354
1393
|
`
|
|
1355
1394
|
Examples:
|
|
1356
|
-
${
|
|
1357
|
-
${
|
|
1358
|
-
${
|
|
1359
|
-
${
|
|
1360
|
-
${
|
|
1395
|
+
${pc7.dim("$")} edsger benchmark
|
|
1396
|
+
${pc7.dim("$")} edsger benchmark -C ./my-repo --json
|
|
1397
|
+
${pc7.dim("$")} edsger pr-review 123 --post
|
|
1398
|
+
${pc7.dim("$")} edsger pr-resolve 123 --instruction "fix the failing test" --push
|
|
1399
|
+
${pc7.dim("$")} edsger skills install ${pc7.dim("# enable /benchmark etc. in Claude Code")}
|
|
1361
1400
|
|
|
1362
1401
|
Auth: the agent uses your Claude Code login (run \`claude\` once to sign in); run \`gh auth login\` for PR commands.
|
|
1363
1402
|
`
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/commands/benchmark.ts","../src/core/assets.ts","../src/core/logger.ts","../src/util/yaml.ts","../src/core/config.ts","../src/core/agent.ts","../src/core/report.ts","../src/core/schema.ts","../src/commands/pr-review.ts","../src/core/gh.ts","../src/commands/pr-resolve.ts","../src/commands/skills.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { Command, Option } from \"commander\";\nimport pc from \"picocolors\";\nimport { runBenchmark } from \"./commands/benchmark.js\";\nimport { runPrReview } from \"./commands/pr-review.js\";\nimport { runPrResolve } from \"./commands/pr-resolve.js\";\nimport { runSkillsInstall, runSkillsList, runSkillsUninstall } from \"./commands/skills.js\";\nimport { log, setVerbose } from \"./core/logger.js\";\nimport type { GlobalOptions } from \"./types.js\";\n\n// Single source of truth: read the version from package.json at runtime.\n// dist/index.js sits one level below the package root, alongside which package.json ships.\nconst pkg = JSON.parse(readFileSync(new URL(\"../package.json\", import.meta.url), \"utf8\")) as {\n version: string;\n};\nconst VERSION = pkg.version;\nconst DEFAULT_MODEL = \"claude-sonnet-4-6\";\n\ninterface RawGlobal {\n cwd?: string;\n model?: string;\n standard?: string;\n assets?: string;\n lang?: string;\n json?: boolean;\n verbose?: boolean;\n dryRun?: boolean;\n maxTurns?: string;\n timeout?: string;\n}\n\nfunction toGlobal(raw: RawGlobal): GlobalOptions {\n setVerbose(Boolean(raw.verbose));\n return {\n cwd: resolve(raw.cwd ?? process.cwd()),\n model: raw.model ?? process.env.EDSGER_MODEL ?? DEFAULT_MODEL,\n standardPath: raw.standard,\n assetsPath: raw.assets,\n lang: raw.lang,\n json: Boolean(raw.json),\n verbose: Boolean(raw.verbose),\n dryRun: Boolean(raw.dryRun),\n maxTurns: raw.maxTurns ? Number.parseInt(raw.maxTurns, 10) : 20,\n timeoutMs: (raw.timeout ? Number.parseFloat(raw.timeout) : 15) * 60_000\n };\n}\n\nfunction addGlobalOptions(cmd: Command): Command {\n return cmd\n .option(\"-C, --cwd <dir>\", \"directory of the repository to operate on\")\n .addOption(new Option(\"-m, --model <model>\", \"model id for the agent\").default(undefined))\n .option(\"--standard <path>\", \"path to a custom standards dir or file (overrides bundled)\")\n .option(\"--assets <path>\", \"override the entire assets root\")\n .option(\"--lang <id>\", \"force a language id, skipping detection\")\n .option(\"--max-turns <n>\", \"max agentic turns\")\n .option(\"--timeout <minutes>\", \"hard wall-clock limit per agent run (default 15)\")\n .option(\"--json\", \"print machine-readable JSON to stdout\")\n .option(\"-v, --verbose\", \"verbose logging\")\n .option(\"--dry-run\", \"run the agent but make no persistent/external changes\");\n}\n\nasync function guard(fn: () => Promise<number>): Promise<void> {\n try {\n const code = await fn();\n process.exitCode = code;\n } catch (err) {\n log.error(err instanceof Error ? err.message : String(err));\n if (process.env.EDSGER_DEBUG && err instanceof Error)\n process.stderr.write((err.stack ?? \"\") + \"\\n\");\n process.exitCode = 1;\n }\n}\n\nconst program = new Command();\nprogram\n .name(\"edsger\")\n .description(\n \"Agentic CLI to benchmark repositories and review/resolve pull requests\\n\" +\n \"against industrial-grade standards (from edsger-assets, fully overridable).\"\n )\n .version(VERSION, \"-V, --version\");\n\naddGlobalOptions(\n program\n .command(\"benchmark\")\n .description(\"Score a repository against a benchmark rubric and write a report\")\n .option(\"--out <dir>\", \"report output directory (relative to repo)\", \".edsger/benchmark\")\n .option(\"--no-write\", \"do not write report files into the repo\")\n).action(async (opts: RawGlobal & { out: string; write: boolean }) => {\n await guard(() =>\n runBenchmark({ ...toGlobal(opts), out: opts.out, noWrite: opts.write === false })\n );\n});\n\naddGlobalOptions(\n program\n .command(\"pr-review\")\n .description(\"Review a pull request against the review standard (requires gh)\")\n .argument(\"<pr>\", \"PR number, URL, or branch\")\n .option(\"--repo <owner/repo>\", \"target repository (defaults to current)\")\n .option(\"--post\", \"submit the review to GitHub (otherwise preview only)\")\n).action(async (pr: string, opts: RawGlobal & { repo?: string; post?: boolean }) => {\n await guard(() =>\n runPrReview({ ...toGlobal(opts), pr, repo: opts.repo, post: Boolean(opts.post) })\n );\n});\n\naddGlobalOptions(\n program\n .command(\"pr-resolve\")\n .description(\"Resolve review feedback / fix a pull request (requires gh)\")\n .argument(\"<pr>\", \"PR number, URL, or branch\")\n .option(\"--repo <owner/repo>\", \"target repository (defaults to current)\")\n .option(\"--instruction <text>\", \"what to do (defaults to addressing review comments)\")\n .option(\"--no-checkout\", \"do not check out the PR branch first\")\n .option(\"--push\", \"commit and push the changes when done\")\n).action(\n async (\n pr: string,\n opts: RawGlobal & { repo?: string; instruction?: string; checkout: boolean; push?: boolean }\n ) => {\n await guard(() =>\n runPrResolve({\n ...toGlobal(opts),\n pr,\n repo: opts.repo,\n instruction: opts.instruction,\n checkout: opts.checkout !== false,\n push: Boolean(opts.push)\n })\n );\n }\n);\n\n// `edsger skills ...` — install the skills into Claude Code with no paths needed.\nconst skills = program\n .command(\"skills\")\n .description(\"install edsger as Claude Code skills (/benchmark, /pr-review, /pr-resolve)\");\n\nskills\n .command(\"install\")\n .description(\"install the skills into Claude Code\")\n .option(\"--global\", \"install for the current user (~/.claude/skills) [default]\")\n .option(\"--project\", \"install into ./.claude/skills instead\")\n .option(\"-C, --cwd <dir>\", \"project directory (with --project)\")\n .option(\"--force\", \"overwrite existing skills\")\n .action(async (opts: { global?: boolean; project?: boolean; cwd?: string; force?: boolean }) => {\n await guard(() =>\n runSkillsInstall({\n cwd: resolve(opts.cwd ?? process.cwd()),\n global: opts.project ? false : true,\n force: Boolean(opts.force)\n })\n );\n });\n\nskills\n .command(\"uninstall\")\n .description(\"remove the edsger skills from Claude Code\")\n .option(\"--global\", \"remove from the user scope (~/.claude/skills) [default]\")\n .option(\"--project\", \"remove from ./.claude/skills instead\")\n .option(\"-C, --cwd <dir>\", \"project directory (with --project)\")\n .action(async (opts: { global?: boolean; project?: boolean; cwd?: string }) => {\n await guard(() =>\n runSkillsUninstall({\n cwd: resolve(opts.cwd ?? process.cwd()),\n global: opts.project ? false : true\n })\n );\n });\n\nskills\n .command(\"list\")\n .description(\"show which edsger skills are installed\")\n .option(\"-C, --cwd <dir>\", \"project directory\")\n .action(async (opts: { cwd?: string }) => {\n await guard(() => runSkillsList({ cwd: resolve(opts.cwd ?? process.cwd()), global: true }));\n });\n\nprogram.addHelpText(\n \"after\",\n `\\nExamples:\\n` +\n ` ${pc.dim(\"$\")} edsger benchmark\\n` +\n ` ${pc.dim(\"$\")} edsger benchmark -C ./my-repo --json\\n` +\n ` ${pc.dim(\"$\")} edsger pr-review 123 --post\\n` +\n ` ${pc.dim(\"$\")} edsger pr-resolve 123 --instruction \"fix the failing test\" --push\\n` +\n ` ${pc.dim(\"$\")} edsger skills install ${pc.dim(\"# enable /benchmark etc. in Claude Code\")}\\n` +\n `\\nAuth: the agent uses your Claude Code login (run \\`claude\\` once to sign in); ` +\n `run \\`gh auth login\\` for PR commands.\\n`\n);\n\nprogram.parseAsync(process.argv);\n","import { mkdirSync, writeFileSync } from \"node:fs\";\nimport { basename, join } from \"node:path\";\nimport pc from \"picocolors\";\nimport { resolveStandard } from \"../core/assets.js\";\nimport { loadConfig } from \"../core/config.js\";\nimport { runAgent } from \"../core/agent.js\";\nimport { log } from \"../core/logger.js\";\nimport { renderBenchmarkMarkdown, scoreBenchmark, type ScoredBenchmark } from \"../core/report.js\";\nimport { BenchmarkResultSchema } from \"../core/schema.js\";\nimport type { BenchmarkStandard, GlobalOptions } from \"../types.js\";\n\nexport interface BenchmarkOptions extends GlobalOptions {\n /** Directory to write the report into (relative to repo). */\n out: string;\n /** Skip writing files into the repo. */\n noWrite: boolean;\n}\n\nexport async function runBenchmark(opts: BenchmarkOptions): Promise<number> {\n const { config, path: configPath } = loadConfig(opts.cwd);\n const configDir = configPath ? join(configPath, \"..\") : opts.cwd;\n const resolved = resolveStandard(\"benchmark\", opts, config, configDir);\n const standard = resolved.standard as BenchmarkStandard;\n\n log.info(\n `Benchmarking ${pc.bold(basename(opts.cwd))} against ${pc.bold(standard.name)} ` +\n `(languages: ${resolved.languages.join(\", \") || \"generic\"})`\n );\n log.debug(`standard layers: ${resolved.layers.join(\" → \")}`);\n\n const prompt = buildPrompt(standard, opts.cwd);\n const { result, costUsd, numTurns } = await runAgent({\n prompt,\n cwd: opts.cwd,\n model: opts.model,\n maxTurns: opts.maxTurns,\n timeoutMs: opts.timeoutMs,\n allowWrite: false,\n verbose: opts.verbose,\n resultShape: BenchmarkResultSchema.shape,\n systemPromptAppend:\n \"You are Edsger, a meticulous staff-level engineer performing an objective \" +\n \"repository assessment. Inspect the actual code and configuration before scoring. \" +\n \"Be evidence-driven and fair; cite concrete files. Do not modify any files.\"\n });\n\n if (!result) {\n log.error(\n \"The agent did not produce a result. Try increasing --max-turns or check credentials.\"\n );\n return 1;\n }\n\n const scored = scoreBenchmark(standard, result);\n const generatedAt = new Date().toISOString();\n // Filesystem-safe UTC run id (e.g. 20260701T034500Z): lexicographic order == chronological.\n const runId = generatedAt.replace(/[-:]/g, \"\").replace(/\\.\\d+Z$/, \"Z\");\n const md = renderBenchmarkMarkdown(scored, {\n repo: basename(opts.cwd),\n languages: resolved.languages,\n layers: resolved.layers,\n generatedAt,\n model: opts.model\n });\n\n const jsonReport = {\n schema: \"edsger.benchmark/1\",\n runId,\n generatedAt,\n model: opts.model,\n repo: basename(opts.cwd),\n languages: resolved.languages,\n standard: { name: standard.name, version: standard.version, layers: resolved.layers },\n overall: scored.overall,\n grade: scored.grade,\n categories: scored.categories,\n summary: scored.summary,\n strengths: scored.strengths,\n weaknesses: scored.weaknesses,\n recommendations: scored.recommendations,\n costUsd\n };\n\n if (!opts.noWrite && !opts.dryRun) {\n const baseDir = join(opts.cwd, opts.out);\n const mdOut = md + \"\\n\";\n const jsonOut = JSON.stringify(jsonReport, null, 2) + \"\\n\";\n\n // Archive this run under runs/<timestamp>/ so history from repeated runs is preserved.\n const runDir = join(baseDir, \"runs\", runId);\n mkdirSync(runDir, { recursive: true });\n writeFileSync(join(runDir, \"report.md\"), mdOut, \"utf8\");\n writeFileSync(join(runDir, \"report.json\"), jsonOut, \"utf8\");\n\n // Always refresh the canonical top-level report as the stable \"latest\" pointer\n // (unchanged path, so CI / diffs keep working).\n writeFileSync(join(baseDir, \"report.md\"), mdOut, \"utf8\");\n writeFileSync(join(baseDir, \"report.json\"), jsonOut, \"utf8\");\n\n log.success(\n `Report written to ${pc.bold(join(opts.out, \"report.md\"))} ` +\n `${pc.dim(`(run archived at ${join(opts.out, \"runs\", runId)})`)}`\n );\n }\n\n printSummary(scored, numTurns, costUsd);\n if (opts.json) process.stdout.write(JSON.stringify(jsonReport, null, 2) + \"\\n\");\n return 0;\n}\n\nfunction printSummary(scored: ScoredBenchmark, numTurns: number, costUsd: number): void {\n log.heading(`Score: ${scored.overall}/100 (Grade ${scored.grade})`);\n for (const c of scored.categories) {\n const pct = Math.round(c.fraction * 100);\n process.stderr.write(` ${bar(pct)} ${String(pct).padStart(3)}% ${c.name}\\n`);\n }\n log.step(`${numTurns} turns · ~$${costUsd.toFixed(3)}`);\n}\n\nfunction bar(pct: number): string {\n const width = 20;\n const filled = Math.round((pct / 100) * width);\n const color = pct >= 80 ? pc.green : pct >= 60 ? pc.yellow : pc.red;\n return color(\"█\".repeat(filled)) + pc.dim(\"░\".repeat(width - filled));\n}\n\nfunction buildPrompt(standard: BenchmarkStandard, cwd: string): string {\n const rubric = standard.categories\n .map((cat) => {\n const crits = cat.criteria\n .map((cr) => {\n const anchors = cr.rubric\n ? Object.entries(cr.rubric)\n .map(([k, v]) => ` - ${k}: ${v}`)\n .join(\"\\n\")\n : \"\";\n return (\n ` - id: ${cat.id}/${cr.id}\\n` +\n ` title: ${cr.title}\\n` +\n ` guidance: ${cr.guidance.trim()}` +\n (anchors ? `\\n anchors:\\n${anchors}` : \"\")\n );\n })\n .join(\"\\n\");\n return `- category: ${cat.id} (${cat.name}, weight ${cat.weight})\\n${crits}`;\n })\n .join(\"\\n\");\n\n return [\n `Assess the repository located at: ${cwd}`,\n ``,\n `Score it against the rubric below. Each criterion is scored from 0 to ${standard.scoreScale}`,\n `(0 = absent/harmful, ${standard.scoreScale} = exemplary), using the level anchors as a guide.`,\n ``,\n `Method:`,\n `1. Explore the repository structure, key source files, configuration, CI, tests, and docs.`,\n ` Use Read/Grep/Glob and read-only Bash (e.g. ls, cat, git log). Do NOT modify anything.`,\n `2. For each criterion, gather concrete evidence (file paths) before deciding a score.`,\n `3. Be objective and consistent. Absence of evidence for a practice means a low score.`,\n `4. When finished, call submit_result exactly once with a score for EVERY criterion id below,`,\n ` grouped by category. Include a short justification and evidence paths for each.`,\n ``,\n `Rubric:`,\n rubric\n ].join(\"\\n\");\n}\n","import { execFileSync } from \"node:child_process\";\nimport { existsSync, readdirSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, isAbsolute, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type {\n BenchmarkStandard,\n Category,\n Criterion,\n FocusArea,\n GlobalOptions,\n ResolvedStandard,\n ReviewStandard,\n Standard,\n StandardKind\n} from \"../types.js\";\nimport { log } from \"./logger.js\";\nimport { loadStructured } from \"../util/yaml.js\";\nimport type { EdsgerConfig } from \"./config.js\";\n\nconst moduleDir = dirname(fileURLToPath(import.meta.url));\n\n/** Walk upward from the running module to find the bundled `assets/` dir. */\nexport function findBundledAssetsDir(): string {\n if (process.env.EDSGER_ASSETS_DIR && existsSync(process.env.EDSGER_ASSETS_DIR)) {\n return process.env.EDSGER_ASSETS_DIR;\n }\n let dir = moduleDir;\n for (let i = 0; i < 8; i++) {\n const candidate = join(dir, \"assets\");\n if (existsSync(join(candidate, \"manifest.yaml\"))) return candidate;\n // Also allow running directly against an edsger-assets checkout layout.\n if (existsSync(join(dir, \"manifest.yaml\")) && existsSync(join(dir, \"benchmark\"))) {\n return dir;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n throw new Error(\"Could not locate bundled assets. Reinstall edsger or set EDSGER_ASSETS_DIR.\");\n}\n\ninterface LanguageDetector {\n id: string;\n markers: string[];\n extensions: string[];\n}\n\ninterface LanguagesConfig {\n minScore: number;\n maxExtensionMatches: number;\n languages: LanguageDetector[];\n}\n\nfunction loadLangConfig(assetsRoot: string): LanguagesConfig | null {\n const cfgPath = join(assetsRoot, \"languages.yaml\");\n if (!existsSync(cfgPath)) return null;\n return loadStructured<LanguagesConfig>(cfgPath);\n}\n\n/** Score languages from a set of file/dir names against the detector config. */\nfunction scoreLanguages(names: string[], cfg: LanguagesConfig, minScore: number): string[] {\n const exts = new Set(names.map(extOf));\n const scored: { id: string; score: number }[] = [];\n for (const lang of cfg.languages) {\n let score = 0;\n for (const m of lang.markers) {\n if (m.includes(\"*\")) {\n const re = globToRegExp(m);\n if (names.some((f) => re.test(f))) score += 3;\n } else if (names.includes(m)) {\n score += 3;\n }\n }\n let extHits = 0;\n for (const e of lang.extensions) if (exts.has(e)) extHits++;\n score += Math.min(extHits, cfg.maxExtensionMatches);\n if (score >= minScore) scored.push({ id: lang.id, score });\n }\n return scored.sort((a, b) => b.score - a.score).map((s) => s.id);\n}\n\n/** Detect which languages a repository uses, ordered by confidence. */\nexport function detectLanguages(cwd: string, assetsRoot: string): string[] {\n const cfg = loadLangConfig(assetsRoot);\n if (!cfg) return [];\n const names = readShallowTree(cwd, 3).map((e) => e.name);\n return scoreLanguages(names, cfg, cfg.minScore);\n}\n\n/**\n * Infer languages from a list of file paths (e.g. a PR's changed files) when a\n * working-directory scan is unavailable or empty. Uses a low threshold since\n * this is a best-effort hint.\n */\nexport function inferLanguagesFromFiles(\n paths: string[],\n assetsRoot: string,\n minScore = 1\n): string[] {\n const cfg = loadLangConfig(assetsRoot);\n if (!cfg) return [];\n const names = paths.flatMap((p) => [p, p.split(\"/\").pop() ?? p]);\n return scoreLanguages(names, cfg, minScore);\n}\n\n/** Resolve the effective standard for a kind via the full override chain. */\nexport function resolveStandard(\n kind: StandardKind,\n opts: GlobalOptions,\n config: EdsgerConfig,\n configDir: string,\n /** Fallback languages used only when a working-dir scan finds nothing. */\n forcedLanguages?: string[]\n): ResolvedStandard {\n const bundled = opts.assetsPath\n ? resolveRootPath(opts.assetsPath, opts.cwd)\n : findBundledAssetsDir();\n\n const languages = opts.lang\n ? [normaliseLang(opts.lang)]\n : config.language\n ? [normaliseLang(config.language)]\n : pickDetected(detectLanguages(opts.cwd, bundled), forcedLanguages);\n\n // Ordered roots: bundled first (lowest precedence), then configured overrides.\n const roots: { path: string; label: string }[] = [\n { path: bundled, label: opts.assetsPath ? `assets:${opts.assetsPath}` : \"bundled\" }\n ];\n const overrideSpec =\n (kind === \"benchmark\" ? config.benchmark?.standards : config.review?.standards) ??\n config.standards;\n if (overrideSpec && !opts.assetsPath) {\n roots.push({ path: resolveRootPath(overrideSpec, configDir), label: `config:${overrideSpec}` });\n }\n\n const layers: { data: Partial<Standard>; label: string }[] = [];\n\n // 1. base + language overlays from each root.\n for (const root of roots) {\n pushIfExists(layers, join(root.path, kind, \"base.yaml\"), `${root.label}/base`);\n for (const lang of languages) {\n pushIfExists(layers, join(root.path, kind, `${lang}.yaml`), `${root.label}/${lang}`);\n }\n }\n\n // 2. repo-local .edsger/<kind>/ overlays (highest-but-one precedence).\n const repoLocal = join(opts.cwd, \".edsger\", kind);\n if (existsSync(repoLocal)) {\n pushIfExists(layers, join(repoLocal, \"base.yaml\"), `repo:.edsger/${kind}/base`);\n for (const lang of languages) {\n pushIfExists(layers, join(repoLocal, `${lang}.yaml`), `repo:.edsger/${kind}/${lang}`);\n }\n }\n\n // 3. explicit --standard path (highest precedence).\n if (opts.standardPath) {\n const p = resolveRootPath(opts.standardPath, opts.cwd);\n if (existsSync(p) && statSync(p).isDirectory()) {\n pushIfExists(layers, join(p, kind, \"base.yaml\"), `--standard/base`);\n for (const lang of languages) {\n pushIfExists(layers, join(p, kind, `${lang}.yaml`), `--standard/${lang}`);\n }\n pushIfExists(layers, join(p, \"base.yaml\"), `--standard/base`);\n } else if (existsSync(p)) {\n pushIfExists(layers, p, `--standard:${opts.standardPath}`);\n } else {\n throw new Error(`--standard path not found: ${p}`);\n }\n }\n\n if (layers.length === 0) {\n throw new Error(`No ${kind} standard found in any source.`);\n }\n\n const merged = mergeLayers(\n kind,\n layers.map((l) => l.data)\n );\n return { standard: merged, layers: layers.map((l) => l.label), languages };\n}\n\n// --- merging -----------------------------------------------------------------\n\nfunction mergeLayers(kind: StandardKind, layers: Partial<Standard>[]): Standard {\n if (kind === \"benchmark\") {\n return layers.reduce(\n (acc, layer) =>\n mergeBenchmark(acc as Partial<BenchmarkStandard>, layer as Partial<BenchmarkStandard>),\n {} as Partial<BenchmarkStandard>\n ) as BenchmarkStandard;\n }\n return layers.reduce(\n (acc, layer) => mergeReview(acc as Partial<ReviewStandard>, layer as Partial<ReviewStandard>),\n {} as Partial<ReviewStandard>\n ) as ReviewStandard;\n}\n\nfunction mergeBenchmark(\n base: Partial<BenchmarkStandard>,\n overlay: Partial<BenchmarkStandard>\n): Partial<BenchmarkStandard> {\n const categories = mergeById<Category>(\n base.categories ?? [],\n overlay.categories ?? [],\n (b, o) => ({\n ...b,\n ...o,\n criteria: mergeById<Criterion>(b.criteria ?? [], o.criteria ?? [], (bc, oc) => ({\n ...bc,\n ...oc\n }))\n })\n );\n return {\n ...base,\n ...overlay,\n // Preserve the base layer's identity rather than the last overlay's.\n id: base.id ?? overlay.id,\n name: base.name ?? overlay.name,\n version: base.version ?? overlay.version,\n kind: \"benchmark\",\n scoreScale: overlay.scoreScale ?? base.scoreScale ?? 4,\n categories\n };\n}\n\nfunction mergeReview(\n base: Partial<ReviewStandard>,\n overlay: Partial<ReviewStandard>\n): Partial<ReviewStandard> {\n const focusAreas = mergeById<FocusArea>(\n base.focusAreas ?? [],\n overlay.focusAreas ?? [],\n (b, o) => ({\n ...b,\n ...o\n })\n );\n return {\n ...base,\n ...overlay,\n id: base.id ?? overlay.id,\n name: base.name ?? overlay.name,\n version: base.version ?? overlay.version,\n kind: \"review\",\n policy: { ...(base.policy ?? {}), ...(overlay.policy ?? {}) } as ReviewStandard[\"policy\"],\n focusAreas\n };\n}\n\nfunction mergeById<T extends { id: string }>(\n base: T[],\n overlay: T[],\n merge: (b: T, o: T) => T\n): T[] {\n const out: T[] = base.map((x) => ({ ...x }));\n const index = new Map(out.map((x, i) => [x.id, i]));\n for (const item of overlay) {\n const at = index.get(item.id);\n if (at === undefined) {\n index.set(item.id, out.length);\n out.push({ ...item });\n } else {\n out[at] = merge(out[at] as T, item);\n }\n }\n return out;\n}\n\n// --- helpers -----------------------------------------------------------------\n\nfunction pushIfExists(\n layers: { data: Partial<Standard>; label: string }[],\n path: string,\n label: string\n): void {\n if (existsSync(path)) {\n layers.push({ data: loadStructured<Partial<Standard>>(path), label });\n log.debug(`standard layer: ${label} (${path})`);\n }\n}\n\nfunction resolveRootPath(spec: string, baseDir: string): string {\n if (spec.startsWith(\"git+\") || /^(https?|git|ssh):\\/\\//.test(spec)) {\n return cloneToCache(spec.replace(/^git\\+/, \"\"));\n }\n return isAbsolute(spec) ? spec : resolve(baseDir, spec);\n}\n\n/** Clone (or reuse a cached clone of) a git standards repo. */\nfunction cloneToCache(url: string): string {\n const [repo, ref] = url.split(\"#\") as [string, string | undefined];\n const safe = repo.replace(/[^a-zA-Z0-9._-]/g, \"_\");\n const dest = join(homedir(), \".cache\", \"edsger\", \"standards\", safe);\n if (!existsSync(dest)) {\n log.step(`cloning standards repo ${repo}`);\n execFileSync(\"git\", [\"clone\", \"--depth\", \"1\", ...(ref ? [\"--branch\", ref] : []), repo, dest], {\n stdio: \"ignore\"\n });\n }\n return dest;\n}\n\ninterface Entry {\n name: string;\n}\n\n/** Read top file/dir names up to `depth` levels, skipping noise dirs. */\nfunction readShallowTree(root: string, depth: number): Entry[] {\n const skip = new Set([\n \"node_modules\",\n \".git\",\n \"dist\",\n \"build\",\n \"out\",\n \"target\",\n \"vendor\",\n \".venv\",\n \"venv\",\n \"__pycache__\",\n \".dart_tool\"\n ]);\n const out: Entry[] = [];\n const walk = (dir: string, level: number): void => {\n let items: string[];\n try {\n items = readdirSync(dir);\n } catch {\n return;\n }\n for (const name of items) {\n if (skip.has(name)) continue;\n out.push({ name });\n if (level < depth) {\n const full = join(dir, name);\n try {\n if (statSync(full).isDirectory()) walk(full, level + 1);\n } catch {\n /* ignore unreadable entries */\n }\n }\n }\n };\n walk(root, 1);\n return out;\n}\n\nfunction extOf(name: string): string {\n const i = name.lastIndexOf(\".\");\n return i < 0 ? \"\" : name.slice(i);\n}\n\nfunction globToRegExp(glob: string): RegExp {\n const escaped = glob.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\").replace(/\\*/g, \".*\");\n return new RegExp(`^${escaped}$`);\n}\n\nfunction pickDetected(detected: string[], fallback?: string[]): string[] {\n return detected.length ? detected : (fallback ?? []);\n}\n\n/** Map a user-supplied language alias to a canonical id (best effort). */\nfunction normaliseLang(input: string): string {\n const v = input.trim().toLowerCase();\n const aliases: Record<string, string> = {\n ts: \"typescript\",\n js: \"typescript\",\n javascript: \"typescript\",\n node: \"typescript\",\n nodejs: \"typescript\",\n py: \"python\",\n golang: \"go\",\n cs: \"csharp\",\n \"c#\": \"csharp\",\n dotnet: \"csharp\",\n jvm: \"java\",\n kotlin: \"java\",\n flutter: \"dart\"\n };\n return aliases[v] ?? v;\n}\n","import pc from \"picocolors\";\n\nlet verbose = false;\n\nexport function setVerbose(v: boolean): void {\n verbose = v;\n}\n\nexport const log = {\n info(msg: string): void {\n process.stderr.write(`${pc.cyan(\"•\")} ${msg}\\n`);\n },\n success(msg: string): void {\n process.stderr.write(`${pc.green(\"✓\")} ${msg}\\n`);\n },\n warn(msg: string): void {\n process.stderr.write(`${pc.yellow(\"!\")} ${msg}\\n`);\n },\n error(msg: string): void {\n process.stderr.write(`${pc.red(\"✗\")} ${msg}\\n`);\n },\n step(msg: string): void {\n process.stderr.write(`${pc.dim(\" →\")} ${pc.dim(msg)}\\n`);\n },\n debug(msg: string): void {\n if (verbose) process.stderr.write(`${pc.dim(` ${msg}`)}\\n`);\n },\n /** Print a heading to stderr so structured stdout stays clean. */\n heading(msg: string): void {\n process.stderr.write(`\\n${pc.bold(msg)}\\n`);\n }\n};\n","import { readFileSync } from \"node:fs\";\nimport yaml from \"js-yaml\";\n\n/** Parse a YAML or JSON file into a plain object. */\nexport function loadStructured<T = unknown>(path: string): T {\n const raw = readFileSync(path, \"utf8\");\n return yaml.load(raw) as T;\n}\n\n/** Parse a YAML or JSON string. */\nexport function parseStructured<T = unknown>(raw: string): T {\n return yaml.load(raw) as T;\n}\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { loadStructured } from \"../util/yaml.js\";\n\n/**\n * User configuration, discovered from the target repository or home dir.\n * Everything is optional — zero config falls back to bundled assets.\n */\nexport interface EdsgerConfig {\n /** Default model for agent runs. */\n model?: string;\n /**\n * Override the standards source. Either:\n * - a local path (absolute, or relative to the config file), or\n * - a git URL (clone + cache) — supported via the `git+` prefix.\n */\n standards?: string;\n /** Force a language id, skipping auto-detection. */\n language?: string;\n /** Per-kind overrides, e.g. { benchmark: \"./team-standards\" }. */\n benchmark?: { standards?: string };\n review?: { standards?: string };\n}\n\nconst CONFIG_FILENAMES = [\n \"edsger.config.yaml\",\n \"edsger.config.yml\",\n \"edsger.config.json\",\n \".edsgerrc.yaml\",\n \".edsgerrc.yml\",\n \".edsgerrc.json\",\n \".edsgerrc\"\n];\n\n/** Find and load an edsger config file from `cwd`, then `.edsger/`. */\nexport function loadConfig(cwd: string): { config: EdsgerConfig; path?: string } {\n const searchDirs = [cwd, join(cwd, \".edsger\")];\n for (const dir of searchDirs) {\n for (const name of CONFIG_FILENAMES) {\n const p = join(dir, name);\n if (existsSync(p)) {\n try {\n const config = loadStructured<EdsgerConfig>(p) ?? {};\n return { config, path: p };\n } catch {\n // Malformed config should not crash discovery; ignore and continue.\n }\n }\n }\n }\n return { config: {} };\n}\n","import {\n createSdkMcpServer,\n query,\n tool,\n type McpServerConfig\n} from \"@anthropic-ai/claude-agent-sdk\";\nimport type { ZodRawShape } from \"zod\";\nimport { z } from \"zod\";\nimport { log } from \"./logger.js\";\n\nexport interface AgentRunOptions<Shape extends ZodRawShape> {\n /** The instruction given to the agent. */\n prompt: string;\n /** Working directory the agent operates in. */\n cwd: string;\n model: string;\n maxTurns: number;\n /** Whether the agent may modify files (Edit/Write) and run mutating commands. */\n allowWrite: boolean;\n /** Appended to the Claude Code system prompt preset. */\n systemPromptAppend: string;\n /**\n * Zod shape describing the structured result. The agent is required to call a\n * `submit_result` tool with this shape exactly once; its validated args are\n * returned. This is the reliable way to get machine-readable output.\n */\n resultShape: Shape;\n /** Extra MCP servers (e.g. github) to expose to the agent. */\n extraMcpServers?: Record<string, McpServerConfig>;\n /** Extra tool names to allow (e.g. \"mcp__github__*\"). */\n extraAllowedTools?: string[];\n /** Hard wall-clock limit; the run is aborted if it exceeds this. */\n timeoutMs?: number;\n verbose: boolean;\n}\n\nexport interface AgentRunResult<T> {\n result: T | undefined;\n costUsd: number;\n numTurns: number;\n}\n\nconst READ_ONLY_DISALLOWED = [\"Edit\", \"Write\", \"NotebookEdit\"];\n\n/**\n * Run an agentic loop with the Claude Agent SDK and collect a structured\n * result. Read-only runs have edit tools removed from the agent's context.\n */\nexport async function runAgent<Shape extends ZodRawShape>(\n opts: AgentRunOptions<Shape>\n): Promise<AgentRunResult<z.infer<z.ZodObject<Shape>>>> {\n type Result = z.infer<z.ZodObject<Shape>>;\n let captured: Result | undefined;\n\n const submitTool = tool(\n \"submit_result\",\n \"Submit the final structured result. Call this exactly once when done.\",\n opts.resultShape,\n async (args) => {\n captured = args as Result;\n return { content: [{ type: \"text\", text: \"Result recorded. You may stop now.\" }] };\n }\n );\n\n const outServer = createSdkMcpServer({\n name: \"edsger_out\",\n version: \"1.0.0\",\n tools: [submitTool]\n });\n\n const allowedTools = [\n \"Read\",\n \"Grep\",\n \"Glob\",\n \"Bash\",\n \"mcp__edsger_out__submit_result\",\n ...(opts.allowWrite ? [\"Edit\", \"Write\", \"MultiEdit\"] : []),\n ...(opts.extraAllowedTools ?? [])\n ];\n\n const mcpServers: Record<string, McpServerConfig> = {\n edsger_out: outServer,\n ...(opts.extraMcpServers ?? {})\n };\n\n let costUsd = 0;\n let numTurns = 0;\n\n // Enforce a wall-clock limit so a stuck run cannot hang a CI job.\n const controller = new AbortController();\n const timer = opts.timeoutMs ? setTimeout(() => controller.abort(), opts.timeoutMs) : undefined;\n\n const stream = query({\n prompt: opts.prompt,\n options: {\n model: opts.model,\n cwd: opts.cwd,\n maxTurns: opts.maxTurns,\n // Reproducible runs: do not load the target repo's settings/CLAUDE.md.\n settingSources: [],\n systemPrompt: {\n type: \"preset\",\n preset: \"claude_code\",\n append: opts.systemPromptAppend\n },\n // The user explicitly invoked an agent to inspect/modify their own repo.\n // Capability is shaped by allowedTools/disallowedTools rather than prompts:\n // read-only runs have edit tools removed from context entirely (below).\n permissionMode: \"bypassPermissions\",\n allowedTools,\n disallowedTools: opts.allowWrite ? [] : READ_ONLY_DISALLOWED,\n mcpServers,\n abortController: controller\n }\n });\n\n try {\n for await (const message of stream as AsyncIterable<AnyMessage>) {\n if (message.type === \"assistant\") {\n for (const block of message.message?.content ?? []) {\n if (block.type === \"tool_use\") {\n log.debug(`tool: ${block.name}`);\n } else if (block.type === \"text\" && opts.verbose && block.text?.trim()) {\n log.debug(block.text.trim().split(\"\\n\")[0] ?? \"\");\n }\n }\n } else if (message.type === \"result\") {\n costUsd = message.total_cost_usd ?? 0;\n numTurns = message.num_turns ?? 0;\n if (message.subtype && message.subtype !== \"success\") {\n log.warn(`agent ended with: ${message.subtype}`);\n }\n }\n }\n } catch (err) {\n if (controller.signal.aborted) {\n throw new Error(`Agent run timed out after ${Math.round((opts.timeoutMs ?? 0) / 1000)}s.`);\n }\n throw err;\n } finally {\n if (timer) clearTimeout(timer);\n }\n\n return { result: captured, costUsd, numTurns };\n}\n\n// Minimal structural typing over the SDK message union so we are resilient to\n// version drift in exported type names.\ninterface AnyMessage {\n type: string;\n subtype?: string;\n total_cost_usd?: number;\n num_turns?: number;\n message?: { content?: Array<{ type: string; name?: string; text?: string }> };\n}\n","import type { BenchmarkStandard, Category, Criterion } from \"../types.js\";\nimport type { BenchmarkResult } from \"./schema.js\";\n\nexport interface ScoredCriterion {\n id: string;\n title: string;\n weight: number;\n rawScore: number;\n maxScore: number;\n fraction: number;\n justification: string;\n evidence: string[];\n}\n\nexport interface ScoredCategory {\n id: string;\n name: string;\n weight: number; // normalised to sum 100 across categories\n fraction: number; // 0..1\n points: number; // weight * fraction\n criteria: ScoredCriterion[];\n}\n\nexport interface ScoredBenchmark {\n standardName: string;\n standardVersion: string;\n overall: number; // 0..100\n grade: string;\n categories: ScoredCategory[];\n summary: string;\n strengths: string[];\n weaknesses: string[];\n recommendations: BenchmarkResult[\"recommendations\"];\n}\n\n/** Deterministically aggregate the agent's per-criterion scores. */\nexport function scoreBenchmark(\n standard: BenchmarkStandard,\n result: BenchmarkResult\n): ScoredBenchmark {\n const scale = standard.scoreScale || 4;\n const totalWeight = standard.categories.reduce((s, c) => s + c.weight, 0) || 1;\n const scoreLookup = new Map<string, number>();\n for (const cat of result.categories) {\n for (const cr of cat.criteria) scoreLookup.set(`${cat.id}/${cr.id}`, cr.score);\n }\n const justifyLookup = new Map<string, { justification: string; evidence: string[] }>();\n for (const cat of result.categories) {\n for (const cr of cat.criteria) {\n justifyLookup.set(`${cat.id}/${cr.id}`, {\n justification: cr.justification,\n evidence: cr.evidence ?? []\n });\n }\n }\n\n const categories: ScoredCategory[] = standard.categories.map((cat: Category) => {\n const critWeightTotal = cat.criteria.reduce((s, c) => s + (c.weight ?? 1), 0) || 1;\n const scored: ScoredCriterion[] = cat.criteria.map((cr: Criterion) => {\n const raw = clamp(scoreLookup.get(`${cat.id}/${cr.id}`) ?? 0, 0, scale);\n const meta = justifyLookup.get(`${cat.id}/${cr.id}`);\n return {\n id: cr.id,\n title: cr.title,\n weight: cr.weight ?? 1,\n rawScore: raw,\n maxScore: scale,\n fraction: raw / scale,\n justification: meta?.justification ?? \"Not assessed.\",\n evidence: meta?.evidence ?? []\n };\n });\n const fraction = scored.reduce((s, c) => s + c.fraction * c.weight, 0) / critWeightTotal;\n const normWeight = (cat.weight / totalWeight) * 100;\n return {\n id: cat.id,\n name: cat.name,\n weight: round(normWeight, 1),\n fraction,\n points: round(normWeight * fraction, 1),\n criteria: scored\n };\n });\n\n const overall = round(\n categories.reduce((s, c) => s + c.points, 0),\n 1\n );\n\n return {\n standardName: standard.name,\n standardVersion: standard.version,\n overall,\n grade: gradeFor(overall),\n categories,\n summary: result.summary,\n strengths: result.strengths ?? [],\n weaknesses: result.weaknesses ?? [],\n recommendations: result.recommendations ?? []\n };\n}\n\nexport function gradeFor(score: number): string {\n if (score >= 90) return \"A\";\n if (score >= 80) return \"B\";\n if (score >= 70) return \"C\";\n if (score >= 60) return \"D\";\n return \"F\";\n}\n\n/** Render a human-readable Markdown report. */\nexport function renderBenchmarkMarkdown(\n scored: ScoredBenchmark,\n meta: { repo: string; languages: string[]; layers: string[]; generatedAt: string; model: string }\n): string {\n const lines: string[] = [];\n lines.push(`# Edsger Benchmark Report`);\n lines.push(\"\");\n lines.push(`**Score: ${scored.overall} / 100 (Grade ${scored.grade})**`);\n lines.push(\"\");\n lines.push(`> ${scored.summary}`);\n lines.push(\"\");\n lines.push(`| Field | Value |`);\n lines.push(`| --- | --- |`);\n lines.push(`| Repository | \\`${meta.repo}\\` |`);\n lines.push(`| Languages | ${meta.languages.join(\", \") || \"n/a\"} |`);\n lines.push(`| Standard | ${scored.standardName} v${scored.standardVersion} |`);\n lines.push(`| Sources | ${meta.layers.join(\" → \")} |`);\n lines.push(`| Model | ${meta.model} |`);\n lines.push(`| Generated | ${meta.generatedAt} |`);\n lines.push(\"\");\n\n lines.push(`## Category scores`);\n lines.push(\"\");\n lines.push(`| Category | Weight | Score | Weighted |`);\n lines.push(`| --- | ---: | ---: | ---: |`);\n for (const c of scored.categories) {\n lines.push(`| ${c.name} | ${c.weight}% | ${Math.round(c.fraction * 100)}% | ${c.points} |`);\n }\n lines.push(`| **Overall** | **100%** | | **${scored.overall}** |`);\n lines.push(\"\");\n\n if (scored.strengths.length) {\n lines.push(`## Strengths`);\n lines.push(\"\");\n for (const s of scored.strengths) lines.push(`- ${s}`);\n lines.push(\"\");\n }\n if (scored.weaknesses.length) {\n lines.push(`## Weaknesses`);\n lines.push(\"\");\n for (const w of scored.weaknesses) lines.push(`- ${w}`);\n lines.push(\"\");\n }\n if (scored.recommendations.length) {\n lines.push(`## Recommendations`);\n lines.push(\"\");\n for (const r of scored.recommendations) {\n lines.push(`- **[${r.priority}] ${r.title}** — ${r.detail}`);\n }\n lines.push(\"\");\n }\n\n lines.push(`## Detailed findings`);\n lines.push(\"\");\n for (const c of scored.categories) {\n lines.push(`### ${c.name} — ${Math.round(c.fraction * 100)}%`);\n lines.push(\"\");\n for (const cr of c.criteria) {\n lines.push(`- **${cr.title}** (${cr.rawScore}/${cr.maxScore}) — ${cr.justification}`);\n for (const e of cr.evidence) lines.push(` - \\`${e}\\``);\n }\n lines.push(\"\");\n }\n\n lines.push(`---`);\n lines.push(`<sub>Generated by [edsger](https://www.npmjs.com/package/edsger).</sub>`);\n return lines.join(\"\\n\");\n}\n\nfunction clamp(n: number, lo: number, hi: number): number {\n return Math.max(lo, Math.min(hi, n));\n}\nfunction round(n: number, dp: number): number {\n const f = 10 ** dp;\n return Math.round(n * f) / f;\n}\n","import { z } from \"zod\";\n\n/** Per-criterion score the agent must produce for a benchmark. */\nexport const CriterionScoreSchema = z.object({\n id: z.string().describe(\"Criterion id from the rubric\"),\n score: z.number().describe(\"Score for this criterion, 0..scoreScale\"),\n justification: z.string().describe(\"Why this score, in one or two sentences\"),\n evidence: z.array(z.string()).default([]).describe(\"File paths / snippets supporting the score\")\n});\n\nexport const CategoryScoreSchema = z.object({\n id: z.string().describe(\"Category id from the rubric\"),\n criteria: z.array(CriterionScoreSchema)\n});\n\nexport const BenchmarkResultSchema = z.object({\n categories: z.array(CategoryScoreSchema),\n summary: z.string().describe(\"2-4 sentence overall assessment\"),\n strengths: z.array(z.string()).default([]),\n weaknesses: z.array(z.string()).default([]),\n recommendations: z\n .array(\n z.object({\n priority: z.enum([\"high\", \"medium\", \"low\"]),\n title: z.string(),\n detail: z.string()\n })\n )\n .default([])\n});\nexport type BenchmarkResult = z.infer<typeof BenchmarkResultSchema>;\n\nconst SeveritySchema = z.enum([\"critical\", \"high\", \"medium\", \"low\", \"info\"]);\n\nexport const ReviewFindingSchema = z.object({\n focusArea: z.string().describe(\"Focus area id this finding relates to\"),\n severity: SeveritySchema,\n file: z.string().describe(\"Repo-relative file path, or '-' if general\"),\n line: z.number().nullable().default(null).describe(\"1-based line in the new file, if applicable\"),\n title: z.string(),\n detail: z.string().describe(\"What is wrong and why it matters\"),\n suggestion: z.string().nullable().default(null).describe(\"Concrete suggested fix\")\n});\n\nexport const ReviewResultSchema = z.object({\n summary: z.string().describe(\"Overall summary of the change and review\"),\n verdict: z.enum([\"approve\", \"request_changes\", \"comment\"]),\n findings: z.array(ReviewFindingSchema).default([])\n});\nexport type ReviewResult = z.infer<typeof ReviewResultSchema>;\nexport type ReviewFinding = z.infer<typeof ReviewFindingSchema>;\n\nexport const ResolveResultSchema = z.object({\n summary: z.string().describe(\"What was changed and why\"),\n changes: z.array(z.object({ file: z.string(), description: z.string() })).default([]),\n testsRun: z.string().nullable().default(null).describe(\"Command used to verify, and its outcome\"),\n remaining: z.array(z.string()).default([]).describe(\"Anything still unresolved\")\n});\nexport type ResolveResult = z.infer<typeof ResolveResultSchema>;\n","import pc from \"picocolors\";\nimport { findBundledAssetsDir, inferLanguagesFromFiles, resolveStandard } from \"../core/assets.js\";\nimport { loadConfig } from \"../core/config.js\";\nimport { runAgent } from \"../core/agent.js\";\nimport {\n ensureGhReady,\n getPrContext,\n postReview,\n type InlineComment,\n type PrContext,\n type ReviewEvent\n} from \"../core/gh.js\";\nimport { log } from \"../core/logger.js\";\nimport { ReviewResultSchema, type ReviewFinding, type ReviewResult } from \"../core/schema.js\";\nimport type { GlobalOptions, ReviewStandard, Severity } from \"../types.js\";\n\nexport interface PrReviewOptions extends GlobalOptions {\n pr: string;\n repo?: string;\n /** Actually submit the review to GitHub (otherwise preview only). */\n post: boolean;\n}\n\nconst SEVERITY_RANK: Record<Severity, number> = {\n critical: 4,\n high: 3,\n medium: 2,\n low: 1,\n info: 0\n};\n\nexport async function runPrReview(opts: PrReviewOptions): Promise<number> {\n await ensureGhReady();\n log.info(`Fetching PR ${pc.bold(opts.pr)}${opts.repo ? ` from ${opts.repo}` : \"\"}`);\n const ctx = await getPrContext(opts.pr, opts.repo, opts.cwd);\n\n const { config, path: configPath } = loadConfig(opts.cwd);\n const configDir = configPath ? `${configPath}/..` : opts.cwd;\n // If the working dir doesn't reveal the language (e.g. reviewing a PR without\n // checking it out), fall back to the PR's changed file types.\n const fileHint = inferLanguagesFromFiles(\n ctx.files.map((f) => f.path),\n findBundledAssetsDir()\n );\n const resolved = resolveStandard(\"review\", opts, config, configDir, fileHint);\n const standard = resolved.standard as ReviewStandard;\n\n log.info(\n `Reviewing \"${pc.bold(ctx.title)}\" (#${ctx.number}, ${ctx.files.length} files) ` +\n `against ${pc.bold(standard.name)}`\n );\n\n const { result, costUsd, numTurns } = await runAgent({\n prompt: buildPrompt(standard, ctx),\n cwd: opts.cwd,\n model: opts.model,\n maxTurns: opts.maxTurns,\n timeoutMs: opts.timeoutMs,\n allowWrite: false,\n verbose: opts.verbose,\n resultShape: ReviewResultSchema.shape,\n systemPromptAppend:\n \"You are Edsger, a senior code reviewer. Review only what the diff changes, but read \" +\n \"surrounding code for context. Be specific, kind, and actionable; prefer high-signal \" +\n \"findings over nitpicks. Do not modify any files.\"\n });\n\n if (!result) {\n log.error(\"The agent did not produce a review.\");\n return 1;\n }\n\n const event = decideEvent(result, standard);\n const body = renderBody(result, ctx, standard, resolved.layers);\n const inline = buildInlineComments(result, ctx, standard);\n\n printPreview(result, event, numTurns, costUsd);\n\n if (opts.json) {\n process.stdout.write(\n JSON.stringify(\n { verdict: result.verdict, event, findings: result.findings, summary: result.summary },\n null,\n 2\n ) + \"\\n\"\n );\n }\n\n if (opts.post && !opts.dryRun) {\n await postReview(ctx, opts.repo, event, body, inline, opts.cwd);\n log.success(`Posted review (${event}) to ${ctx.url}`);\n } else {\n log.warn(`Preview only. Re-run with ${pc.bold(\"--post\")} to submit this review to GitHub.`);\n process.stderr.write(\"\\n\" + body + \"\\n\");\n }\n return 0;\n}\n\nfunction decideEvent(result: ReviewResult, standard: ReviewStandard): ReviewEvent {\n const blocking = new Set(standard.policy.blockingSeverities);\n const hasBlocking = result.findings.some((f) => blocking.has(f.severity));\n if (hasBlocking) return \"REQUEST_CHANGES\";\n if (result.verdict === \"approve\") return \"APPROVE\";\n if (result.verdict === \"request_changes\") return \"REQUEST_CHANGES\";\n return \"COMMENT\";\n}\n\nfunction buildInlineComments(\n result: ReviewResult,\n ctx: PrContext,\n standard: ReviewStandard\n): InlineComment[] {\n const changed = new Set(ctx.files.map((f) => f.path));\n const sorted = [...result.findings].sort(\n (a, b) => SEVERITY_RANK[b.severity] - SEVERITY_RANK[a.severity]\n );\n const out: InlineComment[] = [];\n for (const f of sorted) {\n if (out.length >= standard.policy.maxComments) break;\n if (f.line && f.file && f.file !== \"-\" && changed.has(f.file)) {\n out.push({ path: f.file, line: f.line, body: renderFinding(f) });\n }\n }\n return out;\n}\n\nfunction renderFinding(f: ReviewFinding): string {\n const head = `**[${f.severity}] ${f.title}**`;\n const fix = f.suggestion ? `\\n\\n_Suggestion:_ ${f.suggestion}` : \"\";\n return `${head}\\n\\n${f.detail}${fix}`;\n}\n\nfunction renderBody(\n result: ReviewResult,\n ctx: PrContext,\n standard: ReviewStandard,\n layers: string[]\n): string {\n const counts = countBySeverity(result.findings);\n const lines: string[] = [];\n lines.push(`## Edsger review — ${verdictLabel(result.verdict)}`);\n lines.push(\"\");\n lines.push(result.summary);\n lines.push(\"\");\n lines.push(\n `**Findings:** ` +\n ([\"critical\", \"high\", \"medium\", \"low\", \"info\"] as Severity[])\n .filter((s) => counts[s])\n .map((s) => `${counts[s]} ${s}`)\n .join(\", \") || \"no blocking issues\"\n );\n lines.push(\"\");\n const general = result.findings.filter((f) => !f.line || f.file === \"-\");\n if (general.length) {\n lines.push(`### General comments`);\n lines.push(\"\");\n for (const f of general) lines.push(`- ${renderFinding(f).replace(/\\n+/g, \" \")}`);\n lines.push(\"\");\n }\n lines.push(\"---\");\n lines.push(\n `<sub>Reviewed against ${standard.name} v${standard.version} ` +\n `(${layers.join(\" → \")}) by [edsger](https://www.npmjs.com/package/edsger).</sub>`\n );\n void ctx;\n return lines.join(\"\\n\");\n}\n\nfunction printPreview(\n result: ReviewResult,\n event: ReviewEvent,\n numTurns: number,\n costUsd: number\n): void {\n log.heading(`Verdict: ${event}`);\n const counts = countBySeverity(result.findings);\n for (const s of [\"critical\", \"high\", \"medium\", \"low\", \"info\"] as Severity[]) {\n if (counts[s]) process.stderr.write(` ${sevColor(s)(s.padEnd(8))} ${counts[s]}\\n`);\n }\n log.step(`${numTurns} turns · ~$${costUsd.toFixed(3)}`);\n}\n\nfunction countBySeverity(findings: ReviewFinding[]): Record<Severity, number> {\n const c: Record<Severity, number> = { critical: 0, high: 0, medium: 0, low: 0, info: 0 };\n for (const f of findings) c[f.severity]++;\n return c;\n}\n\nfunction sevColor(s: Severity): (t: string) => string {\n if (s === \"critical\" || s === \"high\") return pc.red;\n if (s === \"medium\") return pc.yellow;\n return pc.dim;\n}\n\nfunction verdictLabel(v: ReviewResult[\"verdict\"]): string {\n return v === \"approve\" ? \"Approve\" : v === \"request_changes\" ? \"Request changes\" : \"Comment\";\n}\n\nfunction buildPrompt(standard: ReviewStandard, ctx: PrContext): string {\n const focus = standard.focusAreas\n .map((fa) => {\n const checklist = (fa.checklist ?? []).map((c) => ` - ${c}`).join(\"\\n\");\n return (\n `- id: ${fa.id} (${fa.title}, default severity ${fa.defaultSeverity ?? \"medium\"})\\n` +\n ` guidance: ${fa.guidance.trim()}` +\n (checklist ? `\\n checklist:\\n${checklist}` : \"\")\n );\n })\n .join(\"\\n\");\n\n return [\n `Review the following pull request.`,\n ``,\n `Title: ${ctx.title}`,\n `Author: ${ctx.author}`,\n `Base: ${ctx.baseRefName} Head: ${ctx.headRefName}`,\n `Description:`,\n ctx.body ? indent(ctx.body) : \" (no description)\",\n ``,\n `Changed files: ${ctx.files.map((f) => f.path).join(\", \")}`,\n ``,\n `Method:`,\n `1. Read the diff below. Use Read/Grep/Glob to inspect surrounding code in the working`,\n ` directory for context when needed. Do NOT modify files.`,\n `2. Evaluate the change against the focus areas. Assign each finding a severity`,\n ` (critical/high/medium/low/info) and, where it maps to a changed line, the file path`,\n ` and the 1-based line number in the NEW version of the file.`,\n `3. Verify the change does what its description claims; flag missing tests for new logic.`,\n `4. Choose a verdict: approve, request_changes, or comment. Then call submit_result once.`,\n ``,\n `Focus areas:`,\n focus,\n ``,\n `Unified diff:`,\n \"```diff\",\n truncate(ctx.diff, 180000),\n \"```\"\n ].join(\"\\n\");\n}\n\nfunction indent(s: string): string {\n return s\n .split(\"\\n\")\n .map((l) => ` ${l}`)\n .join(\"\\n\");\n}\nfunction truncate(s: string, max: number): string {\n return s.length > max ? s.slice(0, max) + \"\\n... [diff truncated] ...\" : s;\n}\n","import { execFile } from \"node:child_process\";\nimport { mkdtempSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\n\nconst exec = promisify(execFile);\n\nexport interface PrContext {\n number: number;\n title: string;\n body: string;\n author: string;\n baseRefName: string;\n headRefName: string;\n state: string;\n url: string;\n /** True when the PR head lives in a fork (cannot push to origin directly). */\n isCrossRepository: boolean;\n files: { path: string; additions: number; deletions: number }[];\n diff: string;\n}\n\nexport interface InlineComment {\n path: string;\n line: number;\n body: string;\n}\n\nasync function gh(args: string[], cwd?: string): Promise<string> {\n const { stdout } = await exec(\"gh\", args, {\n cwd,\n maxBuffer: 64 * 1024 * 1024,\n env: process.env\n });\n return stdout;\n}\n\n/** Throw a friendly error if gh is missing or not authenticated. */\nexport async function ensureGhReady(): Promise<void> {\n try {\n await exec(\"gh\", [\"--version\"]);\n } catch {\n throw new Error(\n \"GitHub CLI (gh) not found. Install it from https://cli.github.com and run `gh auth login`.\"\n );\n }\n try {\n await exec(\"gh\", [\"auth\", \"status\"]);\n } catch {\n throw new Error(\"Not authenticated with GitHub. Run `gh auth login` first.\");\n }\n}\n\n/** Fetch PR metadata, changed files, and the unified diff. */\nexport async function getPrContext(\n ref: string,\n repo: string | undefined,\n cwd: string\n): Promise<PrContext> {\n const repoArgs = repo ? [\"--repo\", repo] : [];\n const fields =\n \"number,title,body,author,baseRefName,headRefName,state,url,isCrossRepository,files\";\n const metaRaw = await gh([\"pr\", \"view\", ref, ...repoArgs, \"--json\", fields], cwd);\n const meta = JSON.parse(metaRaw) as {\n number: number;\n title: string;\n body: string | null;\n author: { login: string };\n baseRefName: string;\n headRefName: string;\n state: string;\n url: string;\n isCrossRepository: boolean;\n files: { path: string; additions: number; deletions: number }[];\n };\n const diff = await gh([\"pr\", \"diff\", ref, ...repoArgs], cwd);\n return {\n number: meta.number,\n title: meta.title,\n body: meta.body ?? \"\",\n author: meta.author?.login ?? \"unknown\",\n baseRefName: meta.baseRefName,\n headRefName: meta.headRefName,\n state: meta.state,\n url: meta.url,\n isCrossRepository: Boolean(meta.isCrossRepository),\n files: meta.files ?? [],\n diff\n };\n}\n\n/** Check out a PR branch locally (for pr-resolve). */\nexport async function checkoutPr(\n ref: string,\n repo: string | undefined,\n cwd: string\n): Promise<void> {\n const repoArgs = repo ? [\"--repo\", repo] : [];\n await gh([\"pr\", \"checkout\", ref, ...repoArgs], cwd);\n}\n\nexport type ReviewEvent = \"APPROVE\" | \"REQUEST_CHANGES\" | \"COMMENT\";\n\n/**\n * Post a review. Inline comments are submitted via the REST API so they attach\n * to specific lines; the summary body is included in the same review.\n */\nexport async function postReview(\n ctx: PrContext,\n repo: string | undefined,\n event: ReviewEvent,\n body: string,\n inline: InlineComment[],\n cwd: string\n): Promise<void> {\n const target = repo ?? (await currentRepoSlug(cwd));\n if (inline.length === 0) {\n const flag =\n event === \"APPROVE\"\n ? \"--approve\"\n : event === \"REQUEST_CHANGES\"\n ? \"--request-changes\"\n : \"--comment\";\n await gh([\"pr\", \"review\", String(ctx.number), \"--repo\", target, flag, \"--body\", body], cwd);\n return;\n }\n const payload = {\n body,\n event,\n comments: inline.map((c) => ({ path: c.path, line: c.line, side: \"RIGHT\", body: c.body }))\n };\n const dir = mkdtempSync(join(tmpdir(), \"edsger-review-\"));\n const file = join(dir, \"review.json\");\n writeFileSync(file, JSON.stringify(payload), \"utf8\");\n try {\n await gh(\n [\"api\", \"--method\", \"POST\", `repos/${target}/pulls/${ctx.number}/reviews`, \"--input\", file],\n cwd\n );\n } catch {\n // Fall back to a plain summary review if inline submission fails (e.g. a\n // comment targets a line outside the diff).\n const flag =\n event === \"APPROVE\"\n ? \"--approve\"\n : event === \"REQUEST_CHANGES\"\n ? \"--request-changes\"\n : \"--comment\";\n await gh([\"pr\", \"review\", String(ctx.number), \"--repo\", target, flag, \"--body\", body], cwd);\n } finally {\n rmSync(dir, { recursive: true, force: true });\n }\n}\n\n/** Resolve \"owner/repo\" for the current checkout. */\nexport async function currentRepoSlug(cwd: string): Promise<string> {\n const raw = await gh([\"repo\", \"view\", \"--json\", \"nameWithOwner\"], cwd);\n return (JSON.parse(raw) as { nameWithOwner: string }).nameWithOwner;\n}\n\nexport interface PrFeedback {\n reviewComments: { author: string; path: string; line: number | null; body: string }[];\n issueComments: { author: string; body: string }[];\n}\n\n/** Fetch inline review comments and conversation comments on a PR. */\nexport async function getPrFeedback(\n ctx: PrContext,\n repo: string | undefined,\n cwd: string\n): Promise<PrFeedback> {\n const target = repo ?? (await currentRepoSlug(cwd));\n const reviewRaw = await gh(\n [\"api\", `repos/${target}/pulls/${ctx.number}/comments`, \"--paginate\"],\n cwd\n ).catch(() => \"[]\");\n const issueRaw = await gh(\n [\"api\", `repos/${target}/issues/${ctx.number}/comments`, \"--paginate\"],\n cwd\n ).catch(() => \"[]\");\n const review = JSON.parse(reviewRaw) as Array<{\n user: { login: string };\n path: string;\n line: number | null;\n body: string;\n }>;\n const issue = JSON.parse(issueRaw) as Array<{ user: { login: string }; body: string }>;\n return {\n reviewComments: review.map((c) => ({\n author: c.user?.login ?? \"unknown\",\n path: c.path,\n line: c.line,\n body: c.body\n })),\n issueComments: issue.map((c) => ({ author: c.user?.login ?? \"unknown\", body: c.body }))\n };\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport pc from \"picocolors\";\nimport { runAgent } from \"../core/agent.js\";\nimport {\n checkoutPr,\n ensureGhReady,\n getPrContext,\n getPrFeedback,\n type PrContext,\n type PrFeedback\n} from \"../core/gh.js\";\nimport { log } from \"../core/logger.js\";\nimport { ResolveResultSchema, type ResolveResult } from \"../core/schema.js\";\nimport type { GlobalOptions } from \"../types.js\";\n\nconst exec = promisify(execFile);\n\nexport interface PrResolveOptions extends GlobalOptions {\n pr: string;\n repo?: string;\n /** Free-form instruction, e.g. \"address review comments and fix the failing test\". */\n instruction?: string;\n /** Check out the PR branch locally before editing. */\n checkout: boolean;\n /** Commit and push the changes when done. */\n push: boolean;\n}\n\nexport async function runPrResolve(opts: PrResolveOptions): Promise<number> {\n await ensureGhReady();\n log.info(`Fetching PR ${pc.bold(opts.pr)}${opts.repo ? ` from ${opts.repo}` : \"\"}`);\n const ctx = await getPrContext(opts.pr, opts.repo, opts.cwd);\n const feedback = await getPrFeedback(ctx, opts.repo, opts.cwd).catch(() => ({\n reviewComments: [],\n issueComments: []\n }));\n\n if (opts.checkout && !opts.dryRun) {\n log.step(`checking out PR branch ${ctx.headRefName}`);\n await checkoutPr(opts.pr, opts.repo, opts.cwd);\n }\n\n log.info(\n `Resolving \"${pc.bold(ctx.title)}\" (#${ctx.number}) — ` +\n `${feedback.reviewComments.length} review comments`\n );\n\n const { result, costUsd, numTurns } = await runAgent({\n prompt: buildPrompt(ctx, feedback, opts.instruction),\n cwd: opts.cwd,\n model: opts.model,\n maxTurns: Math.max(opts.maxTurns, 30),\n timeoutMs: Math.max(opts.timeoutMs, 20 * 60_000),\n allowWrite: true,\n verbose: opts.verbose,\n resultShape: ResolveResultSchema.shape,\n systemPromptAppend:\n \"You are Edsger, a careful senior engineer fixing a pull request. Make the smallest \" +\n \"correct change that addresses the feedback. Match the existing code style. After \" +\n \"editing, run the project's tests/linters to verify. Never weaken tests to make them \" +\n \"pass, and never commit secrets.\"\n });\n\n if (!result) {\n log.error(\"The agent did not produce a result.\");\n return 1;\n }\n\n printSummary(result, numTurns, costUsd);\n if (opts.json) process.stdout.write(JSON.stringify(result, null, 2) + \"\\n\");\n\n if (opts.push && !opts.dryRun) {\n const pushed = await commitAndPush(ctx, result, opts.cwd, opts.checkout);\n if (pushed) log.success(`Committed and pushed to ${ctx.headRefName}`);\n else log.warn(\"Nothing to commit — working tree is clean.\");\n } else {\n log.warn(\n `Changes left in the working tree. Review them, then commit/push (or re-run with ${pc.bold(\"--push\")}).`\n );\n }\n return 0;\n}\n\nasync function commitAndPush(\n ctx: PrContext,\n result: ResolveResult,\n cwd: string,\n checkedOut: boolean\n): Promise<boolean> {\n const status = await exec(\"git\", [\"status\", \"--porcelain\"], { cwd });\n if (!status.stdout.trim()) return false;\n await exec(\"git\", [\"add\", \"-A\"], { cwd });\n const message = `fix: address review feedback on #${ctx.number}\\n\\n${result.summary}`;\n await exec(\"git\", [\"commit\", \"-m\", message], { cwd });\n\n // `gh pr checkout` configures the local branch to push back to the right\n // remote (including a fork), so prefer a plain push when we checked out.\n if (checkedOut) {\n try {\n await exec(\"git\", [\"push\"], { cwd });\n return true;\n } catch (err) {\n if (ctx.isCrossRepository) {\n throw new Error(\n `Could not push to the fork's branch automatically: ${errText(err)}\\n` +\n \"Push manually, or ensure the PR branch was checked out with gh.\"\n );\n }\n // Same-repo: fall through to an explicit origin push.\n }\n }\n if (ctx.isCrossRepository) {\n throw new Error(\n \"This PR is from a fork. Re-run without --no-checkout so gh can configure \" +\n \"the push target, or commit and push to the fork manually.\"\n );\n }\n await exec(\"git\", [\"push\", \"origin\", `HEAD:${ctx.headRefName}`], { cwd });\n return true;\n}\n\nfunction errText(err: unknown): string {\n return err instanceof Error ? (err.message.split(\"\\n\")[0] ?? \"\") : String(err);\n}\n\nfunction printSummary(result: ResolveResult, numTurns: number, costUsd: number): void {\n log.heading(\"Resolution summary\");\n process.stderr.write(` ${result.summary}\\n\\n`);\n if (result.changes.length) {\n for (const c of result.changes)\n process.stderr.write(` ${pc.green(\"~\")} ${c.file} — ${c.description}\\n`);\n }\n if (result.testsRun) log.step(`verification: ${result.testsRun}`);\n if (result.remaining.length) {\n log.warn(\"Remaining items:\");\n for (const r of result.remaining) process.stderr.write(` - ${r}\\n`);\n }\n log.step(`${numTurns} turns · ~$${costUsd.toFixed(3)}`);\n}\n\nfunction buildPrompt(ctx: PrContext, feedback: PrFeedback, instruction?: string): string {\n const reviewComments = feedback.reviewComments.length\n ? feedback.reviewComments\n .map((c) => ` - ${c.path}${c.line ? `:${c.line}` : \"\"} (${c.author}): ${c.body}`)\n .join(\"\\n\")\n : \" (none)\";\n const issueComments = feedback.issueComments.length\n ? feedback.issueComments.map((c) => ` - ${c.author}: ${c.body}`).join(\"\\n\")\n : \" (none)\";\n\n return [\n `Resolve the open items on this pull request by editing the code in the working directory.`,\n ``,\n `PR #${ctx.number}: ${ctx.title}`,\n `Base: ${ctx.baseRefName} Head: ${ctx.headRefName}`,\n ``,\n instruction\n ? `Primary instruction: ${instruction}`\n : `Primary goal: address the reviewer feedback below.`,\n ``,\n `Inline review comments:`,\n reviewComments,\n ``,\n `Conversation comments:`,\n issueComments,\n ``,\n `Method:`,\n `1. Understand each requested change. Use Read/Grep/Glob to locate the relevant code.`,\n `2. Make the minimal, correct edits with Edit/Write. Match existing conventions.`,\n `3. Run the project's tests and linters (via Bash) to verify your changes pass.`,\n `4. Do not weaken or delete tests to make them pass; do not introduce secrets.`,\n `5. Call submit_result once with a summary, the list of files changed, how you verified,`,\n ` and anything you could not resolve.`\n ].join(\"\\n\");\n}\n","import {\n cpSync,\n existsSync,\n mkdirSync,\n readFileSync,\n readdirSync,\n rmSync,\n statSync,\n writeFileSync\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport pc from \"picocolors\";\nimport { findBundledAssetsDir } from \"../core/assets.js\";\nimport { log } from \"../core/logger.js\";\n\nexport interface SkillsScope {\n cwd: string;\n /** Install for the whole user (~/.claude) instead of the current project. */\n global: boolean;\n}\n\nexport interface SkillsInstallOptions extends SkillsScope {\n force: boolean;\n}\n\n/** The skills this CLI manages (must match dir names under assets/skills). */\nconst MANAGED = [\"benchmark\", \"pr-review\", \"pr-resolve\"];\n\nfunction targetSkillsDir(scope: SkillsScope): string {\n return scope.global ? join(homedir(), \".claude\", \"skills\") : join(scope.cwd, \".claude\", \"skills\");\n}\n\nfunction sourceSkillsDir(): string {\n return join(findBundledAssetsDir(), \"skills\");\n}\n\n/**\n * Install the edsger skills into Claude Code so `/benchmark`, `/pr-review` and\n * `/pr-resolve` work — no plugin marketplace or paths required. The skill's\n * `${CLAUDE_PLUGIN_ROOT}` references are rewritten to the bundled assets dir.\n */\nexport async function runSkillsInstall(opts: SkillsInstallOptions): Promise<number> {\n const assetsDir = findBundledAssetsDir();\n const src = sourceSkillsDir();\n if (!existsSync(src)) {\n log.error(`Bundled skills not found at ${src}. Reinstall edsger.`);\n return 1;\n }\n const dest = targetSkillsDir(opts);\n mkdirSync(dest, { recursive: true });\n\n const available = readdirSync(src).filter((n) => existsSync(join(src, n, \"SKILL.md\")));\n let installed = 0;\n for (const name of available) {\n const outDir = join(dest, name);\n if (existsSync(outDir) && !opts.force) {\n log.warn(`skill \"${name}\" already exists — use --force to overwrite`);\n continue;\n }\n // Copy the whole skill dir (in case it grows auxiliary files), then rewrite\n // the SKILL.md plugin-root token to the absolute bundled assets path.\n rmSync(outDir, { recursive: true, force: true });\n cpSync(join(src, name), outDir, { recursive: true });\n const skillFile = join(outDir, \"SKILL.md\");\n const rewritten = readFileSync(skillFile, \"utf8\")\n .split(\"${CLAUDE_PLUGIN_ROOT}\")\n .join(assetsDir);\n writeFileSync(skillFile, rewritten, \"utf8\");\n installed++;\n log.success(`installed /${name}`);\n }\n\n if (installed === 0) {\n log.info(\"Nothing installed.\");\n return 0;\n }\n log.heading(`Installed ${installed} skill(s) into ${pc.bold(dest)}`);\n log.step(`scope: ${opts.global ? \"user (all projects)\" : \"this project\"}`);\n log.step(`standards: ${assetsDir}`);\n log.step(\"Open Claude Code and run /benchmark, /pr-review, or /pr-resolve.\");\n return 0;\n}\n\nexport async function runSkillsUninstall(opts: SkillsScope): Promise<number> {\n const dest = targetSkillsDir(opts);\n let removed = 0;\n for (const name of MANAGED) {\n const dir = join(dest, name);\n if (existsSync(dir)) {\n rmSync(dir, { recursive: true, force: true });\n removed++;\n log.success(`removed /${name}`);\n }\n }\n log.info(removed ? `Removed ${removed} skill(s) from ${dest}` : \"No edsger skills found.\");\n return 0;\n}\n\nexport async function runSkillsList(opts: SkillsScope): Promise<number> {\n for (const [label, scope] of [\n [\"user\", { ...opts, global: true }],\n [\"project\", { ...opts, global: false }]\n ] as const) {\n const dir = targetSkillsDir(scope);\n const present = MANAGED.filter((n) => {\n const p = join(dir, n, \"SKILL.md\");\n return existsSync(p) && statSync(p).isFile();\n });\n log.heading(`${label}: ${dir}`);\n if (present.length) for (const n of present) process.stderr.write(` ${pc.green(\"✓\")} /${n}\\n`);\n else process.stderr.write(` ${pc.dim(\"(none installed)\")}\\n`);\n }\n return 0;\n}\n"],"mappings":"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","names":["readFileSync","resolve","pc","join","pc","existsSync","join","join","existsSync","join","pc","pc","writeFileSync","join","pc","buildPrompt","execFile","promisify","pc","exec","promisify","execFile","pc","buildPrompt","printSummary","existsSync","mkdirSync","readFileSync","readdirSync","rmSync","statSync","writeFileSync","homedir","join","pc","join","homedir","existsSync","mkdirSync","readdirSync","rmSync","readFileSync","writeFileSync","pc","statSync","readFileSync","resolve","pc"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands/benchmark.ts","../src/core/assets.ts","../src/core/logger.ts","../src/util/yaml.ts","../src/core/config.ts","../src/core/agent.ts","../src/core/report.ts","../src/core/schema.ts","../src/commands/pr-review.ts","../src/core/gh.ts","../src/commands/pr-resolve.ts","../src/commands/skills.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { Command, Option } from \"commander\";\nimport pc from \"picocolors\";\nimport { runBenchmark } from \"./commands/benchmark.js\";\nimport { runPrReview } from \"./commands/pr-review.js\";\nimport { runPrResolve } from \"./commands/pr-resolve.js\";\nimport { runSkillsInstall, runSkillsList, runSkillsUninstall } from \"./commands/skills.js\";\nimport { log, setVerbose } from \"./core/logger.js\";\nimport type { GlobalOptions } from \"./types.js\";\n\n// Single source of truth: read the version from package.json at runtime.\n// dist/index.js sits one level below the package root, alongside which package.json ships.\nconst pkg = JSON.parse(readFileSync(new URL(\"../package.json\", import.meta.url), \"utf8\")) as {\n version: string;\n};\nconst VERSION = pkg.version;\nconst DEFAULT_MODEL = \"claude-sonnet-4-6\";\n\ninterface RawGlobal {\n cwd?: string;\n model?: string;\n standard?: string;\n assets?: string;\n lang?: string;\n json?: boolean;\n verbose?: boolean;\n dryRun?: boolean;\n maxTurns?: string;\n timeout?: string;\n}\n\nfunction toGlobal(raw: RawGlobal): GlobalOptions {\n setVerbose(Boolean(raw.verbose));\n return {\n cwd: resolve(raw.cwd ?? process.cwd()),\n model: raw.model ?? process.env.EDSGER_MODEL ?? DEFAULT_MODEL,\n standardPath: raw.standard,\n assetsPath: raw.assets,\n lang: raw.lang,\n json: Boolean(raw.json),\n verbose: Boolean(raw.verbose),\n dryRun: Boolean(raw.dryRun),\n // Unlimited by default — only cap turns / wall-clock when explicitly asked.\n maxTurns: raw.maxTurns ? Number.parseInt(raw.maxTurns, 10) : undefined,\n timeoutMs: raw.timeout ? Number.parseFloat(raw.timeout) * 60_000 : undefined\n };\n}\n\nfunction addGlobalOptions(cmd: Command): Command {\n return cmd\n .option(\"-C, --cwd <dir>\", \"directory of the repository to operate on\")\n .addOption(new Option(\"-m, --model <model>\", \"model id for the agent\").default(undefined))\n .option(\"--standard <path>\", \"path to a custom standards dir or file (overrides bundled)\")\n .option(\"--assets <path>\", \"override the entire assets root\")\n .option(\"--lang <id>\", \"force a language id, skipping detection\")\n .option(\"--max-turns <n>\", \"cap on agentic turns (default: unlimited)\")\n .option(\"--timeout <minutes>\", \"hard wall-clock limit per agent run (default: no limit)\")\n .option(\"--json\", \"print machine-readable JSON to stdout\")\n .option(\"-v, --verbose\", \"verbose logging\")\n .option(\"--dry-run\", \"run the agent but make no persistent/external changes\");\n}\n\nasync function guard(fn: () => Promise<number>): Promise<void> {\n try {\n const code = await fn();\n process.exitCode = code;\n } catch (err) {\n log.error(err instanceof Error ? err.message : String(err));\n if (process.env.EDSGER_DEBUG && err instanceof Error)\n process.stderr.write((err.stack ?? \"\") + \"\\n\");\n process.exitCode = 1;\n }\n}\n\nconst program = new Command();\nprogram\n .name(\"edsger\")\n .description(\n \"Agentic CLI to benchmark repositories and review/resolve pull requests\\n\" +\n \"against industrial-grade standards (from edsger-assets, fully overridable).\"\n )\n .version(VERSION, \"-V, --version\");\n\naddGlobalOptions(\n program\n .command(\"benchmark\")\n .description(\"Score a repository against a benchmark rubric and write a report\")\n .option(\"--out <dir>\", \"report output directory (relative to repo)\", \".edsger/benchmark\")\n .option(\"--no-write\", \"do not write report files into the repo\")\n).action(async (opts: RawGlobal & { out: string; write: boolean }) => {\n await guard(() =>\n runBenchmark({ ...toGlobal(opts), out: opts.out, noWrite: opts.write === false })\n );\n});\n\naddGlobalOptions(\n program\n .command(\"pr-review\")\n .description(\"Review a pull request against the review standard (requires gh)\")\n .argument(\"<pr>\", \"PR number, URL, or branch\")\n .option(\"--repo <owner/repo>\", \"target repository (defaults to current)\")\n .option(\"--post\", \"submit the review to GitHub (otherwise preview only)\")\n).action(async (pr: string, opts: RawGlobal & { repo?: string; post?: boolean }) => {\n await guard(() =>\n runPrReview({ ...toGlobal(opts), pr, repo: opts.repo, post: Boolean(opts.post) })\n );\n});\n\naddGlobalOptions(\n program\n .command(\"pr-resolve\")\n .description(\"Resolve review feedback / fix a pull request (requires gh)\")\n .argument(\"<pr>\", \"PR number, URL, or branch\")\n .option(\"--repo <owner/repo>\", \"target repository (defaults to current)\")\n .option(\"--instruction <text>\", \"what to do (defaults to addressing review comments)\")\n .option(\"--no-checkout\", \"do not check out the PR branch first\")\n .option(\"--push\", \"commit and push the changes when done\")\n).action(\n async (\n pr: string,\n opts: RawGlobal & { repo?: string; instruction?: string; checkout: boolean; push?: boolean }\n ) => {\n await guard(() =>\n runPrResolve({\n ...toGlobal(opts),\n pr,\n repo: opts.repo,\n instruction: opts.instruction,\n checkout: opts.checkout !== false,\n push: Boolean(opts.push)\n })\n );\n }\n);\n\n// `edsger skills ...` — install the skills into Claude Code with no paths needed.\nconst skills = program\n .command(\"skills\")\n .description(\"install edsger as Claude Code skills (/benchmark, /pr-review, /pr-resolve)\");\n\nskills\n .command(\"install\")\n .description(\"install the skills into Claude Code\")\n .option(\"--global\", \"install for the current user (~/.claude/skills) [default]\")\n .option(\"--project\", \"install into ./.claude/skills instead\")\n .option(\"-C, --cwd <dir>\", \"project directory (with --project)\")\n .option(\"--force\", \"overwrite existing skills\")\n .action(async (opts: { global?: boolean; project?: boolean; cwd?: string; force?: boolean }) => {\n await guard(() =>\n runSkillsInstall({\n cwd: resolve(opts.cwd ?? process.cwd()),\n global: opts.project ? false : true,\n force: Boolean(opts.force)\n })\n );\n });\n\nskills\n .command(\"uninstall\")\n .description(\"remove the edsger skills from Claude Code\")\n .option(\"--global\", \"remove from the user scope (~/.claude/skills) [default]\")\n .option(\"--project\", \"remove from ./.claude/skills instead\")\n .option(\"-C, --cwd <dir>\", \"project directory (with --project)\")\n .action(async (opts: { global?: boolean; project?: boolean; cwd?: string }) => {\n await guard(() =>\n runSkillsUninstall({\n cwd: resolve(opts.cwd ?? process.cwd()),\n global: opts.project ? false : true\n })\n );\n });\n\nskills\n .command(\"list\")\n .description(\"show which edsger skills are installed\")\n .option(\"-C, --cwd <dir>\", \"project directory\")\n .action(async (opts: { cwd?: string }) => {\n await guard(() => runSkillsList({ cwd: resolve(opts.cwd ?? process.cwd()), global: true }));\n });\n\nprogram.addHelpText(\n \"after\",\n `\\nExamples:\\n` +\n ` ${pc.dim(\"$\")} edsger benchmark\\n` +\n ` ${pc.dim(\"$\")} edsger benchmark -C ./my-repo --json\\n` +\n ` ${pc.dim(\"$\")} edsger pr-review 123 --post\\n` +\n ` ${pc.dim(\"$\")} edsger pr-resolve 123 --instruction \"fix the failing test\" --push\\n` +\n ` ${pc.dim(\"$\")} edsger skills install ${pc.dim(\"# enable /benchmark etc. in Claude Code\")}\\n` +\n `\\nAuth: the agent uses your Claude Code login (run \\`claude\\` once to sign in); ` +\n `run \\`gh auth login\\` for PR commands.\\n`\n);\n\nprogram.parseAsync(process.argv);\n","import { mkdirSync, writeFileSync } from \"node:fs\";\nimport { basename, join } from \"node:path\";\nimport pc from \"picocolors\";\nimport { resolveStandard } from \"../core/assets.js\";\nimport { loadConfig } from \"../core/config.js\";\nimport { runAgent } from \"../core/agent.js\";\nimport { log } from \"../core/logger.js\";\nimport { renderBenchmarkMarkdown, scoreBenchmark, type ScoredBenchmark } from \"../core/report.js\";\nimport { BenchmarkResultSchema } from \"../core/schema.js\";\nimport type { BenchmarkStandard, GlobalOptions } from \"../types.js\";\n\nexport interface BenchmarkOptions extends GlobalOptions {\n /** Directory to write the report into (relative to repo). */\n out: string;\n /** Skip writing files into the repo. */\n noWrite: boolean;\n}\n\nexport async function runBenchmark(opts: BenchmarkOptions): Promise<number> {\n const { config, path: configPath } = loadConfig(opts.cwd);\n const configDir = configPath ? join(configPath, \"..\") : opts.cwd;\n const resolved = resolveStandard(\"benchmark\", opts, config, configDir);\n const standard = resolved.standard as BenchmarkStandard;\n\n log.info(\n `Benchmarking ${pc.bold(basename(opts.cwd))} against ${pc.bold(standard.name)} ` +\n `(languages: ${resolved.languages.join(\", \") || \"generic\"})`\n );\n log.debug(`standard layers: ${resolved.layers.join(\" → \")}`);\n\n const prompt = buildPrompt(standard, opts.cwd);\n const { result, costUsd, numTurns } = await runAgent({\n prompt,\n cwd: opts.cwd,\n model: opts.model,\n maxTurns: opts.maxTurns,\n timeoutMs: opts.timeoutMs,\n allowWrite: false,\n verbose: opts.verbose,\n resultShape: BenchmarkResultSchema.shape,\n systemPromptAppend:\n \"You are Edsger, a meticulous staff-level engineer performing an objective \" +\n \"repository assessment. Inspect the actual code and configuration before scoring. \" +\n \"Be evidence-driven and fair; cite concrete files. Do not modify any files.\"\n });\n\n if (!result) {\n log.error(\n \"The agent did not produce a result. Try increasing --max-turns or check credentials.\"\n );\n return 1;\n }\n\n const scored = scoreBenchmark(standard, result);\n const generatedAt = new Date().toISOString();\n // Filesystem-safe UTC run id (e.g. 20260701T034500Z): lexicographic order == chronological.\n const runId = generatedAt.replace(/[-:]/g, \"\").replace(/\\.\\d+Z$/, \"Z\");\n const md = renderBenchmarkMarkdown(scored, {\n repo: basename(opts.cwd),\n languages: resolved.languages,\n layers: resolved.layers,\n generatedAt,\n model: opts.model\n });\n\n const jsonReport = {\n schema: \"edsger.benchmark/1\",\n runId,\n generatedAt,\n model: opts.model,\n repo: basename(opts.cwd),\n languages: resolved.languages,\n standard: { name: standard.name, version: standard.version, layers: resolved.layers },\n overall: scored.overall,\n grade: scored.grade,\n categories: scored.categories,\n summary: scored.summary,\n strengths: scored.strengths,\n weaknesses: scored.weaknesses,\n recommendations: scored.recommendations,\n costUsd\n };\n\n if (!opts.noWrite && !opts.dryRun) {\n const baseDir = join(opts.cwd, opts.out);\n const mdOut = md + \"\\n\";\n const jsonOut = JSON.stringify(jsonReport, null, 2) + \"\\n\";\n\n // Archive this run under runs/<timestamp>/ so history from repeated runs is preserved.\n const runDir = join(baseDir, \"runs\", runId);\n mkdirSync(runDir, { recursive: true });\n writeFileSync(join(runDir, \"report.md\"), mdOut, \"utf8\");\n writeFileSync(join(runDir, \"report.json\"), jsonOut, \"utf8\");\n\n // Always refresh the canonical top-level report as the stable \"latest\" pointer\n // (unchanged path, so CI / diffs keep working).\n writeFileSync(join(baseDir, \"report.md\"), mdOut, \"utf8\");\n writeFileSync(join(baseDir, \"report.json\"), jsonOut, \"utf8\");\n\n log.success(\n `Report written to ${pc.bold(join(opts.out, \"report.md\"))} ` +\n `${pc.dim(`(run archived at ${join(opts.out, \"runs\", runId)})`)}`\n );\n }\n\n printSummary(scored, numTurns, costUsd);\n if (opts.json) process.stdout.write(JSON.stringify(jsonReport, null, 2) + \"\\n\");\n return 0;\n}\n\nfunction printSummary(scored: ScoredBenchmark, numTurns: number, costUsd: number): void {\n log.heading(`Score: ${scored.overall}/100 (Grade ${scored.grade})`);\n for (const c of scored.categories) {\n const pct = Math.round(c.fraction * 100);\n process.stderr.write(` ${bar(pct)} ${String(pct).padStart(3)}% ${c.name}\\n`);\n }\n log.step(`${numTurns} turns · ~$${costUsd.toFixed(3)}`);\n}\n\nfunction bar(pct: number): string {\n const width = 20;\n const filled = Math.round((pct / 100) * width);\n const color = pct >= 80 ? pc.green : pct >= 60 ? pc.yellow : pc.red;\n return color(\"█\".repeat(filled)) + pc.dim(\"░\".repeat(width - filled));\n}\n\nfunction buildPrompt(standard: BenchmarkStandard, cwd: string): string {\n const rubric = standard.categories\n .map((cat) => {\n const crits = cat.criteria\n .map((cr) => {\n const anchors = cr.rubric\n ? Object.entries(cr.rubric)\n .map(([k, v]) => ` - ${k}: ${v}`)\n .join(\"\\n\")\n : \"\";\n return (\n ` - id: ${cat.id}/${cr.id}\\n` +\n ` title: ${cr.title}\\n` +\n ` guidance: ${cr.guidance.trim()}` +\n (anchors ? `\\n anchors:\\n${anchors}` : \"\")\n );\n })\n .join(\"\\n\");\n return `- category: ${cat.id} (${cat.name}, weight ${cat.weight})\\n${crits}`;\n })\n .join(\"\\n\");\n\n return [\n `Assess the repository located at: ${cwd}`,\n ``,\n `Score it against the rubric below. Each criterion is scored from 0 to ${standard.scoreScale}`,\n `(0 = absent/harmful, ${standard.scoreScale} = exemplary), using the level anchors as a guide.`,\n ``,\n `Method:`,\n `1. Explore the repository structure, key source files, configuration, CI, tests, and docs.`,\n ` Use Read/Grep/Glob and read-only Bash (e.g. ls, cat, git log). Do NOT modify anything.`,\n `2. For each criterion, gather concrete evidence (file paths) before deciding a score.`,\n `3. Be objective and consistent. Absence of evidence for a practice means a low score.`,\n `4. When finished, call submit_result exactly once with a score for EVERY criterion id below,`,\n ` grouped by category. Include a short justification and evidence paths for each.`,\n ``,\n `Rubric:`,\n rubric\n ].join(\"\\n\");\n}\n","import { execFileSync } from \"node:child_process\";\nimport { existsSync, readdirSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, isAbsolute, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type {\n BenchmarkStandard,\n Category,\n Criterion,\n FocusArea,\n GlobalOptions,\n ResolvedStandard,\n ReviewStandard,\n Standard,\n StandardKind\n} from \"../types.js\";\nimport { log } from \"./logger.js\";\nimport { loadStructured } from \"../util/yaml.js\";\nimport type { EdsgerConfig } from \"./config.js\";\n\nconst moduleDir = dirname(fileURLToPath(import.meta.url));\n\n/** Walk upward from the running module to find the bundled `assets/` dir. */\nexport function findBundledAssetsDir(): string {\n if (process.env.EDSGER_ASSETS_DIR && existsSync(process.env.EDSGER_ASSETS_DIR)) {\n return process.env.EDSGER_ASSETS_DIR;\n }\n let dir = moduleDir;\n for (let i = 0; i < 8; i++) {\n const candidate = join(dir, \"assets\");\n if (existsSync(join(candidate, \"manifest.yaml\"))) return candidate;\n // Also allow running directly against an edsger-assets checkout layout.\n if (existsSync(join(dir, \"manifest.yaml\")) && existsSync(join(dir, \"benchmark\"))) {\n return dir;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n throw new Error(\"Could not locate bundled assets. Reinstall edsger or set EDSGER_ASSETS_DIR.\");\n}\n\ninterface LanguageDetector {\n id: string;\n markers: string[];\n extensions: string[];\n}\n\ninterface LanguagesConfig {\n minScore: number;\n maxExtensionMatches: number;\n languages: LanguageDetector[];\n}\n\nfunction loadLangConfig(assetsRoot: string): LanguagesConfig | null {\n const cfgPath = join(assetsRoot, \"languages.yaml\");\n if (!existsSync(cfgPath)) return null;\n return loadStructured<LanguagesConfig>(cfgPath);\n}\n\n/** Score languages from a set of file/dir names against the detector config. */\nfunction scoreLanguages(names: string[], cfg: LanguagesConfig, minScore: number): string[] {\n const exts = new Set(names.map(extOf));\n const scored: { id: string; score: number }[] = [];\n for (const lang of cfg.languages) {\n let score = 0;\n for (const m of lang.markers) {\n if (m.includes(\"*\")) {\n const re = globToRegExp(m);\n if (names.some((f) => re.test(f))) score += 3;\n } else if (names.includes(m)) {\n score += 3;\n }\n }\n let extHits = 0;\n for (const e of lang.extensions) if (exts.has(e)) extHits++;\n score += Math.min(extHits, cfg.maxExtensionMatches);\n if (score >= minScore) scored.push({ id: lang.id, score });\n }\n return scored.sort((a, b) => b.score - a.score).map((s) => s.id);\n}\n\n/** Detect which languages a repository uses, ordered by confidence. */\nexport function detectLanguages(cwd: string, assetsRoot: string): string[] {\n const cfg = loadLangConfig(assetsRoot);\n if (!cfg) return [];\n const names = readShallowTree(cwd, 3).map((e) => e.name);\n return scoreLanguages(names, cfg, cfg.minScore);\n}\n\n/**\n * Infer languages from a list of file paths (e.g. a PR's changed files) when a\n * working-directory scan is unavailable or empty. Uses a low threshold since\n * this is a best-effort hint.\n */\nexport function inferLanguagesFromFiles(\n paths: string[],\n assetsRoot: string,\n minScore = 1\n): string[] {\n const cfg = loadLangConfig(assetsRoot);\n if (!cfg) return [];\n const names = paths.flatMap((p) => [p, p.split(\"/\").pop() ?? p]);\n return scoreLanguages(names, cfg, minScore);\n}\n\n/** Resolve the effective standard for a kind via the full override chain. */\nexport function resolveStandard(\n kind: StandardKind,\n opts: GlobalOptions,\n config: EdsgerConfig,\n configDir: string,\n /** Fallback languages used only when a working-dir scan finds nothing. */\n forcedLanguages?: string[]\n): ResolvedStandard {\n const bundled = opts.assetsPath\n ? resolveRootPath(opts.assetsPath, opts.cwd)\n : findBundledAssetsDir();\n\n const languages = opts.lang\n ? [normaliseLang(opts.lang)]\n : config.language\n ? [normaliseLang(config.language)]\n : pickDetected(detectLanguages(opts.cwd, bundled), forcedLanguages);\n\n // Ordered roots: bundled first (lowest precedence), then configured overrides.\n const roots: { path: string; label: string }[] = [\n { path: bundled, label: opts.assetsPath ? `assets:${opts.assetsPath}` : \"bundled\" }\n ];\n const overrideSpec =\n (kind === \"benchmark\" ? config.benchmark?.standards : config.review?.standards) ??\n config.standards;\n if (overrideSpec && !opts.assetsPath) {\n roots.push({ path: resolveRootPath(overrideSpec, configDir), label: `config:${overrideSpec}` });\n }\n\n const layers: { data: Partial<Standard>; label: string }[] = [];\n\n // 1. base + language overlays from each root.\n for (const root of roots) {\n pushIfExists(layers, join(root.path, kind, \"base.yaml\"), `${root.label}/base`);\n for (const lang of languages) {\n pushIfExists(layers, join(root.path, kind, `${lang}.yaml`), `${root.label}/${lang}`);\n }\n }\n\n // 2. repo-local .edsger/<kind>/ overlays (highest-but-one precedence).\n const repoLocal = join(opts.cwd, \".edsger\", kind);\n if (existsSync(repoLocal)) {\n pushIfExists(layers, join(repoLocal, \"base.yaml\"), `repo:.edsger/${kind}/base`);\n for (const lang of languages) {\n pushIfExists(layers, join(repoLocal, `${lang}.yaml`), `repo:.edsger/${kind}/${lang}`);\n }\n }\n\n // 3. explicit --standard path (highest precedence).\n if (opts.standardPath) {\n const p = resolveRootPath(opts.standardPath, opts.cwd);\n if (existsSync(p) && statSync(p).isDirectory()) {\n pushIfExists(layers, join(p, kind, \"base.yaml\"), `--standard/base`);\n for (const lang of languages) {\n pushIfExists(layers, join(p, kind, `${lang}.yaml`), `--standard/${lang}`);\n }\n pushIfExists(layers, join(p, \"base.yaml\"), `--standard/base`);\n } else if (existsSync(p)) {\n pushIfExists(layers, p, `--standard:${opts.standardPath}`);\n } else {\n throw new Error(`--standard path not found: ${p}`);\n }\n }\n\n if (layers.length === 0) {\n throw new Error(`No ${kind} standard found in any source.`);\n }\n\n const merged = mergeLayers(\n kind,\n layers.map((l) => l.data)\n );\n return { standard: merged, layers: layers.map((l) => l.label), languages };\n}\n\n// --- merging -----------------------------------------------------------------\n\nfunction mergeLayers(kind: StandardKind, layers: Partial<Standard>[]): Standard {\n if (kind === \"benchmark\") {\n return layers.reduce(\n (acc, layer) =>\n mergeBenchmark(acc as Partial<BenchmarkStandard>, layer as Partial<BenchmarkStandard>),\n {} as Partial<BenchmarkStandard>\n ) as BenchmarkStandard;\n }\n return layers.reduce(\n (acc, layer) => mergeReview(acc as Partial<ReviewStandard>, layer as Partial<ReviewStandard>),\n {} as Partial<ReviewStandard>\n ) as ReviewStandard;\n}\n\nfunction mergeBenchmark(\n base: Partial<BenchmarkStandard>,\n overlay: Partial<BenchmarkStandard>\n): Partial<BenchmarkStandard> {\n const categories = mergeById<Category>(\n base.categories ?? [],\n overlay.categories ?? [],\n (b, o) => ({\n ...b,\n ...o,\n criteria: mergeById<Criterion>(b.criteria ?? [], o.criteria ?? [], (bc, oc) => ({\n ...bc,\n ...oc\n }))\n })\n );\n return {\n ...base,\n ...overlay,\n // Preserve the base layer's identity rather than the last overlay's.\n id: base.id ?? overlay.id,\n name: base.name ?? overlay.name,\n version: base.version ?? overlay.version,\n kind: \"benchmark\",\n scoreScale: overlay.scoreScale ?? base.scoreScale ?? 4,\n categories\n };\n}\n\nfunction mergeReview(\n base: Partial<ReviewStandard>,\n overlay: Partial<ReviewStandard>\n): Partial<ReviewStandard> {\n const focusAreas = mergeById<FocusArea>(\n base.focusAreas ?? [],\n overlay.focusAreas ?? [],\n (b, o) => ({\n ...b,\n ...o\n })\n );\n return {\n ...base,\n ...overlay,\n id: base.id ?? overlay.id,\n name: base.name ?? overlay.name,\n version: base.version ?? overlay.version,\n kind: \"review\",\n policy: { ...(base.policy ?? {}), ...(overlay.policy ?? {}) } as ReviewStandard[\"policy\"],\n focusAreas\n };\n}\n\nfunction mergeById<T extends { id: string }>(\n base: T[],\n overlay: T[],\n merge: (b: T, o: T) => T\n): T[] {\n const out: T[] = base.map((x) => ({ ...x }));\n const index = new Map(out.map((x, i) => [x.id, i]));\n for (const item of overlay) {\n const at = index.get(item.id);\n if (at === undefined) {\n index.set(item.id, out.length);\n out.push({ ...item });\n } else {\n out[at] = merge(out[at] as T, item);\n }\n }\n return out;\n}\n\n// --- helpers -----------------------------------------------------------------\n\nfunction pushIfExists(\n layers: { data: Partial<Standard>; label: string }[],\n path: string,\n label: string\n): void {\n if (existsSync(path)) {\n layers.push({ data: loadStructured<Partial<Standard>>(path), label });\n log.debug(`standard layer: ${label} (${path})`);\n }\n}\n\nfunction resolveRootPath(spec: string, baseDir: string): string {\n if (spec.startsWith(\"git+\") || /^(https?|git|ssh):\\/\\//.test(spec)) {\n return cloneToCache(spec.replace(/^git\\+/, \"\"));\n }\n return isAbsolute(spec) ? spec : resolve(baseDir, spec);\n}\n\n/** Clone (or reuse a cached clone of) a git standards repo. */\nfunction cloneToCache(url: string): string {\n const [repo, ref] = url.split(\"#\") as [string, string | undefined];\n const safe = repo.replace(/[^a-zA-Z0-9._-]/g, \"_\");\n const dest = join(homedir(), \".cache\", \"edsger\", \"standards\", safe);\n if (!existsSync(dest)) {\n log.step(`cloning standards repo ${repo}`);\n execFileSync(\"git\", [\"clone\", \"--depth\", \"1\", ...(ref ? [\"--branch\", ref] : []), repo, dest], {\n stdio: \"ignore\"\n });\n }\n return dest;\n}\n\ninterface Entry {\n name: string;\n}\n\n/** Read top file/dir names up to `depth` levels, skipping noise dirs. */\nfunction readShallowTree(root: string, depth: number): Entry[] {\n const skip = new Set([\n \"node_modules\",\n \".git\",\n \"dist\",\n \"build\",\n \"out\",\n \"target\",\n \"vendor\",\n \".venv\",\n \"venv\",\n \"__pycache__\",\n \".dart_tool\"\n ]);\n const out: Entry[] = [];\n const walk = (dir: string, level: number): void => {\n let items: string[];\n try {\n items = readdirSync(dir);\n } catch {\n return;\n }\n for (const name of items) {\n if (skip.has(name)) continue;\n out.push({ name });\n if (level < depth) {\n const full = join(dir, name);\n try {\n if (statSync(full).isDirectory()) walk(full, level + 1);\n } catch {\n /* ignore unreadable entries */\n }\n }\n }\n };\n walk(root, 1);\n return out;\n}\n\nfunction extOf(name: string): string {\n const i = name.lastIndexOf(\".\");\n return i < 0 ? \"\" : name.slice(i);\n}\n\nfunction globToRegExp(glob: string): RegExp {\n const escaped = glob.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\").replace(/\\*/g, \".*\");\n return new RegExp(`^${escaped}$`);\n}\n\nfunction pickDetected(detected: string[], fallback?: string[]): string[] {\n return detected.length ? detected : (fallback ?? []);\n}\n\n/** Map a user-supplied language alias to a canonical id (best effort). */\nfunction normaliseLang(input: string): string {\n const v = input.trim().toLowerCase();\n const aliases: Record<string, string> = {\n ts: \"typescript\",\n js: \"typescript\",\n javascript: \"typescript\",\n node: \"typescript\",\n nodejs: \"typescript\",\n py: \"python\",\n golang: \"go\",\n cs: \"csharp\",\n \"c#\": \"csharp\",\n dotnet: \"csharp\",\n jvm: \"java\",\n kotlin: \"java\",\n flutter: \"dart\"\n };\n return aliases[v] ?? v;\n}\n","import pc from \"picocolors\";\n\nlet verbose = false;\n\nexport function setVerbose(v: boolean): void {\n verbose = v;\n}\n\nexport const log = {\n info(msg: string): void {\n process.stderr.write(`${pc.cyan(\"•\")} ${msg}\\n`);\n },\n success(msg: string): void {\n process.stderr.write(`${pc.green(\"✓\")} ${msg}\\n`);\n },\n warn(msg: string): void {\n process.stderr.write(`${pc.yellow(\"!\")} ${msg}\\n`);\n },\n error(msg: string): void {\n process.stderr.write(`${pc.red(\"✗\")} ${msg}\\n`);\n },\n step(msg: string): void {\n process.stderr.write(`${pc.dim(\" →\")} ${pc.dim(msg)}\\n`);\n },\n debug(msg: string): void {\n if (verbose) process.stderr.write(`${pc.dim(` ${msg}`)}\\n`);\n },\n /** Print a heading to stderr so structured stdout stays clean. */\n heading(msg: string): void {\n process.stderr.write(`\\n${pc.bold(msg)}\\n`);\n }\n};\n","import { readFileSync } from \"node:fs\";\nimport yaml from \"js-yaml\";\n\n/** Parse a YAML or JSON file into a plain object. */\nexport function loadStructured<T = unknown>(path: string): T {\n const raw = readFileSync(path, \"utf8\");\n return yaml.load(raw) as T;\n}\n\n/** Parse a YAML or JSON string. */\nexport function parseStructured<T = unknown>(raw: string): T {\n return yaml.load(raw) as T;\n}\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { loadStructured } from \"../util/yaml.js\";\n\n/**\n * User configuration, discovered from the target repository or home dir.\n * Everything is optional — zero config falls back to bundled assets.\n */\nexport interface EdsgerConfig {\n /** Default model for agent runs. */\n model?: string;\n /**\n * Override the standards source. Either:\n * - a local path (absolute, or relative to the config file), or\n * - a git URL (clone + cache) — supported via the `git+` prefix.\n */\n standards?: string;\n /** Force a language id, skipping auto-detection. */\n language?: string;\n /** Per-kind overrides, e.g. { benchmark: \"./team-standards\" }. */\n benchmark?: { standards?: string };\n review?: { standards?: string };\n}\n\nconst CONFIG_FILENAMES = [\n \"edsger.config.yaml\",\n \"edsger.config.yml\",\n \"edsger.config.json\",\n \".edsgerrc.yaml\",\n \".edsgerrc.yml\",\n \".edsgerrc.json\",\n \".edsgerrc\"\n];\n\n/** Find and load an edsger config file from `cwd`, then `.edsger/`. */\nexport function loadConfig(cwd: string): { config: EdsgerConfig; path?: string } {\n const searchDirs = [cwd, join(cwd, \".edsger\")];\n for (const dir of searchDirs) {\n for (const name of CONFIG_FILENAMES) {\n const p = join(dir, name);\n if (existsSync(p)) {\n try {\n const config = loadStructured<EdsgerConfig>(p) ?? {};\n return { config, path: p };\n } catch {\n // Malformed config should not crash discovery; ignore and continue.\n }\n }\n }\n }\n return { config: {} };\n}\n","import {\n createSdkMcpServer,\n query,\n tool,\n type McpServerConfig\n} from \"@anthropic-ai/claude-agent-sdk\";\nimport type { ZodRawShape } from \"zod\";\nimport { z } from \"zod\";\nimport pc from \"picocolors\";\nimport { log } from \"./logger.js\";\n\nexport interface AgentRunOptions<Shape extends ZodRawShape> {\n /** The instruction given to the agent. */\n prompt: string;\n /** Working directory the agent operates in. */\n cwd: string;\n model: string;\n /** Cap on agentic turns; undefined = unlimited. */\n maxTurns?: number;\n /** Whether the agent may modify files (Edit/Write) and run mutating commands. */\n allowWrite: boolean;\n /** Appended to the Claude Code system prompt preset. */\n systemPromptAppend: string;\n /**\n * Zod shape describing the structured result. The agent is required to call a\n * `submit_result` tool with this shape exactly once; its validated args are\n * returned. This is the reliable way to get machine-readable output.\n */\n resultShape: Shape;\n /** Extra MCP servers (e.g. github) to expose to the agent. */\n extraMcpServers?: Record<string, McpServerConfig>;\n /** Extra tool names to allow (e.g. \"mcp__github__*\"). */\n extraAllowedTools?: string[];\n /** Hard wall-clock limit; the run is aborted if it exceeds this. */\n timeoutMs?: number;\n verbose: boolean;\n}\n\nexport interface AgentRunResult<T> {\n result: T | undefined;\n costUsd: number;\n numTurns: number;\n}\n\nconst READ_ONLY_DISALLOWED = [\"Edit\", \"Write\", \"NotebookEdit\"];\n\n/**\n * Run an agentic loop with the Claude Agent SDK and collect a structured\n * result. Read-only runs have edit tools removed from the agent's context.\n */\nexport async function runAgent<Shape extends ZodRawShape>(\n opts: AgentRunOptions<Shape>\n): Promise<AgentRunResult<z.infer<z.ZodObject<Shape>>>> {\n type Result = z.infer<z.ZodObject<Shape>>;\n let captured: Result | undefined;\n\n const submitTool = tool(\n \"submit_result\",\n \"Submit the final structured result. Call this exactly once when done.\",\n opts.resultShape,\n async (args) => {\n captured = args as Result;\n return { content: [{ type: \"text\", text: \"Result recorded. You may stop now.\" }] };\n }\n );\n\n const outServer = createSdkMcpServer({\n name: \"edsger_out\",\n version: \"1.0.0\",\n tools: [submitTool]\n });\n\n const allowedTools = [\n \"Read\",\n \"Grep\",\n \"Glob\",\n \"Bash\",\n \"mcp__edsger_out__submit_result\",\n ...(opts.allowWrite ? [\"Edit\", \"Write\", \"MultiEdit\"] : []),\n ...(opts.extraAllowedTools ?? [])\n ];\n\n const mcpServers: Record<string, McpServerConfig> = {\n edsger_out: outServer,\n ...(opts.extraMcpServers ?? {})\n };\n\n let costUsd = 0;\n let numTurns = 0;\n\n // Enforce a wall-clock limit so a stuck run cannot hang a CI job.\n const controller = new AbortController();\n const timer = opts.timeoutMs ? setTimeout(() => controller.abort(), opts.timeoutMs) : undefined;\n\n const stream = query({\n prompt: opts.prompt,\n options: {\n model: opts.model,\n cwd: opts.cwd,\n // Only impose a turn cap when the user explicitly set one; otherwise let the\n // agent run to completion (no max-turns stop).\n ...(opts.maxTurns ? { maxTurns: opts.maxTurns } : {}),\n // Reproducible runs: do not load the target repo's settings/CLAUDE.md.\n settingSources: [],\n systemPrompt: {\n type: \"preset\",\n preset: \"claude_code\",\n append: opts.systemPromptAppend\n },\n // The user explicitly invoked an agent to inspect/modify their own repo.\n // Capability is shaped by allowedTools/disallowedTools rather than prompts:\n // read-only runs have edit tools removed from context entirely (below).\n permissionMode: \"bypassPermissions\",\n allowedTools,\n disallowedTools: opts.allowWrite ? [] : READ_ONLY_DISALLOWED,\n mcpServers,\n abortController: controller\n }\n });\n\n let turn = 0;\n try {\n for await (const message of stream as AsyncIterable<AnyMessage>) {\n if (message.type === \"assistant\") {\n turn += 1;\n for (const block of message.message?.content ?? []) {\n if (block.type === \"tool_use\") {\n // Visible by default so a long run shows live progress, not a frozen screen.\n const counter = opts.maxTurns ? `${turn}/${opts.maxTurns}` : `${turn}`;\n log.step(`[${counter}] ${summarizeTool(block.name, block.input)}`);\n } else if (block.type === \"text\" && opts.verbose && block.text?.trim()) {\n // The agent's reasoning — only in verbose mode, and only the first few lines.\n for (const line of block.text.trim().split(\"\\n\").slice(0, 4)) {\n if (line.trim()) log.debug(line.trim());\n }\n }\n }\n } else if (message.type === \"result\") {\n costUsd = message.total_cost_usd ?? 0;\n numTurns = message.num_turns ?? 0;\n if (message.subtype && message.subtype !== \"success\") {\n log.warn(`agent ended with: ${message.subtype}`);\n }\n }\n }\n } catch (err) {\n if (controller.signal.aborted) {\n throw new Error(`Agent run timed out after ${Math.round((opts.timeoutMs ?? 0) / 1000)}s.`);\n }\n throw err;\n } finally {\n if (timer) clearTimeout(timer);\n }\n\n return { result: captured, costUsd, numTurns };\n}\n\n// Minimal structural typing over the SDK message union so we are resilient to\n// version drift in exported type names.\ninterface AnyMessage {\n type: string;\n subtype?: string;\n total_cost_usd?: number;\n num_turns?: number;\n message?: {\n content?: Array<{\n type: string;\n name?: string;\n text?: string;\n input?: Record<string, unknown>;\n }>;\n };\n}\n\n/** One-line, human-readable summary of a tool call for progress output. */\nfunction summarizeTool(name = \"tool\", input: Record<string, unknown> = {}): string {\n const str = (v: unknown): string => (typeof v === \"string\" ? v : \"\");\n const oneLine = (v: string, max = 80): string => {\n const s = v.replace(/\\s+/g, \" \").trim();\n return s.length > max ? s.slice(0, max - 1) + \"…\" : s;\n };\n const base = (p: string): string => p.split(\"/\").filter(Boolean).pop() ?? p;\n\n switch (name) {\n case \"Read\":\n case \"Edit\":\n case \"Write\":\n case \"MultiEdit\":\n case \"NotebookEdit\":\n return `${name} ${base(str(input.file_path))}`;\n case \"Bash\": {\n const cmd = oneLine(str(input.command));\n return `Bash ${cmd ? pc.dim(`$ ${cmd}`) : \"\"}`.trimEnd();\n }\n case \"Grep\": {\n const where = str(input.path) || str(input.glob);\n return `Grep /${oneLine(str(input.pattern), 40)}/${where ? ` in ${base(where)}` : \"\"}`;\n }\n case \"Glob\":\n return `Glob ${oneLine(str(input.pattern), 60)}`;\n case \"mcp__edsger_out__submit_result\":\n return \"recording result\";\n default:\n return name;\n }\n}\n","import type { BenchmarkStandard, Category, Criterion } from \"../types.js\";\nimport type { BenchmarkResult } from \"./schema.js\";\n\nexport interface ScoredCriterion {\n id: string;\n title: string;\n weight: number;\n rawScore: number;\n maxScore: number;\n fraction: number;\n justification: string;\n evidence: string[];\n}\n\nexport interface ScoredCategory {\n id: string;\n name: string;\n weight: number; // normalised to sum 100 across categories\n fraction: number; // 0..1\n points: number; // weight * fraction\n criteria: ScoredCriterion[];\n}\n\nexport interface ScoredBenchmark {\n standardName: string;\n standardVersion: string;\n overall: number; // 0..100\n grade: string;\n categories: ScoredCategory[];\n summary: string;\n strengths: string[];\n weaknesses: string[];\n recommendations: BenchmarkResult[\"recommendations\"];\n}\n\n/** Deterministically aggregate the agent's per-criterion scores. */\nexport function scoreBenchmark(\n standard: BenchmarkStandard,\n result: BenchmarkResult\n): ScoredBenchmark {\n const scale = standard.scoreScale || 4;\n const totalWeight = standard.categories.reduce((s, c) => s + c.weight, 0) || 1;\n const scoreLookup = new Map<string, number>();\n for (const cat of result.categories) {\n for (const cr of cat.criteria) scoreLookup.set(`${cat.id}/${cr.id}`, cr.score);\n }\n const justifyLookup = new Map<string, { justification: string; evidence: string[] }>();\n for (const cat of result.categories) {\n for (const cr of cat.criteria) {\n justifyLookup.set(`${cat.id}/${cr.id}`, {\n justification: cr.justification,\n evidence: cr.evidence ?? []\n });\n }\n }\n\n const categories: ScoredCategory[] = standard.categories.map((cat: Category) => {\n const critWeightTotal = cat.criteria.reduce((s, c) => s + (c.weight ?? 1), 0) || 1;\n const scored: ScoredCriterion[] = cat.criteria.map((cr: Criterion) => {\n const raw = clamp(scoreLookup.get(`${cat.id}/${cr.id}`) ?? 0, 0, scale);\n const meta = justifyLookup.get(`${cat.id}/${cr.id}`);\n return {\n id: cr.id,\n title: cr.title,\n weight: cr.weight ?? 1,\n rawScore: raw,\n maxScore: scale,\n fraction: raw / scale,\n justification: meta?.justification ?? \"Not assessed.\",\n evidence: meta?.evidence ?? []\n };\n });\n const fraction = scored.reduce((s, c) => s + c.fraction * c.weight, 0) / critWeightTotal;\n const normWeight = (cat.weight / totalWeight) * 100;\n return {\n id: cat.id,\n name: cat.name,\n weight: round(normWeight, 1),\n fraction,\n points: round(normWeight * fraction, 1),\n criteria: scored\n };\n });\n\n const overall = round(\n categories.reduce((s, c) => s + c.points, 0),\n 1\n );\n\n return {\n standardName: standard.name,\n standardVersion: standard.version,\n overall,\n grade: gradeFor(overall),\n categories,\n summary: result.summary,\n strengths: result.strengths ?? [],\n weaknesses: result.weaknesses ?? [],\n recommendations: result.recommendations ?? []\n };\n}\n\nexport function gradeFor(score: number): string {\n if (score >= 90) return \"A\";\n if (score >= 80) return \"B\";\n if (score >= 70) return \"C\";\n if (score >= 60) return \"D\";\n return \"F\";\n}\n\n/** Render a human-readable Markdown report. */\nexport function renderBenchmarkMarkdown(\n scored: ScoredBenchmark,\n meta: { repo: string; languages: string[]; layers: string[]; generatedAt: string; model: string }\n): string {\n const lines: string[] = [];\n lines.push(`# Edsger Benchmark Report`);\n lines.push(\"\");\n lines.push(`**Score: ${scored.overall} / 100 (Grade ${scored.grade})**`);\n lines.push(\"\");\n lines.push(`> ${scored.summary}`);\n lines.push(\"\");\n lines.push(`| Field | Value |`);\n lines.push(`| --- | --- |`);\n lines.push(`| Repository | \\`${meta.repo}\\` |`);\n lines.push(`| Languages | ${meta.languages.join(\", \") || \"n/a\"} |`);\n lines.push(`| Standard | ${scored.standardName} v${scored.standardVersion} |`);\n lines.push(`| Sources | ${meta.layers.join(\" → \")} |`);\n lines.push(`| Model | ${meta.model} |`);\n lines.push(`| Generated | ${meta.generatedAt} |`);\n lines.push(\"\");\n\n lines.push(`## Category scores`);\n lines.push(\"\");\n lines.push(`| Category | Weight | Score | Weighted |`);\n lines.push(`| --- | ---: | ---: | ---: |`);\n for (const c of scored.categories) {\n lines.push(`| ${c.name} | ${c.weight}% | ${Math.round(c.fraction * 100)}% | ${c.points} |`);\n }\n lines.push(`| **Overall** | **100%** | | **${scored.overall}** |`);\n lines.push(\"\");\n\n if (scored.strengths.length) {\n lines.push(`## Strengths`);\n lines.push(\"\");\n for (const s of scored.strengths) lines.push(`- ${s}`);\n lines.push(\"\");\n }\n if (scored.weaknesses.length) {\n lines.push(`## Weaknesses`);\n lines.push(\"\");\n for (const w of scored.weaknesses) lines.push(`- ${w}`);\n lines.push(\"\");\n }\n if (scored.recommendations.length) {\n lines.push(`## Recommendations`);\n lines.push(\"\");\n for (const r of scored.recommendations) {\n lines.push(`- **[${r.priority}] ${r.title}** — ${r.detail}`);\n }\n lines.push(\"\");\n }\n\n lines.push(`## Detailed findings`);\n lines.push(\"\");\n for (const c of scored.categories) {\n lines.push(`### ${c.name} — ${Math.round(c.fraction * 100)}%`);\n lines.push(\"\");\n for (const cr of c.criteria) {\n lines.push(`- **${cr.title}** (${cr.rawScore}/${cr.maxScore}) — ${cr.justification}`);\n for (const e of cr.evidence) lines.push(` - \\`${e}\\``);\n }\n lines.push(\"\");\n }\n\n lines.push(`---`);\n lines.push(`<sub>Generated by [edsger](https://www.npmjs.com/package/edsger).</sub>`);\n return lines.join(\"\\n\");\n}\n\nfunction clamp(n: number, lo: number, hi: number): number {\n return Math.max(lo, Math.min(hi, n));\n}\nfunction round(n: number, dp: number): number {\n const f = 10 ** dp;\n return Math.round(n * f) / f;\n}\n","import { z } from \"zod\";\n\n/** Per-criterion score the agent must produce for a benchmark. */\nexport const CriterionScoreSchema = z.object({\n id: z.string().describe(\"Criterion id from the rubric\"),\n score: z.number().describe(\"Score for this criterion, 0..scoreScale\"),\n justification: z.string().describe(\"Why this score, in one or two sentences\"),\n evidence: z.array(z.string()).default([]).describe(\"File paths / snippets supporting the score\")\n});\n\nexport const CategoryScoreSchema = z.object({\n id: z.string().describe(\"Category id from the rubric\"),\n criteria: z.array(CriterionScoreSchema)\n});\n\nexport const BenchmarkResultSchema = z.object({\n categories: z.array(CategoryScoreSchema),\n summary: z.string().describe(\"2-4 sentence overall assessment\"),\n strengths: z.array(z.string()).default([]),\n weaknesses: z.array(z.string()).default([]),\n recommendations: z\n .array(\n z.object({\n priority: z.enum([\"high\", \"medium\", \"low\"]),\n title: z.string(),\n detail: z.string()\n })\n )\n .default([])\n});\nexport type BenchmarkResult = z.infer<typeof BenchmarkResultSchema>;\n\nconst SeveritySchema = z.enum([\"critical\", \"high\", \"medium\", \"low\", \"info\"]);\n\nexport const ReviewFindingSchema = z.object({\n focusArea: z.string().describe(\"Focus area id this finding relates to\"),\n severity: SeveritySchema,\n file: z.string().describe(\"Repo-relative file path, or '-' if general\"),\n line: z.number().nullable().default(null).describe(\"1-based line in the new file, if applicable\"),\n title: z.string(),\n detail: z.string().describe(\"What is wrong and why it matters\"),\n suggestion: z.string().nullable().default(null).describe(\"Concrete suggested fix\")\n});\n\nexport const ReviewResultSchema = z.object({\n summary: z.string().describe(\"Overall summary of the change and review\"),\n verdict: z.enum([\"approve\", \"request_changes\", \"comment\"]),\n findings: z.array(ReviewFindingSchema).default([])\n});\nexport type ReviewResult = z.infer<typeof ReviewResultSchema>;\nexport type ReviewFinding = z.infer<typeof ReviewFindingSchema>;\n\nexport const ResolveResultSchema = z.object({\n summary: z.string().describe(\"What was changed and why\"),\n changes: z.array(z.object({ file: z.string(), description: z.string() })).default([]),\n testsRun: z.string().nullable().default(null).describe(\"Command used to verify, and its outcome\"),\n remaining: z.array(z.string()).default([]).describe(\"Anything still unresolved\")\n});\nexport type ResolveResult = z.infer<typeof ResolveResultSchema>;\n","import pc from \"picocolors\";\nimport { findBundledAssetsDir, inferLanguagesFromFiles, resolveStandard } from \"../core/assets.js\";\nimport { loadConfig } from \"../core/config.js\";\nimport { runAgent } from \"../core/agent.js\";\nimport {\n ensureGhReady,\n getPrContext,\n postReview,\n type InlineComment,\n type PrContext,\n type ReviewEvent\n} from \"../core/gh.js\";\nimport { log } from \"../core/logger.js\";\nimport { ReviewResultSchema, type ReviewFinding, type ReviewResult } from \"../core/schema.js\";\nimport type { GlobalOptions, ReviewStandard, Severity } from \"../types.js\";\n\nexport interface PrReviewOptions extends GlobalOptions {\n pr: string;\n repo?: string;\n /** Actually submit the review to GitHub (otherwise preview only). */\n post: boolean;\n}\n\nconst SEVERITY_RANK: Record<Severity, number> = {\n critical: 4,\n high: 3,\n medium: 2,\n low: 1,\n info: 0\n};\n\nexport async function runPrReview(opts: PrReviewOptions): Promise<number> {\n await ensureGhReady();\n log.info(`Fetching PR ${pc.bold(opts.pr)}${opts.repo ? ` from ${opts.repo}` : \"\"}`);\n const ctx = await getPrContext(opts.pr, opts.repo, opts.cwd);\n\n const { config, path: configPath } = loadConfig(opts.cwd);\n const configDir = configPath ? `${configPath}/..` : opts.cwd;\n // If the working dir doesn't reveal the language (e.g. reviewing a PR without\n // checking it out), fall back to the PR's changed file types.\n const fileHint = inferLanguagesFromFiles(\n ctx.files.map((f) => f.path),\n findBundledAssetsDir()\n );\n const resolved = resolveStandard(\"review\", opts, config, configDir, fileHint);\n const standard = resolved.standard as ReviewStandard;\n\n log.info(\n `Reviewing \"${pc.bold(ctx.title)}\" (#${ctx.number}, ${ctx.files.length} files) ` +\n `against ${pc.bold(standard.name)}`\n );\n\n const { result, costUsd, numTurns } = await runAgent({\n prompt: buildPrompt(standard, ctx),\n cwd: opts.cwd,\n model: opts.model,\n maxTurns: opts.maxTurns,\n timeoutMs: opts.timeoutMs,\n allowWrite: false,\n verbose: opts.verbose,\n resultShape: ReviewResultSchema.shape,\n systemPromptAppend:\n \"You are Edsger, a senior code reviewer. Review only what the diff changes, but read \" +\n \"surrounding code for context. Be specific, kind, and actionable; prefer high-signal \" +\n \"findings over nitpicks. Do not modify any files.\"\n });\n\n if (!result) {\n log.error(\"The agent did not produce a review.\");\n return 1;\n }\n\n const event = decideEvent(result, standard);\n const body = renderBody(result, ctx, standard, resolved.layers);\n const inline = buildInlineComments(result, ctx, standard);\n\n printPreview(result, event, numTurns, costUsd);\n\n if (opts.json) {\n process.stdout.write(\n JSON.stringify(\n { verdict: result.verdict, event, findings: result.findings, summary: result.summary },\n null,\n 2\n ) + \"\\n\"\n );\n }\n\n if (opts.post && !opts.dryRun) {\n await postReview(ctx, opts.repo, event, body, inline, opts.cwd);\n log.success(`Posted review (${event}) to ${ctx.url}`);\n } else {\n log.warn(`Preview only. Re-run with ${pc.bold(\"--post\")} to submit this review to GitHub.`);\n process.stderr.write(\"\\n\" + body + \"\\n\");\n }\n return 0;\n}\n\nfunction decideEvent(result: ReviewResult, standard: ReviewStandard): ReviewEvent {\n const blocking = new Set(standard.policy.blockingSeverities);\n const hasBlocking = result.findings.some((f) => blocking.has(f.severity));\n if (hasBlocking) return \"REQUEST_CHANGES\";\n if (result.verdict === \"approve\") return \"APPROVE\";\n if (result.verdict === \"request_changes\") return \"REQUEST_CHANGES\";\n return \"COMMENT\";\n}\n\nfunction buildInlineComments(\n result: ReviewResult,\n ctx: PrContext,\n standard: ReviewStandard\n): InlineComment[] {\n const changed = new Set(ctx.files.map((f) => f.path));\n const sorted = [...result.findings].sort(\n (a, b) => SEVERITY_RANK[b.severity] - SEVERITY_RANK[a.severity]\n );\n const out: InlineComment[] = [];\n for (const f of sorted) {\n if (out.length >= standard.policy.maxComments) break;\n if (f.line && f.file && f.file !== \"-\" && changed.has(f.file)) {\n out.push({ path: f.file, line: f.line, body: renderFinding(f) });\n }\n }\n return out;\n}\n\nfunction renderFinding(f: ReviewFinding): string {\n const head = `**[${f.severity}] ${f.title}**`;\n const fix = f.suggestion ? `\\n\\n_Suggestion:_ ${f.suggestion}` : \"\";\n return `${head}\\n\\n${f.detail}${fix}`;\n}\n\nfunction renderBody(\n result: ReviewResult,\n ctx: PrContext,\n standard: ReviewStandard,\n layers: string[]\n): string {\n const counts = countBySeverity(result.findings);\n const lines: string[] = [];\n lines.push(`## Edsger review — ${verdictLabel(result.verdict)}`);\n lines.push(\"\");\n lines.push(result.summary);\n lines.push(\"\");\n lines.push(\n `**Findings:** ` +\n ([\"critical\", \"high\", \"medium\", \"low\", \"info\"] as Severity[])\n .filter((s) => counts[s])\n .map((s) => `${counts[s]} ${s}`)\n .join(\", \") || \"no blocking issues\"\n );\n lines.push(\"\");\n const general = result.findings.filter((f) => !f.line || f.file === \"-\");\n if (general.length) {\n lines.push(`### General comments`);\n lines.push(\"\");\n for (const f of general) lines.push(`- ${renderFinding(f).replace(/\\n+/g, \" \")}`);\n lines.push(\"\");\n }\n lines.push(\"---\");\n lines.push(\n `<sub>Reviewed against ${standard.name} v${standard.version} ` +\n `(${layers.join(\" → \")}) by [edsger](https://www.npmjs.com/package/edsger).</sub>`\n );\n void ctx;\n return lines.join(\"\\n\");\n}\n\nfunction printPreview(\n result: ReviewResult,\n event: ReviewEvent,\n numTurns: number,\n costUsd: number\n): void {\n log.heading(`Verdict: ${event}`);\n const counts = countBySeverity(result.findings);\n for (const s of [\"critical\", \"high\", \"medium\", \"low\", \"info\"] as Severity[]) {\n if (counts[s]) process.stderr.write(` ${sevColor(s)(s.padEnd(8))} ${counts[s]}\\n`);\n }\n log.step(`${numTurns} turns · ~$${costUsd.toFixed(3)}`);\n}\n\nfunction countBySeverity(findings: ReviewFinding[]): Record<Severity, number> {\n const c: Record<Severity, number> = { critical: 0, high: 0, medium: 0, low: 0, info: 0 };\n for (const f of findings) c[f.severity]++;\n return c;\n}\n\nfunction sevColor(s: Severity): (t: string) => string {\n if (s === \"critical\" || s === \"high\") return pc.red;\n if (s === \"medium\") return pc.yellow;\n return pc.dim;\n}\n\nfunction verdictLabel(v: ReviewResult[\"verdict\"]): string {\n return v === \"approve\" ? \"Approve\" : v === \"request_changes\" ? \"Request changes\" : \"Comment\";\n}\n\nfunction buildPrompt(standard: ReviewStandard, ctx: PrContext): string {\n const focus = standard.focusAreas\n .map((fa) => {\n const checklist = (fa.checklist ?? []).map((c) => ` - ${c}`).join(\"\\n\");\n return (\n `- id: ${fa.id} (${fa.title}, default severity ${fa.defaultSeverity ?? \"medium\"})\\n` +\n ` guidance: ${fa.guidance.trim()}` +\n (checklist ? `\\n checklist:\\n${checklist}` : \"\")\n );\n })\n .join(\"\\n\");\n\n return [\n `Review the following pull request.`,\n ``,\n `Title: ${ctx.title}`,\n `Author: ${ctx.author}`,\n `Base: ${ctx.baseRefName} Head: ${ctx.headRefName}`,\n `Description:`,\n ctx.body ? indent(ctx.body) : \" (no description)\",\n ``,\n `Changed files: ${ctx.files.map((f) => f.path).join(\", \")}`,\n ``,\n `Method:`,\n `1. Read the diff below. Use Read/Grep/Glob to inspect surrounding code in the working`,\n ` directory for context when needed. Do NOT modify files.`,\n `2. Evaluate the change against the focus areas. Assign each finding a severity`,\n ` (critical/high/medium/low/info) and, where it maps to a changed line, the file path`,\n ` and the 1-based line number in the NEW version of the file.`,\n `3. Verify the change does what its description claims; flag missing tests for new logic.`,\n `4. Choose a verdict: approve, request_changes, or comment. Then call submit_result once.`,\n ``,\n `Focus areas:`,\n focus,\n ``,\n `Unified diff:`,\n \"```diff\",\n truncate(ctx.diff, 180000),\n \"```\"\n ].join(\"\\n\");\n}\n\nfunction indent(s: string): string {\n return s\n .split(\"\\n\")\n .map((l) => ` ${l}`)\n .join(\"\\n\");\n}\nfunction truncate(s: string, max: number): string {\n return s.length > max ? s.slice(0, max) + \"\\n... [diff truncated] ...\" : s;\n}\n","import { execFile } from \"node:child_process\";\nimport { mkdtempSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\n\nconst exec = promisify(execFile);\n\nexport interface PrContext {\n number: number;\n title: string;\n body: string;\n author: string;\n baseRefName: string;\n headRefName: string;\n state: string;\n url: string;\n /** True when the PR head lives in a fork (cannot push to origin directly). */\n isCrossRepository: boolean;\n files: { path: string; additions: number; deletions: number }[];\n diff: string;\n}\n\nexport interface InlineComment {\n path: string;\n line: number;\n body: string;\n}\n\nasync function gh(args: string[], cwd?: string): Promise<string> {\n const { stdout } = await exec(\"gh\", args, {\n cwd,\n maxBuffer: 64 * 1024 * 1024,\n env: process.env\n });\n return stdout;\n}\n\n/** Throw a friendly error if gh is missing or not authenticated. */\nexport async function ensureGhReady(): Promise<void> {\n try {\n await exec(\"gh\", [\"--version\"]);\n } catch {\n throw new Error(\n \"GitHub CLI (gh) not found. Install it from https://cli.github.com and run `gh auth login`.\"\n );\n }\n try {\n await exec(\"gh\", [\"auth\", \"status\"]);\n } catch {\n throw new Error(\"Not authenticated with GitHub. Run `gh auth login` first.\");\n }\n}\n\n/** Fetch PR metadata, changed files, and the unified diff. */\nexport async function getPrContext(\n ref: string,\n repo: string | undefined,\n cwd: string\n): Promise<PrContext> {\n const repoArgs = repo ? [\"--repo\", repo] : [];\n const fields =\n \"number,title,body,author,baseRefName,headRefName,state,url,isCrossRepository,files\";\n const metaRaw = await gh([\"pr\", \"view\", ref, ...repoArgs, \"--json\", fields], cwd);\n const meta = JSON.parse(metaRaw) as {\n number: number;\n title: string;\n body: string | null;\n author: { login: string };\n baseRefName: string;\n headRefName: string;\n state: string;\n url: string;\n isCrossRepository: boolean;\n files: { path: string; additions: number; deletions: number }[];\n };\n const diff = await gh([\"pr\", \"diff\", ref, ...repoArgs], cwd);\n return {\n number: meta.number,\n title: meta.title,\n body: meta.body ?? \"\",\n author: meta.author?.login ?? \"unknown\",\n baseRefName: meta.baseRefName,\n headRefName: meta.headRefName,\n state: meta.state,\n url: meta.url,\n isCrossRepository: Boolean(meta.isCrossRepository),\n files: meta.files ?? [],\n diff\n };\n}\n\n/** Check out a PR branch locally (for pr-resolve). */\nexport async function checkoutPr(\n ref: string,\n repo: string | undefined,\n cwd: string\n): Promise<void> {\n const repoArgs = repo ? [\"--repo\", repo] : [];\n await gh([\"pr\", \"checkout\", ref, ...repoArgs], cwd);\n}\n\nexport type ReviewEvent = \"APPROVE\" | \"REQUEST_CHANGES\" | \"COMMENT\";\n\n/**\n * Post a review. Inline comments are submitted via the REST API so they attach\n * to specific lines; the summary body is included in the same review.\n */\nexport async function postReview(\n ctx: PrContext,\n repo: string | undefined,\n event: ReviewEvent,\n body: string,\n inline: InlineComment[],\n cwd: string\n): Promise<void> {\n const target = repo ?? (await currentRepoSlug(cwd));\n if (inline.length === 0) {\n const flag =\n event === \"APPROVE\"\n ? \"--approve\"\n : event === \"REQUEST_CHANGES\"\n ? \"--request-changes\"\n : \"--comment\";\n await gh([\"pr\", \"review\", String(ctx.number), \"--repo\", target, flag, \"--body\", body], cwd);\n return;\n }\n const payload = {\n body,\n event,\n comments: inline.map((c) => ({ path: c.path, line: c.line, side: \"RIGHT\", body: c.body }))\n };\n const dir = mkdtempSync(join(tmpdir(), \"edsger-review-\"));\n const file = join(dir, \"review.json\");\n writeFileSync(file, JSON.stringify(payload), \"utf8\");\n try {\n await gh(\n [\"api\", \"--method\", \"POST\", `repos/${target}/pulls/${ctx.number}/reviews`, \"--input\", file],\n cwd\n );\n } catch {\n // Fall back to a plain summary review if inline submission fails (e.g. a\n // comment targets a line outside the diff).\n const flag =\n event === \"APPROVE\"\n ? \"--approve\"\n : event === \"REQUEST_CHANGES\"\n ? \"--request-changes\"\n : \"--comment\";\n await gh([\"pr\", \"review\", String(ctx.number), \"--repo\", target, flag, \"--body\", body], cwd);\n } finally {\n rmSync(dir, { recursive: true, force: true });\n }\n}\n\n/** Resolve \"owner/repo\" for the current checkout. */\nexport async function currentRepoSlug(cwd: string): Promise<string> {\n const raw = await gh([\"repo\", \"view\", \"--json\", \"nameWithOwner\"], cwd);\n return (JSON.parse(raw) as { nameWithOwner: string }).nameWithOwner;\n}\n\nexport interface PrFeedback {\n reviewComments: { author: string; path: string; line: number | null; body: string }[];\n issueComments: { author: string; body: string }[];\n}\n\n/** Fetch inline review comments and conversation comments on a PR. */\nexport async function getPrFeedback(\n ctx: PrContext,\n repo: string | undefined,\n cwd: string\n): Promise<PrFeedback> {\n const target = repo ?? (await currentRepoSlug(cwd));\n const reviewRaw = await gh(\n [\"api\", `repos/${target}/pulls/${ctx.number}/comments`, \"--paginate\"],\n cwd\n ).catch(() => \"[]\");\n const issueRaw = await gh(\n [\"api\", `repos/${target}/issues/${ctx.number}/comments`, \"--paginate\"],\n cwd\n ).catch(() => \"[]\");\n const review = JSON.parse(reviewRaw) as Array<{\n user: { login: string };\n path: string;\n line: number | null;\n body: string;\n }>;\n const issue = JSON.parse(issueRaw) as Array<{ user: { login: string }; body: string }>;\n return {\n reviewComments: review.map((c) => ({\n author: c.user?.login ?? \"unknown\",\n path: c.path,\n line: c.line,\n body: c.body\n })),\n issueComments: issue.map((c) => ({ author: c.user?.login ?? \"unknown\", body: c.body }))\n };\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport pc from \"picocolors\";\nimport { runAgent } from \"../core/agent.js\";\nimport {\n checkoutPr,\n ensureGhReady,\n getPrContext,\n getPrFeedback,\n type PrContext,\n type PrFeedback\n} from \"../core/gh.js\";\nimport { log } from \"../core/logger.js\";\nimport { ResolveResultSchema, type ResolveResult } from \"../core/schema.js\";\nimport type { GlobalOptions } from \"../types.js\";\n\nconst exec = promisify(execFile);\n\nexport interface PrResolveOptions extends GlobalOptions {\n pr: string;\n repo?: string;\n /** Free-form instruction, e.g. \"address review comments and fix the failing test\". */\n instruction?: string;\n /** Check out the PR branch locally before editing. */\n checkout: boolean;\n /** Commit and push the changes when done. */\n push: boolean;\n}\n\nexport async function runPrResolve(opts: PrResolveOptions): Promise<number> {\n await ensureGhReady();\n log.info(`Fetching PR ${pc.bold(opts.pr)}${opts.repo ? ` from ${opts.repo}` : \"\"}`);\n const ctx = await getPrContext(opts.pr, opts.repo, opts.cwd);\n const feedback = await getPrFeedback(ctx, opts.repo, opts.cwd).catch(() => ({\n reviewComments: [],\n issueComments: []\n }));\n\n if (opts.checkout && !opts.dryRun) {\n log.step(`checking out PR branch ${ctx.headRefName}`);\n await checkoutPr(opts.pr, opts.repo, opts.cwd);\n }\n\n log.info(\n `Resolving \"${pc.bold(ctx.title)}\" (#${ctx.number}) — ` +\n `${feedback.reviewComments.length} review comments`\n );\n\n const { result, costUsd, numTurns } = await runAgent({\n prompt: buildPrompt(ctx, feedback, opts.instruction),\n cwd: opts.cwd,\n model: opts.model,\n maxTurns: opts.maxTurns,\n timeoutMs: opts.timeoutMs,\n allowWrite: true,\n verbose: opts.verbose,\n resultShape: ResolveResultSchema.shape,\n systemPromptAppend:\n \"You are Edsger, a careful senior engineer fixing a pull request. Make the smallest \" +\n \"correct change that addresses the feedback. Match the existing code style. After \" +\n \"editing, run the project's tests/linters to verify. Never weaken tests to make them \" +\n \"pass, and never commit secrets.\"\n });\n\n if (!result) {\n log.error(\"The agent did not produce a result.\");\n return 1;\n }\n\n printSummary(result, numTurns, costUsd);\n if (opts.json) process.stdout.write(JSON.stringify(result, null, 2) + \"\\n\");\n\n if (opts.push && !opts.dryRun) {\n const pushed = await commitAndPush(ctx, result, opts.cwd, opts.checkout);\n if (pushed) log.success(`Committed and pushed to ${ctx.headRefName}`);\n else log.warn(\"Nothing to commit — working tree is clean.\");\n } else {\n log.warn(\n `Changes left in the working tree. Review them, then commit/push (or re-run with ${pc.bold(\"--push\")}).`\n );\n }\n return 0;\n}\n\nasync function commitAndPush(\n ctx: PrContext,\n result: ResolveResult,\n cwd: string,\n checkedOut: boolean\n): Promise<boolean> {\n const status = await exec(\"git\", [\"status\", \"--porcelain\"], { cwd });\n if (!status.stdout.trim()) return false;\n await exec(\"git\", [\"add\", \"-A\"], { cwd });\n const message = `fix: address review feedback on #${ctx.number}\\n\\n${result.summary}`;\n await exec(\"git\", [\"commit\", \"-m\", message], { cwd });\n\n // `gh pr checkout` configures the local branch to push back to the right\n // remote (including a fork), so prefer a plain push when we checked out.\n if (checkedOut) {\n try {\n await exec(\"git\", [\"push\"], { cwd });\n return true;\n } catch (err) {\n if (ctx.isCrossRepository) {\n throw new Error(\n `Could not push to the fork's branch automatically: ${errText(err)}\\n` +\n \"Push manually, or ensure the PR branch was checked out with gh.\"\n );\n }\n // Same-repo: fall through to an explicit origin push.\n }\n }\n if (ctx.isCrossRepository) {\n throw new Error(\n \"This PR is from a fork. Re-run without --no-checkout so gh can configure \" +\n \"the push target, or commit and push to the fork manually.\"\n );\n }\n await exec(\"git\", [\"push\", \"origin\", `HEAD:${ctx.headRefName}`], { cwd });\n return true;\n}\n\nfunction errText(err: unknown): string {\n return err instanceof Error ? (err.message.split(\"\\n\")[0] ?? \"\") : String(err);\n}\n\nfunction printSummary(result: ResolveResult, numTurns: number, costUsd: number): void {\n log.heading(\"Resolution summary\");\n process.stderr.write(` ${result.summary}\\n\\n`);\n if (result.changes.length) {\n for (const c of result.changes)\n process.stderr.write(` ${pc.green(\"~\")} ${c.file} — ${c.description}\\n`);\n }\n if (result.testsRun) log.step(`verification: ${result.testsRun}`);\n if (result.remaining.length) {\n log.warn(\"Remaining items:\");\n for (const r of result.remaining) process.stderr.write(` - ${r}\\n`);\n }\n log.step(`${numTurns} turns · ~$${costUsd.toFixed(3)}`);\n}\n\nfunction buildPrompt(ctx: PrContext, feedback: PrFeedback, instruction?: string): string {\n const reviewComments = feedback.reviewComments.length\n ? feedback.reviewComments\n .map((c) => ` - ${c.path}${c.line ? `:${c.line}` : \"\"} (${c.author}): ${c.body}`)\n .join(\"\\n\")\n : \" (none)\";\n const issueComments = feedback.issueComments.length\n ? feedback.issueComments.map((c) => ` - ${c.author}: ${c.body}`).join(\"\\n\")\n : \" (none)\";\n\n return [\n `Resolve the open items on this pull request by editing the code in the working directory.`,\n ``,\n `PR #${ctx.number}: ${ctx.title}`,\n `Base: ${ctx.baseRefName} Head: ${ctx.headRefName}`,\n ``,\n instruction\n ? `Primary instruction: ${instruction}`\n : `Primary goal: address the reviewer feedback below.`,\n ``,\n `Inline review comments:`,\n reviewComments,\n ``,\n `Conversation comments:`,\n issueComments,\n ``,\n `Method:`,\n `1. Understand each requested change. Use Read/Grep/Glob to locate the relevant code.`,\n `2. Make the minimal, correct edits with Edit/Write. Match existing conventions.`,\n `3. Run the project's tests and linters (via Bash) to verify your changes pass.`,\n `4. Do not weaken or delete tests to make them pass; do not introduce secrets.`,\n `5. Call submit_result once with a summary, the list of files changed, how you verified,`,\n ` and anything you could not resolve.`\n ].join(\"\\n\");\n}\n","import {\n cpSync,\n existsSync,\n mkdirSync,\n readFileSync,\n readdirSync,\n rmSync,\n statSync,\n writeFileSync\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport pc from \"picocolors\";\nimport { findBundledAssetsDir } from \"../core/assets.js\";\nimport { log } from \"../core/logger.js\";\n\nexport interface SkillsScope {\n cwd: string;\n /** Install for the whole user (~/.claude) instead of the current project. */\n global: boolean;\n}\n\nexport interface SkillsInstallOptions extends SkillsScope {\n force: boolean;\n}\n\n/** The skills this CLI manages (must match dir names under assets/skills). */\nconst MANAGED = [\"benchmark\", \"pr-review\", \"pr-resolve\"];\n\nfunction targetSkillsDir(scope: SkillsScope): string {\n return scope.global ? join(homedir(), \".claude\", \"skills\") : join(scope.cwd, \".claude\", \"skills\");\n}\n\nfunction sourceSkillsDir(): string {\n return join(findBundledAssetsDir(), \"skills\");\n}\n\n/**\n * Install the edsger skills into Claude Code so `/benchmark`, `/pr-review` and\n * `/pr-resolve` work — no plugin marketplace or paths required. The skill's\n * `${CLAUDE_PLUGIN_ROOT}` references are rewritten to the bundled assets dir.\n */\nexport async function runSkillsInstall(opts: SkillsInstallOptions): Promise<number> {\n const assetsDir = findBundledAssetsDir();\n const src = sourceSkillsDir();\n if (!existsSync(src)) {\n log.error(`Bundled skills not found at ${src}. Reinstall edsger.`);\n return 1;\n }\n const dest = targetSkillsDir(opts);\n mkdirSync(dest, { recursive: true });\n\n const available = readdirSync(src).filter((n) => existsSync(join(src, n, \"SKILL.md\")));\n let installed = 0;\n for (const name of available) {\n const outDir = join(dest, name);\n if (existsSync(outDir) && !opts.force) {\n log.warn(`skill \"${name}\" already exists — use --force to overwrite`);\n continue;\n }\n // Copy the whole skill dir (in case it grows auxiliary files), then rewrite\n // the SKILL.md plugin-root token to the absolute bundled assets path.\n rmSync(outDir, { recursive: true, force: true });\n cpSync(join(src, name), outDir, { recursive: true });\n const skillFile = join(outDir, \"SKILL.md\");\n const rewritten = readFileSync(skillFile, \"utf8\")\n .split(\"${CLAUDE_PLUGIN_ROOT}\")\n .join(assetsDir);\n writeFileSync(skillFile, rewritten, \"utf8\");\n installed++;\n log.success(`installed /${name}`);\n }\n\n if (installed === 0) {\n log.info(\"Nothing installed.\");\n return 0;\n }\n log.heading(`Installed ${installed} skill(s) into ${pc.bold(dest)}`);\n log.step(`scope: ${opts.global ? \"user (all projects)\" : \"this project\"}`);\n log.step(`standards: ${assetsDir}`);\n log.step(\"Open Claude Code and run /benchmark, /pr-review, or /pr-resolve.\");\n return 0;\n}\n\nexport async function runSkillsUninstall(opts: SkillsScope): Promise<number> {\n const dest = targetSkillsDir(opts);\n let removed = 0;\n for (const name of MANAGED) {\n const dir = join(dest, name);\n if (existsSync(dir)) {\n rmSync(dir, { recursive: true, force: true });\n removed++;\n log.success(`removed /${name}`);\n }\n }\n log.info(removed ? `Removed ${removed} skill(s) from ${dest}` : \"No edsger skills found.\");\n return 0;\n}\n\nexport async function runSkillsList(opts: SkillsScope): Promise<number> {\n for (const [label, scope] of [\n [\"user\", { ...opts, global: true }],\n [\"project\", { ...opts, global: false }]\n ] as const) {\n const dir = targetSkillsDir(scope);\n const present = MANAGED.filter((n) => {\n const p = join(dir, n, \"SKILL.md\");\n return existsSync(p) && statSync(p).isFile();\n });\n log.heading(`${label}: ${dir}`);\n if (present.length) for (const n of present) process.stderr.write(` ${pc.green(\"✓\")} /${n}\\n`);\n else process.stderr.write(` ${pc.dim(\"(none installed)\")}\\n`);\n }\n return 0;\n}\n"],"mappings":"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","names":["readFileSync","resolve","pc","join","pc","existsSync","join","join","existsSync","pc","pc","join","pc","pc","writeFileSync","join","pc","buildPrompt","execFile","promisify","pc","exec","promisify","execFile","pc","buildPrompt","printSummary","existsSync","mkdirSync","readFileSync","readdirSync","rmSync","statSync","writeFileSync","homedir","join","pc","join","homedir","existsSync","mkdirSync","readdirSync","rmSync","readFileSync","writeFileSync","pc","statSync","readFileSync","resolve","pc"]}
|