@open-code-review/cli 1.6.0 → 1.8.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 +20 -4
- package/dist/dashboard/client/assets/{_basePickBy-BGuMbEDR.js → _basePickBy-DbLJVCA4.js} +1 -1
- package/dist/dashboard/client/assets/{_baseUniq-Bx8loabg.js → _baseUniq-IXEG0cJJ.js} +1 -1
- package/dist/dashboard/client/assets/{arc-DUgpt7nY.js → arc-lsKxmOJY.js} +1 -1
- package/dist/dashboard/client/assets/{architectureDiagram-VXUJARFQ-D25nt6Xz.js → architectureDiagram-VXUJARFQ-DfMlzFJX.js} +1 -1
- package/dist/dashboard/client/assets/{blockDiagram-VD42YOAC-D8PUF3h4.js → blockDiagram-VD42YOAC-bSpnd26J.js} +1 -1
- package/dist/dashboard/client/assets/{c4Diagram-YG6GDRKO-lorsCz-I.js → c4Diagram-YG6GDRKO-DPYmVhCZ.js} +1 -1
- package/dist/dashboard/client/assets/channel-C--wY_Wd.js +1 -0
- package/dist/dashboard/client/assets/{chunk-4BX2VUAB-8lVyfRJM.js → chunk-4BX2VUAB-CI9zC4lV.js} +1 -1
- package/dist/dashboard/client/assets/{chunk-55IACEB6-C4SjgsZO.js → chunk-55IACEB6-BqUdJdx5.js} +1 -1
- package/dist/dashboard/client/assets/{chunk-B4BG7PRW-BXzTPbH1.js → chunk-B4BG7PRW-DymQrTp-.js} +1 -1
- package/dist/dashboard/client/assets/{chunk-DI55MBZ5-Bp7QllDt.js → chunk-DI55MBZ5-lZ_9LKGJ.js} +1 -1
- package/dist/dashboard/client/assets/{chunk-FMBD7UC4-B4g9S67N.js → chunk-FMBD7UC4-DC5rgLNm.js} +1 -1
- package/dist/dashboard/client/assets/{chunk-QN33PNHL-Dyk7Hc0J.js → chunk-QN33PNHL-BrygpHrX.js} +1 -1
- package/dist/dashboard/client/assets/{chunk-QZHKN3VN-DTvkGdnm.js → chunk-QZHKN3VN-CWJqBdNg.js} +1 -1
- package/dist/dashboard/client/assets/{chunk-TZMSLE5B-BAeZLvrI.js → chunk-TZMSLE5B-BACgM5pG.js} +1 -1
- package/dist/dashboard/client/assets/classDiagram-2ON5EDUG-DoxmMlnf.js +1 -0
- package/dist/dashboard/client/assets/classDiagram-v2-WZHVMYZB-DoxmMlnf.js +1 -0
- package/dist/dashboard/client/assets/clone-BgvweD4v.js +1 -0
- package/dist/dashboard/client/assets/{cose-bilkent-S5V4N54A--6-kzrdu.js → cose-bilkent-S5V4N54A-BYvGIfo0.js} +1 -1
- package/dist/dashboard/client/assets/{dagre-6UL2VRFP-D10_QE2P.js → dagre-6UL2VRFP-B1rZyiLJ.js} +1 -1
- package/dist/dashboard/client/assets/{diagram-PSM6KHXK-kS1x75Bl.js → diagram-PSM6KHXK-Dvl5dQMd.js} +1 -1
- package/dist/dashboard/client/assets/{diagram-QEK2KX5R-D_LLCPas.js → diagram-QEK2KX5R-Cmntmhht.js} +1 -1
- package/dist/dashboard/client/assets/{diagram-S2PKOQOG-Duy1t5UO.js → diagram-S2PKOQOG-BqZcpG85.js} +1 -1
- package/dist/dashboard/client/assets/{erDiagram-Q2GNP2WA-DyQXwzLf.js → erDiagram-Q2GNP2WA-Cw7BALso.js} +1 -1
- package/dist/dashboard/client/assets/{flowDiagram-NV44I4VS-D9U11XVw.js → flowDiagram-NV44I4VS-B_amTHzQ.js} +1 -1
- package/dist/dashboard/client/assets/{ganttDiagram-JELNMOA3-STy-TC-3.js → ganttDiagram-JELNMOA3-B1j2-sTo.js} +1 -1
- package/dist/dashboard/client/assets/{gitGraphDiagram-V2S2FVAM-B04PgURg.js → gitGraphDiagram-V2S2FVAM-D5BkfAMt.js} +1 -1
- package/dist/dashboard/client/assets/{graph-AiGwnT5H.js → graph-B_v15DHv.js} +1 -1
- package/dist/dashboard/client/assets/index-UkJZZdYD.js +548 -0
- package/dist/dashboard/client/assets/index-Zl---B_3.css +1 -0
- package/dist/dashboard/client/assets/{infoDiagram-HS3SLOUP-D4arwl6T.js → infoDiagram-HS3SLOUP-C4dtIkj3.js} +1 -1
- package/dist/dashboard/client/assets/{journeyDiagram-XKPGCS4Q-CsKqlKkf.js → journeyDiagram-XKPGCS4Q-hha4Am8v.js} +1 -1
- package/dist/dashboard/client/assets/{kanban-definition-3W4ZIXB7-CUFnzQE3.js → kanban-definition-3W4ZIXB7-1EY8l7Ng.js} +1 -1
- package/dist/dashboard/client/assets/{layout-BvvYJVPv.js → layout-7SmAbjFT.js} +1 -1
- package/dist/dashboard/client/assets/{linear-BiBJkzyE.js → linear-BfjSBezh.js} +1 -1
- package/dist/dashboard/client/assets/{mermaid-renderer-DGUmIWXY.js → mermaid-renderer-PPIt-kY4.js} +4 -4
- package/dist/dashboard/client/assets/{mindmap-definition-VGOIOE7T-D-Kc9Xgu.js → mindmap-definition-VGOIOE7T-BFpjN9LY.js} +1 -1
- package/dist/dashboard/client/assets/{pieDiagram-ADFJNKIX-CooPKLnX.js → pieDiagram-ADFJNKIX-GBbQtDBQ.js} +1 -1
- package/dist/dashboard/client/assets/{quadrantDiagram-AYHSOK5B-3soPtaSQ.js → quadrantDiagram-AYHSOK5B-Dm0vOhOw.js} +1 -1
- package/dist/dashboard/client/assets/{requirementDiagram-UZGBJVZJ-rE40t0IG.js → requirementDiagram-UZGBJVZJ-BrKONIV8.js} +1 -1
- package/dist/dashboard/client/assets/{sankeyDiagram-TZEHDZUN-CrgDF_jW.js → sankeyDiagram-TZEHDZUN-IOobtmDc.js} +1 -1
- package/dist/dashboard/client/assets/{sequenceDiagram-WL72ISMW-B628IlDW.js → sequenceDiagram-WL72ISMW-Dnb0bOW5.js} +1 -1
- package/dist/dashboard/client/assets/{stateDiagram-FKZM4ZOC-C4yb7S9D.js → stateDiagram-FKZM4ZOC-C9-bf7bn.js} +1 -1
- package/dist/dashboard/client/assets/stateDiagram-v2-4FDKWEC3-C8Gr4khP.js +1 -0
- package/dist/dashboard/client/assets/{timeline-definition-IT6M3QCI-5uLN4f_J.js → timeline-definition-IT6M3QCI-tJogDEHB.js} +1 -1
- package/dist/dashboard/client/assets/{treemap-GDKQZRPO-BHXME3bw.js → treemap-GDKQZRPO-DQY6HADq.js} +1 -1
- package/dist/dashboard/client/assets/{xychartDiagram-PRI3JC2R-BYTod6eI.js → xychartDiagram-PRI3JC2R-DfxeQmTO.js} +1 -1
- package/dist/dashboard/client/index.html +2 -2
- package/dist/dashboard/server.js +312 -187
- package/dist/index.js +326 -10
- package/package.json +2 -2
- package/dist/dashboard/client/assets/channel-yW2sWou_.js +0 -1
- package/dist/dashboard/client/assets/classDiagram-2ON5EDUG-1pMX5UXO.js +0 -1
- package/dist/dashboard/client/assets/classDiagram-v2-WZHVMYZB-1pMX5UXO.js +0 -1
- package/dist/dashboard/client/assets/clone-DQwdw3YR.js +0 -1
- package/dist/dashboard/client/assets/index-BzQ3i_QR.js +0 -458
- package/dist/dashboard/client/assets/index-CGGYXSm-.css +0 -1
- package/dist/dashboard/client/assets/stateDiagram-v2-4FDKWEC3-BoFeOfLI.js +0 -1
package/dist/index.js
CHANGED
|
@@ -20361,6 +20361,153 @@ function installCommandsForTool(tool, commandsSource, targetDir) {
|
|
|
20361
20361
|
return false;
|
|
20362
20362
|
}
|
|
20363
20363
|
}
|
|
20364
|
+
var BUILTIN_ICON_MAP = {
|
|
20365
|
+
architect: "blocks",
|
|
20366
|
+
fullstack: "layers",
|
|
20367
|
+
reliability: "activity",
|
|
20368
|
+
"staff-engineer": "compass",
|
|
20369
|
+
principal: "crown",
|
|
20370
|
+
frontend: "layout",
|
|
20371
|
+
backend: "server",
|
|
20372
|
+
infrastructure: "cloud",
|
|
20373
|
+
performance: "gauge",
|
|
20374
|
+
accessibility: "accessibility",
|
|
20375
|
+
data: "database",
|
|
20376
|
+
devops: "rocket",
|
|
20377
|
+
dx: "terminal",
|
|
20378
|
+
mobile: "smartphone",
|
|
20379
|
+
security: "shield-alert",
|
|
20380
|
+
quality: "sparkles",
|
|
20381
|
+
testing: "test-tubes",
|
|
20382
|
+
ai: "bot",
|
|
20383
|
+
"docs-writer": "file-text"
|
|
20384
|
+
};
|
|
20385
|
+
var HOLISTIC_IDS = /* @__PURE__ */ new Set(["architect", "fullstack", "reliability", "staff-engineer", "principal"]);
|
|
20386
|
+
var SPECIALIST_IDS = /* @__PURE__ */ new Set([
|
|
20387
|
+
"frontend",
|
|
20388
|
+
"backend",
|
|
20389
|
+
"infrastructure",
|
|
20390
|
+
"performance",
|
|
20391
|
+
"accessibility",
|
|
20392
|
+
"data",
|
|
20393
|
+
"devops",
|
|
20394
|
+
"dx",
|
|
20395
|
+
"mobile",
|
|
20396
|
+
"security",
|
|
20397
|
+
"quality",
|
|
20398
|
+
"testing",
|
|
20399
|
+
"ai",
|
|
20400
|
+
"docs-writer"
|
|
20401
|
+
]);
|
|
20402
|
+
var PERSONA_IDS = /* @__PURE__ */ new Set([
|
|
20403
|
+
"martin-fowler",
|
|
20404
|
+
"kent-beck",
|
|
20405
|
+
"john-ousterhout",
|
|
20406
|
+
"anders-hejlsberg",
|
|
20407
|
+
"vladimir-khorikov",
|
|
20408
|
+
"kent-dodds",
|
|
20409
|
+
"tanner-linsley",
|
|
20410
|
+
"kamil-mysliwiec",
|
|
20411
|
+
"sandi-metz",
|
|
20412
|
+
"rich-hickey"
|
|
20413
|
+
]);
|
|
20414
|
+
function classifyTier(id) {
|
|
20415
|
+
if (PERSONA_IDS.has(id)) return "persona";
|
|
20416
|
+
if (HOLISTIC_IDS.has(id)) return "holistic";
|
|
20417
|
+
if (SPECIALIST_IDS.has(id)) return "specialist";
|
|
20418
|
+
return "custom";
|
|
20419
|
+
}
|
|
20420
|
+
function extractReviewerName(content) {
|
|
20421
|
+
const match = content.match(/^#\s+(.+?)(?:\s+—\s+Reviewer|\s+Reviewer)\s*$/m);
|
|
20422
|
+
if (match?.[1]) return match[1];
|
|
20423
|
+
const titleMatch = content.match(/^#\s+(.+)$/m);
|
|
20424
|
+
return titleMatch?.[1]?.replace(/\s*Reviewer\s*$/, "").trim() ?? "Unknown";
|
|
20425
|
+
}
|
|
20426
|
+
function extractReviewerDescription(content) {
|
|
20427
|
+
const lines = content.split("\n");
|
|
20428
|
+
for (const line of lines) {
|
|
20429
|
+
const trimmed = line.trim();
|
|
20430
|
+
if (!trimmed || trimmed.startsWith("#") || trimmed.startsWith(">")) continue;
|
|
20431
|
+
if (trimmed.startsWith("You are a **") || trimmed.startsWith("You are reviewing")) {
|
|
20432
|
+
return trimmed.replace(/\*\*/g, "").replace(/^You are a /, "").replace(/^You are reviewing code through the lens of .*?\.\s*/, "").trim();
|
|
20433
|
+
}
|
|
20434
|
+
}
|
|
20435
|
+
return "";
|
|
20436
|
+
}
|
|
20437
|
+
function extractFocusAreas(content) {
|
|
20438
|
+
const areas = [];
|
|
20439
|
+
const focusMatch = content.match(/## Your Focus Areas\n([\s\S]*?)(?=\n##|\n---|\z)/);
|
|
20440
|
+
if (focusMatch?.[1]) {
|
|
20441
|
+
const bullets = focusMatch[1].match(/- \*\*(.+?)\*\*/g);
|
|
20442
|
+
if (bullets) {
|
|
20443
|
+
for (const b of bullets) {
|
|
20444
|
+
const m = b.match(/- \*\*(.+?)\*\*/);
|
|
20445
|
+
if (m?.[1]) areas.push(m[1]);
|
|
20446
|
+
}
|
|
20447
|
+
}
|
|
20448
|
+
}
|
|
20449
|
+
return areas;
|
|
20450
|
+
}
|
|
20451
|
+
function extractPersonaFields(content) {
|
|
20452
|
+
const knownMatch = content.match(/>\s*\*\*Known for\*\*:\s*(.+)/);
|
|
20453
|
+
const philMatch = content.match(/>\s*\*\*Philosophy\*\*:\s*([\s\S]*?)(?=\n(?!>)|\n\n)/);
|
|
20454
|
+
const result = {};
|
|
20455
|
+
if (knownMatch?.[1]) result.known_for = knownMatch[1].trim();
|
|
20456
|
+
if (philMatch?.[1]) {
|
|
20457
|
+
result.philosophy = philMatch[1].split("\n").map((l) => l.replace(/^>\s*/, "").trim()).join(" ").trim();
|
|
20458
|
+
}
|
|
20459
|
+
return result;
|
|
20460
|
+
}
|
|
20461
|
+
function generateReviewersMeta(reviewersDir, configPath) {
|
|
20462
|
+
if (!existsSync2(reviewersDir)) return null;
|
|
20463
|
+
const files = readdirSync(reviewersDir).filter((f) => f.endsWith(".md"));
|
|
20464
|
+
if (files.length === 0) return null;
|
|
20465
|
+
const defaultTeamIds = /* @__PURE__ */ new Set();
|
|
20466
|
+
if (existsSync2(configPath)) {
|
|
20467
|
+
try {
|
|
20468
|
+
const configContent = readFileSync3(configPath, "utf-8");
|
|
20469
|
+
const teamMatch = configContent.match(/default_team:\s*\n((?:\s+\w[\w-]*:\s*\d+\s*(?:#[^\n]*)?\n?)*)/);
|
|
20470
|
+
if (teamMatch?.[1]) {
|
|
20471
|
+
const entries = teamMatch[1].matchAll(/\s+([\w-]+):\s*\d+/g);
|
|
20472
|
+
for (const entry of entries) {
|
|
20473
|
+
if (entry[1]) defaultTeamIds.add(entry[1]);
|
|
20474
|
+
}
|
|
20475
|
+
}
|
|
20476
|
+
} catch {
|
|
20477
|
+
}
|
|
20478
|
+
}
|
|
20479
|
+
const reviewers = [];
|
|
20480
|
+
for (const file of files) {
|
|
20481
|
+
const id = file.replace(/\.md$/, "");
|
|
20482
|
+
try {
|
|
20483
|
+
const content = readFileSync3(join2(reviewersDir, file), "utf-8");
|
|
20484
|
+
const tier = classifyTier(id);
|
|
20485
|
+
const isBuiltin = HOLISTIC_IDS.has(id) || SPECIALIST_IDS.has(id) || PERSONA_IDS.has(id);
|
|
20486
|
+
const reviewer = {
|
|
20487
|
+
id,
|
|
20488
|
+
name: extractReviewerName(content),
|
|
20489
|
+
tier,
|
|
20490
|
+
icon: BUILTIN_ICON_MAP[id] ?? (tier === "persona" ? "brain" : "user"),
|
|
20491
|
+
description: extractReviewerDescription(content),
|
|
20492
|
+
focus_areas: extractFocusAreas(content),
|
|
20493
|
+
is_default: defaultTeamIds.has(id),
|
|
20494
|
+
is_builtin: isBuiltin
|
|
20495
|
+
};
|
|
20496
|
+
if (tier === "persona") {
|
|
20497
|
+
const persona = extractPersonaFields(content);
|
|
20498
|
+
if (persona.known_for) reviewer.known_for = persona.known_for;
|
|
20499
|
+
if (persona.philosophy) reviewer.philosophy = persona.philosophy;
|
|
20500
|
+
}
|
|
20501
|
+
reviewers.push(reviewer);
|
|
20502
|
+
} catch {
|
|
20503
|
+
}
|
|
20504
|
+
}
|
|
20505
|
+
return {
|
|
20506
|
+
schema_version: 1,
|
|
20507
|
+
generated_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
20508
|
+
reviewers
|
|
20509
|
+
};
|
|
20510
|
+
}
|
|
20364
20511
|
function installForTool(tool, targetDir) {
|
|
20365
20512
|
const agentsPath = getAgentsPackagePath();
|
|
20366
20513
|
const ocrSkillsSource = join2(agentsPath, "skills", "ocr");
|
|
@@ -20435,6 +20582,14 @@ function installForTool(tool, targetDir) {
|
|
|
20435
20582
|
}
|
|
20436
20583
|
}
|
|
20437
20584
|
}
|
|
20585
|
+
const metaPath = join2(ocrDir, "reviewers-meta.json");
|
|
20586
|
+
try {
|
|
20587
|
+
const meta = generateReviewersMeta(reviewersDir, configPath);
|
|
20588
|
+
if (meta) {
|
|
20589
|
+
writeFileSync3(metaPath, JSON.stringify(meta, null, 2) + "\n");
|
|
20590
|
+
}
|
|
20591
|
+
} catch {
|
|
20592
|
+
}
|
|
20438
20593
|
const commandsOk = installCommandsForTool(tool, commandsSource, targetDir);
|
|
20439
20594
|
if (!commandsOk) {
|
|
20440
20595
|
return {
|
|
@@ -20600,6 +20755,28 @@ function setConfiguredToolIds(targetDir, toolIds) {
|
|
|
20600
20755
|
configuredTools: toolIds
|
|
20601
20756
|
});
|
|
20602
20757
|
}
|
|
20758
|
+
function stampCliVersion(targetDir, version) {
|
|
20759
|
+
const existing = loadCliConfig(targetDir) ?? { configuredTools: [] };
|
|
20760
|
+
return saveCliConfig(targetDir, { ...existing, cliVersion: version });
|
|
20761
|
+
}
|
|
20762
|
+
function checkLocalArtifactVersion(targetDir, runningVersion) {
|
|
20763
|
+
const config = loadCliConfig(targetDir);
|
|
20764
|
+
if (!config?.cliVersion) return null;
|
|
20765
|
+
if (config.cliVersion === runningVersion) return null;
|
|
20766
|
+
return { storedVersion: config.cliVersion, runningVersion };
|
|
20767
|
+
}
|
|
20768
|
+
function printLocalVersionHint(drift) {
|
|
20769
|
+
const msg = source_default.yellow(" Local .ocr/ files were installed with ") + source_default.dim(`v${drift.storedVersion}`) + source_default.yellow(" but you're running ") + source_default.green(`v${drift.runningVersion}`) + source_default.yellow(".");
|
|
20770
|
+
const hint = source_default.dim(" Run ") + source_default.bold("ocr update") + source_default.dim(" to refresh local assets.");
|
|
20771
|
+
process.stderr.write(`
|
|
20772
|
+
${msg}
|
|
20773
|
+
${hint}
|
|
20774
|
+
|
|
20775
|
+
`);
|
|
20776
|
+
}
|
|
20777
|
+
|
|
20778
|
+
// src/lib/version.ts
|
|
20779
|
+
var CLI_VERSION = true ? "1.8.0" : createRequire(import.meta.url)("../../package.json").version;
|
|
20603
20780
|
|
|
20604
20781
|
// src/lib/deps.ts
|
|
20605
20782
|
import { execFileSync } from "node:child_process";
|
|
@@ -20843,6 +21020,7 @@ var initCommand = new Command("init").description("Set up OCR for AI coding envi
|
|
|
20843
21020
|
}
|
|
20844
21021
|
const successfulToolIds = successful.map((r) => r.tool.id);
|
|
20845
21022
|
setConfiguredToolIds(targetDir, successfulToolIds);
|
|
21023
|
+
stampCliVersion(targetDir, CLI_VERSION);
|
|
20846
21024
|
}
|
|
20847
21025
|
if (failed.length > 0) {
|
|
20848
21026
|
console.log();
|
|
@@ -25453,6 +25631,7 @@ var updateCommand = new Command("update").description("Update OCR assets after p
|
|
|
25453
25631
|
if (options.dryRun) {
|
|
25454
25632
|
console.log(source_default.dim(" Run without --dry-run to apply changes."));
|
|
25455
25633
|
} else {
|
|
25634
|
+
stampCliVersion(targetDir, CLI_VERSION);
|
|
25456
25635
|
console.log(source_default.green(" \u2713 Update complete"));
|
|
25457
25636
|
}
|
|
25458
25637
|
console.log();
|
|
@@ -25616,14 +25795,145 @@ var doctorCommand = new Command("doctor").description("Check OCR installation an
|
|
|
25616
25795
|
console.log();
|
|
25617
25796
|
});
|
|
25618
25797
|
|
|
25798
|
+
// src/commands/reviewers.ts
|
|
25799
|
+
import { writeFileSync as writeFileSync8, renameSync as renameSync2 } from "node:fs";
|
|
25800
|
+
import { join as join18 } from "node:path";
|
|
25801
|
+
async function readStdin2() {
|
|
25802
|
+
const chunks = [];
|
|
25803
|
+
for await (const chunk of process.stdin) {
|
|
25804
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
25805
|
+
}
|
|
25806
|
+
const data = Buffer.concat(chunks).toString("utf-8").trim();
|
|
25807
|
+
if (data.length === 0) {
|
|
25808
|
+
throw new Error("No data received on stdin");
|
|
25809
|
+
}
|
|
25810
|
+
return data;
|
|
25811
|
+
}
|
|
25812
|
+
var VALID_TIERS = /* @__PURE__ */ new Set(["holistic", "specialist", "persona", "custom"]);
|
|
25813
|
+
var SLUG_RE = /^[a-z][a-z0-9-]*$/;
|
|
25814
|
+
function validateReviewersMeta(data) {
|
|
25815
|
+
if (typeof data !== "object" || data === null || Array.isArray(data)) {
|
|
25816
|
+
throw new Error("Payload must be a JSON object");
|
|
25817
|
+
}
|
|
25818
|
+
const obj = data;
|
|
25819
|
+
if (obj.schema_version !== 1) {
|
|
25820
|
+
throw new Error(`schema_version must be 1, got ${JSON.stringify(obj.schema_version)}`);
|
|
25821
|
+
}
|
|
25822
|
+
if (typeof obj.generated_at !== "string" || obj.generated_at.length === 0) {
|
|
25823
|
+
throw new Error("generated_at must be a non-empty ISO 8601 string");
|
|
25824
|
+
}
|
|
25825
|
+
if (!Array.isArray(obj.reviewers)) {
|
|
25826
|
+
throw new Error("reviewers must be an array");
|
|
25827
|
+
}
|
|
25828
|
+
const seenIds = /* @__PURE__ */ new Set();
|
|
25829
|
+
for (let i = 0; i < obj.reviewers.length; i++) {
|
|
25830
|
+
const r = obj.reviewers[i];
|
|
25831
|
+
const prefix = `reviewers[${i}]`;
|
|
25832
|
+
if (typeof r.id !== "string" || !SLUG_RE.test(r.id)) {
|
|
25833
|
+
throw new Error(`${prefix}.id must be a lowercase slug (got ${JSON.stringify(r.id)})`);
|
|
25834
|
+
}
|
|
25835
|
+
if (seenIds.has(r.id)) {
|
|
25836
|
+
throw new Error(`Duplicate reviewer id: "${r.id}"`);
|
|
25837
|
+
}
|
|
25838
|
+
seenIds.add(r.id);
|
|
25839
|
+
if (typeof r.name !== "string" || r.name.length === 0) {
|
|
25840
|
+
throw new Error(`${prefix}.name must be a non-empty string`);
|
|
25841
|
+
}
|
|
25842
|
+
if (!VALID_TIERS.has(r.tier)) {
|
|
25843
|
+
throw new Error(`${prefix}.tier must be one of: ${[...VALID_TIERS].join(", ")} (got ${JSON.stringify(r.tier)})`);
|
|
25844
|
+
}
|
|
25845
|
+
if (typeof r.description !== "string" || r.description.length === 0) {
|
|
25846
|
+
throw new Error(`${prefix}.description must be a non-empty string`);
|
|
25847
|
+
}
|
|
25848
|
+
if (!Array.isArray(r.focus_areas)) {
|
|
25849
|
+
throw new Error(`${prefix}.focus_areas must be an array`);
|
|
25850
|
+
}
|
|
25851
|
+
if (r.known_for !== void 0 && typeof r.known_for !== "string") {
|
|
25852
|
+
throw new Error(`${prefix}.known_for must be a string if provided`);
|
|
25853
|
+
}
|
|
25854
|
+
if (r.philosophy !== void 0 && typeof r.philosophy !== "string") {
|
|
25855
|
+
throw new Error(`${prefix}.philosophy must be a string if provided`);
|
|
25856
|
+
}
|
|
25857
|
+
}
|
|
25858
|
+
return data;
|
|
25859
|
+
}
|
|
25860
|
+
var syncSubcommand2 = new Command("sync").description("Sync reviewers-meta.json from reviewer markdown files or structured JSON").option("--stdin", "Read reviewers JSON from stdin (for AI-invoked sync)").action(async (options) => {
|
|
25861
|
+
const targetDir = process.cwd();
|
|
25862
|
+
requireOcrSetup(targetDir);
|
|
25863
|
+
const ocrDir = join18(targetDir, ".ocr");
|
|
25864
|
+
if (!options.stdin) {
|
|
25865
|
+
try {
|
|
25866
|
+
const reviewersDir = join18(ocrDir, "skills", "references", "reviewers");
|
|
25867
|
+
const configPath = join18(ocrDir, "config.yaml");
|
|
25868
|
+
const meta = generateReviewersMeta(reviewersDir, configPath);
|
|
25869
|
+
if (!meta || meta.reviewers.length === 0) {
|
|
25870
|
+
console.error(source_default.yellow("No reviewer files found in .ocr/skills/references/reviewers/"));
|
|
25871
|
+
process.exit(1);
|
|
25872
|
+
}
|
|
25873
|
+
const metaPath = join18(ocrDir, "reviewers-meta.json");
|
|
25874
|
+
const tmpPath = metaPath + ".tmp";
|
|
25875
|
+
writeFileSync8(tmpPath, JSON.stringify(meta, null, 2) + "\n");
|
|
25876
|
+
renameSync2(tmpPath, metaPath);
|
|
25877
|
+
const tierCounts = meta.reviewers.reduce(
|
|
25878
|
+
(acc, r) => {
|
|
25879
|
+
acc[r.tier] = (acc[r.tier] ?? 0) + 1;
|
|
25880
|
+
return acc;
|
|
25881
|
+
},
|
|
25882
|
+
{}
|
|
25883
|
+
);
|
|
25884
|
+
const breakdown = Object.entries(tierCounts).map(([tier, count]) => `${count} ${tier}`).join(", ");
|
|
25885
|
+
console.log(source_default.green(`Synced ${meta.reviewers.length} reviewer(s) (${breakdown}).`));
|
|
25886
|
+
} catch (error) {
|
|
25887
|
+
console.error(
|
|
25888
|
+
source_default.red(`Error: ${error instanceof Error ? error.message : "Failed to sync reviewers"}`)
|
|
25889
|
+
);
|
|
25890
|
+
process.exit(1);
|
|
25891
|
+
}
|
|
25892
|
+
return;
|
|
25893
|
+
}
|
|
25894
|
+
try {
|
|
25895
|
+
const raw = await readStdin2();
|
|
25896
|
+
let parsed;
|
|
25897
|
+
try {
|
|
25898
|
+
parsed = JSON.parse(raw);
|
|
25899
|
+
} catch {
|
|
25900
|
+
throw new Error("Invalid JSON on stdin");
|
|
25901
|
+
}
|
|
25902
|
+
const meta = validateReviewersMeta(parsed);
|
|
25903
|
+
const metaPath = join18(ocrDir, "reviewers-meta.json");
|
|
25904
|
+
const tmpPath = metaPath + ".tmp";
|
|
25905
|
+
writeFileSync8(tmpPath, JSON.stringify(meta, null, 2) + "\n");
|
|
25906
|
+
renameSync2(tmpPath, metaPath);
|
|
25907
|
+
const tierCounts = meta.reviewers.reduce(
|
|
25908
|
+
(acc, r) => {
|
|
25909
|
+
acc[r.tier] = (acc[r.tier] ?? 0) + 1;
|
|
25910
|
+
return acc;
|
|
25911
|
+
},
|
|
25912
|
+
{}
|
|
25913
|
+
);
|
|
25914
|
+
const breakdown = Object.entries(tierCounts).map(([tier, count]) => `${count} ${tier}`).join(", ");
|
|
25915
|
+
console.log(
|
|
25916
|
+
source_default.green(`Synced ${meta.reviewers.length} reviewer(s) (${breakdown}).`)
|
|
25917
|
+
);
|
|
25918
|
+
} catch (error) {
|
|
25919
|
+
console.error(
|
|
25920
|
+
source_default.red(
|
|
25921
|
+
`Error: ${error instanceof Error ? error.message : "Failed to sync reviewers"}`
|
|
25922
|
+
)
|
|
25923
|
+
);
|
|
25924
|
+
process.exit(1);
|
|
25925
|
+
}
|
|
25926
|
+
});
|
|
25927
|
+
var reviewersCommand = new Command("reviewers").description("Manage OCR reviewer metadata").addCommand(syncSubcommand2);
|
|
25928
|
+
|
|
25619
25929
|
// src/lib/update-check.ts
|
|
25620
25930
|
import { homedir } from "node:os";
|
|
25621
|
-
import { join as
|
|
25622
|
-
import { readFileSync as readFileSync10, writeFileSync as
|
|
25931
|
+
import { join as join19 } from "node:path";
|
|
25932
|
+
import { readFileSync as readFileSync10, writeFileSync as writeFileSync9, mkdirSync as mkdirSync6 } from "node:fs";
|
|
25623
25933
|
var PACKAGE_NAME = "@open-code-review/cli";
|
|
25624
25934
|
var REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
|
|
25625
|
-
var CACHE_DIR =
|
|
25626
|
-
var CACHE_FILE =
|
|
25935
|
+
var CACHE_DIR = join19(homedir(), ".ocr");
|
|
25936
|
+
var CACHE_FILE = join19(CACHE_DIR, "update-check.json");
|
|
25627
25937
|
var CHECK_INTERVAL_MS = 4 * 60 * 60 * 1e3;
|
|
25628
25938
|
var FETCH_TIMEOUT_MS = 3e3;
|
|
25629
25939
|
function readCache(cacheFile) {
|
|
@@ -25635,8 +25945,8 @@ function readCache(cacheFile) {
|
|
|
25635
25945
|
}
|
|
25636
25946
|
function writeCache(cacheFile, cache) {
|
|
25637
25947
|
try {
|
|
25638
|
-
mkdirSync6(
|
|
25639
|
-
|
|
25948
|
+
mkdirSync6(join19(cacheFile, ".."), { recursive: true });
|
|
25949
|
+
writeFileSync9(cacheFile, JSON.stringify(cache));
|
|
25640
25950
|
} catch {
|
|
25641
25951
|
}
|
|
25642
25952
|
}
|
|
@@ -25656,7 +25966,7 @@ async function checkForUpdate(currentVersion, options) {
|
|
|
25656
25966
|
if (process.env.CI || process.env.OCR_NO_UPDATE_CHECK) {
|
|
25657
25967
|
return null;
|
|
25658
25968
|
}
|
|
25659
|
-
const cacheFile =
|
|
25969
|
+
const cacheFile = join19(options?.cacheDir ?? CACHE_DIR, "update-check.json");
|
|
25660
25970
|
try {
|
|
25661
25971
|
const cache = readCache(cacheFile);
|
|
25662
25972
|
if (cache && Date.now() - cache.lastCheck < CHECK_INTERVAL_MS) {
|
|
@@ -25700,19 +26010,25 @@ ${line2}
|
|
|
25700
26010
|
}
|
|
25701
26011
|
|
|
25702
26012
|
// src/index.ts
|
|
25703
|
-
var cliVersion = true ? "1.6.0" : createRequire(import.meta.url)("../package.json").version;
|
|
25704
26013
|
var HUMAN_COMMANDS = /* @__PURE__ */ new Set(["init", "update", "doctor", "dashboard", "progress"]);
|
|
25705
26014
|
var subcommand = process.argv[2];
|
|
25706
|
-
var updateCheck = subcommand && HUMAN_COMMANDS.has(subcommand) ? checkForUpdate(
|
|
26015
|
+
var updateCheck = subcommand && HUMAN_COMMANDS.has(subcommand) ? checkForUpdate(CLI_VERSION) : null;
|
|
25707
26016
|
var program2 = new Command();
|
|
25708
|
-
program2.name("ocr").description("Open Code Review - AI-powered multi-agent code review").version(
|
|
26017
|
+
program2.name("ocr").description("Open Code Review - AI-powered multi-agent code review").version(CLI_VERSION);
|
|
25709
26018
|
program2.addCommand(initCommand);
|
|
25710
26019
|
program2.addCommand(progressCommand);
|
|
25711
26020
|
program2.addCommand(stateCommand);
|
|
25712
26021
|
program2.addCommand(updateCommand);
|
|
25713
26022
|
program2.addCommand(dashboardCommand);
|
|
25714
26023
|
program2.addCommand(doctorCommand);
|
|
26024
|
+
program2.addCommand(reviewersCommand);
|
|
25715
26025
|
await program2.parseAsync();
|
|
26026
|
+
if (subcommand && HUMAN_COMMANDS.has(subcommand)) {
|
|
26027
|
+
const drift = checkLocalArtifactVersion(process.cwd(), CLI_VERSION);
|
|
26028
|
+
if (drift) {
|
|
26029
|
+
printLocalVersionHint(drift);
|
|
26030
|
+
}
|
|
26031
|
+
}
|
|
25716
26032
|
if (updateCheck) {
|
|
25717
26033
|
const updateResult = await Promise.race([
|
|
25718
26034
|
updateCheck,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-code-review/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "CLI for Open Code Review - Multi-environment setup and progress tracking",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"ora": "^8.1.1",
|
|
51
51
|
"socket.io": "^4.8",
|
|
52
52
|
"sql.js": "^1.14.1",
|
|
53
|
-
"@open-code-review/agents": "1.
|
|
53
|
+
"@open-code-review/agents": "1.8.0"
|
|
54
54
|
},
|
|
55
55
|
"publishConfig": {
|
|
56
56
|
"access": "public"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{ap as o,aq as n}from"./mermaid-renderer-DGUmIWXY.js";const t=(a,r)=>o.lang.round(n.parse(a)[r]);export{t as c};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,c as s,a as e,C as t}from"./chunk-B4BG7PRW-BXzTPbH1.js";import{_ as i}from"./mermaid-renderer-DGUmIWXY.js";import"./chunk-FMBD7UC4-B4g9S67N.js";import"./chunk-55IACEB6-C4SjgsZO.js";import"./chunk-QN33PNHL-Dyk7Hc0J.js";import"./index-BzQ3i_QR.js";var u={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{u as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,c as s,a as e,C as t}from"./chunk-B4BG7PRW-BXzTPbH1.js";import{_ as i}from"./mermaid-renderer-DGUmIWXY.js";import"./chunk-FMBD7UC4-B4g9S67N.js";import"./chunk-55IACEB6-C4SjgsZO.js";import"./chunk-QN33PNHL-Dyk7Hc0J.js";import"./index-BzQ3i_QR.js";var u={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{u as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{b as r}from"./_baseUniq-Bx8loabg.js";var e=4;function a(o){return r(o,e)}export{a as c};
|