@nk070281sjv/cli 2.3.21 → 2.3.23
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 +7 -18
- package/dist/index.js +157 -147
- package/package.json +2 -3
- package/dist/dashboard/client/assets/_basePickBy-CZOJm2vF.js +0 -1
- package/dist/dashboard/client/assets/_baseUniq-BNrzwRTV.js +0 -1
- package/dist/dashboard/client/assets/arc-Bl8fh4M2.js +0 -1
- package/dist/dashboard/client/assets/architectureDiagram-VXUJARFQ-TTtHv-xF.js +0 -36
- package/dist/dashboard/client/assets/blockDiagram-VD42YOAC-Civ0_twg.js +0 -122
- package/dist/dashboard/client/assets/c4Diagram-YG6GDRKO-FpPihNtg.js +0 -10
- package/dist/dashboard/client/assets/channel-BXL5vtDv.js +0 -1
- package/dist/dashboard/client/assets/chunk-4BX2VUAB-DPa8WBIp.js +0 -1
- package/dist/dashboard/client/assets/chunk-55IACEB6-BxRzcpzA.js +0 -1
- package/dist/dashboard/client/assets/chunk-B4BG7PRW-DajTgf2c.js +0 -165
- package/dist/dashboard/client/assets/chunk-DI55MBZ5-iF7jh16b.js +0 -220
- package/dist/dashboard/client/assets/chunk-FMBD7UC4-BNfvHrjT.js +0 -15
- package/dist/dashboard/client/assets/chunk-QN33PNHL-DDEcP3Rr.js +0 -1
- package/dist/dashboard/client/assets/chunk-QZHKN3VN-CNrv8PPa.js +0 -1
- package/dist/dashboard/client/assets/chunk-TZMSLE5B-Cf7ruLpv.js +0 -1
- package/dist/dashboard/client/assets/classDiagram-2ON5EDUG-l6aRknEX.js +0 -1
- package/dist/dashboard/client/assets/classDiagram-v2-WZHVMYZB-l6aRknEX.js +0 -1
- package/dist/dashboard/client/assets/clone-DlyIkpMA.js +0 -1
- package/dist/dashboard/client/assets/cose-bilkent-S5V4N54A-BLdeLAXN.js +0 -1
- package/dist/dashboard/client/assets/cytoscape.esm-DtBltrT8.js +0 -331
- package/dist/dashboard/client/assets/dagre-6UL2VRFP-BJ4sOJMG.js +0 -4
- package/dist/dashboard/client/assets/defaultLocale-DX6XiGOO.js +0 -1
- package/dist/dashboard/client/assets/diagram-PSM6KHXK-6bnUwEUL.js +0 -24
- package/dist/dashboard/client/assets/diagram-QEK2KX5R-BVM40PZZ.js +0 -43
- package/dist/dashboard/client/assets/diagram-S2PKOQOG-Bymzcnfw.js +0 -24
- package/dist/dashboard/client/assets/erDiagram-Q2GNP2WA-BVADk0og.js +0 -60
- package/dist/dashboard/client/assets/flowDiagram-NV44I4VS-_eGXTmsk.js +0 -162
- package/dist/dashboard/client/assets/ganttDiagram-JELNMOA3-CX3MM-Kg.js +0 -267
- package/dist/dashboard/client/assets/gitGraphDiagram-V2S2FVAM-CkKtnGnz.js +0 -65
- package/dist/dashboard/client/assets/graph-DHnUlkk_.js +0 -1
- package/dist/dashboard/client/assets/index-Czwdh6UA.css +0 -1
- package/dist/dashboard/client/assets/index-D9drpDt3.js +0 -581
- package/dist/dashboard/client/assets/infoDiagram-HS3SLOUP-D9BnKoPB.js +0 -2
- package/dist/dashboard/client/assets/init-Gi6I4Gst.js +0 -1
- package/dist/dashboard/client/assets/journeyDiagram-XKPGCS4Q-DS_q4bTn.js +0 -139
- package/dist/dashboard/client/assets/kanban-definition-3W4ZIXB7-8_1dZaX4.js +0 -89
- package/dist/dashboard/client/assets/katex-DGN8GczM.js +0 -261
- package/dist/dashboard/client/assets/layout-CsLHITt3.js +0 -1
- package/dist/dashboard/client/assets/linear-CCtPUyi6.js +0 -1
- package/dist/dashboard/client/assets/mermaid-renderer-YLFCVv-z.js +0 -256
- package/dist/dashboard/client/assets/mindmap-definition-VGOIOE7T-DR-LlyOU.js +0 -68
- package/dist/dashboard/client/assets/ordinal-Cboi1Yqb.js +0 -1
- package/dist/dashboard/client/assets/pieDiagram-ADFJNKIX-Bb5Zk2R3.js +0 -30
- package/dist/dashboard/client/assets/quadrantDiagram-AYHSOK5B-jsjp4NWV.js +0 -7
- package/dist/dashboard/client/assets/requirementDiagram-UZGBJVZJ-fAoABRs-.js +0 -64
- package/dist/dashboard/client/assets/sankeyDiagram-TZEHDZUN-BTJZKbMB.js +0 -10
- package/dist/dashboard/client/assets/sequenceDiagram-WL72ISMW-D1CT5eZr.js +0 -145
- package/dist/dashboard/client/assets/stateDiagram-FKZM4ZOC-BOuyRm06.js +0 -1
- package/dist/dashboard/client/assets/stateDiagram-v2-4FDKWEC3-DtmMH8sN.js +0 -1
- package/dist/dashboard/client/assets/timeline-definition-IT6M3QCI-IT_de2GW.js +0 -61
- package/dist/dashboard/client/assets/treemap-GDKQZRPO-ChPy-xEn.js +0 -162
- package/dist/dashboard/client/assets/xychartDiagram-PRI3JC2R-CNHEwC5B.js +0 -7
- package/dist/dashboard/client/favicon-dark.ico +0 -0
- package/dist/dashboard/client/favicon-light.ico +0 -0
- package/dist/dashboard/client/index.html +0 -15
- package/dist/dashboard/server.js +0 -39726
package/dist/index.js
CHANGED
|
@@ -16686,10 +16686,6 @@ var init_counts = __esm({
|
|
|
16686
16686
|
});
|
|
16687
16687
|
|
|
16688
16688
|
// ../shared/platform/src/index.ts
|
|
16689
|
-
import { pathToFileURL } from "node:url";
|
|
16690
|
-
async function importModule(absolutePath) {
|
|
16691
|
-
return import(pathToFileURL(absolutePath).href);
|
|
16692
|
-
}
|
|
16693
16689
|
function killErrorMeansDead(err) {
|
|
16694
16690
|
return err instanceof Error && "code" in err && err.code === "ESRCH";
|
|
16695
16691
|
}
|
|
@@ -30779,7 +30775,7 @@ ${hint}
|
|
|
30779
30775
|
}
|
|
30780
30776
|
|
|
30781
30777
|
// src/lib/version.ts
|
|
30782
|
-
var CLI_VERSION = true ? "2.3.
|
|
30778
|
+
var CLI_VERSION = true ? "2.3.23" : createRequire(import.meta.url)("../../package.json").version;
|
|
30783
30779
|
|
|
30784
30780
|
// src/lib/deps.ts
|
|
30785
30781
|
init_src();
|
|
@@ -30788,7 +30784,7 @@ var CATEGORY_INFO = {
|
|
|
30788
30784
|
core: { label: "Core", hint: "" },
|
|
30789
30785
|
"ai-cli": {
|
|
30790
30786
|
label: "AI CLI",
|
|
30791
|
-
hint: "powers
|
|
30787
|
+
hint: "powers CLI/OpenCode review commands"
|
|
30792
30788
|
},
|
|
30793
30789
|
github: {
|
|
30794
30790
|
label: "GitHub Integration",
|
|
@@ -30925,13 +30921,13 @@ function printCapabilities(result) {
|
|
|
30925
30921
|
},
|
|
30926
30922
|
{
|
|
30927
30923
|
ok: true,
|
|
30928
|
-
label: "
|
|
30929
|
-
detail: "ocr
|
|
30924
|
+
label: "CLI artifacts",
|
|
30925
|
+
detail: "browse .ocr/sessions and use review status/watch"
|
|
30930
30926
|
},
|
|
30931
30927
|
{
|
|
30932
30928
|
ok: caps.dashboardAi,
|
|
30933
|
-
label: "
|
|
30934
|
-
detail: caps.dashboardAi ? "
|
|
30929
|
+
label: "AI review commands",
|
|
30930
|
+
detail: caps.dashboardAi ? "/ocr-review and process-agent reviews" : "Install Claude Code or OpenCode to enable"
|
|
30935
30931
|
},
|
|
30936
30932
|
{
|
|
30937
30933
|
ok: caps.githubPost,
|
|
@@ -31076,16 +31072,16 @@ var initCommand = new Command("init").description("Set up OCR for AI coding envi
|
|
|
31076
31072
|
);
|
|
31077
31073
|
console.log();
|
|
31078
31074
|
console.log(
|
|
31079
|
-
` ${source_default.cyan("3.")} Run ${source_default.yellow("ocr
|
|
31075
|
+
` ${source_default.cyan("3.")} Run ${source_default.yellow("ocr review run-agents --fresh")} from your project or use the installed /ocr-review command.`
|
|
31080
31076
|
);
|
|
31081
31077
|
if (depResult.capabilities.dashboardAi) {
|
|
31082
31078
|
console.log(
|
|
31083
|
-
source_default.dim("
|
|
31079
|
+
source_default.dim(" AI review commands are ready.")
|
|
31084
31080
|
);
|
|
31085
31081
|
} else {
|
|
31086
31082
|
console.log(
|
|
31087
31083
|
source_default.dim(
|
|
31088
|
-
"
|
|
31084
|
+
" Install Claude Code or OpenCode for AI review execution."
|
|
31089
31085
|
)
|
|
31090
31086
|
);
|
|
31091
31087
|
}
|
|
@@ -31821,9 +31817,9 @@ var NodeFsHandler = class {
|
|
|
31821
31817
|
if (this.fsw.closed) {
|
|
31822
31818
|
return;
|
|
31823
31819
|
}
|
|
31824
|
-
const
|
|
31820
|
+
const dirname12 = sysPath.dirname(file);
|
|
31825
31821
|
const basename9 = sysPath.basename(file);
|
|
31826
|
-
const parent = this.fsw._getWatchedDir(
|
|
31822
|
+
const parent = this.fsw._getWatchedDir(dirname12);
|
|
31827
31823
|
let prevStats = stats;
|
|
31828
31824
|
if (parent.has(basename9))
|
|
31829
31825
|
return;
|
|
@@ -31850,7 +31846,7 @@ var NodeFsHandler = class {
|
|
|
31850
31846
|
prevStats = newStats2;
|
|
31851
31847
|
}
|
|
31852
31848
|
} catch (error) {
|
|
31853
|
-
this.fsw._remove(
|
|
31849
|
+
this.fsw._remove(dirname12, basename9);
|
|
31854
31850
|
}
|
|
31855
31851
|
} else if (parent.has(basename9)) {
|
|
31856
31852
|
const at = newStats.atimeMs;
|
|
@@ -34983,6 +34979,12 @@ var VALID_SEVERITIES2 = /* @__PURE__ */ new Set([
|
|
|
34983
34979
|
"low",
|
|
34984
34980
|
"info"
|
|
34985
34981
|
]);
|
|
34982
|
+
var VALID_AGGREGATION_SEVERITIES = /* @__PURE__ */ new Set([
|
|
34983
|
+
"critical",
|
|
34984
|
+
"high",
|
|
34985
|
+
"medium",
|
|
34986
|
+
"low"
|
|
34987
|
+
]);
|
|
34986
34988
|
var VALID_CATEGORIES2 = /* @__PURE__ */ new Set([
|
|
34987
34989
|
"blocker",
|
|
34988
34990
|
"should_fix",
|
|
@@ -35025,12 +35027,15 @@ function validateAggregationJson(value) {
|
|
|
35025
35027
|
if (!f) return;
|
|
35026
35028
|
expectString(f.id, `findings[${index}].id`, errors);
|
|
35027
35029
|
expectString(f.title, `findings[${index}].title`, errors);
|
|
35028
|
-
expectStringArray(f.
|
|
35030
|
+
expectStringArray(f.src, `findings[${index}].src`, errors);
|
|
35029
35031
|
expectEnum(f.signal, VALID_SIGNALS, `findings[${index}].signal`, errors);
|
|
35030
|
-
expectEnum(f.severity,
|
|
35031
|
-
|
|
35032
|
-
expectString(f.
|
|
35033
|
-
expectString(f.
|
|
35032
|
+
expectEnum(f.severity, VALID_AGGREGATION_SEVERITIES, `findings[${index}].severity`, errors);
|
|
35033
|
+
expectStringArray(f.files, `findings[${index}].files`, errors);
|
|
35034
|
+
expectString(f.claim, `findings[${index}].claim`, errors);
|
|
35035
|
+
expectString(f.evidence, `findings[${index}].evidence`, errors);
|
|
35036
|
+
expectString(f.impact, `findings[${index}].impact`, errors);
|
|
35037
|
+
expectStringArray(f.validate, `findings[${index}].validate`, errors);
|
|
35038
|
+
expectString(f.fix, `findings[${index}].fix`, errors);
|
|
35034
35039
|
});
|
|
35035
35040
|
}
|
|
35036
35041
|
const dropped = expectArray(obj.dropped, "dropped", errors);
|
|
@@ -35038,7 +35043,7 @@ function validateAggregationJson(value) {
|
|
|
35038
35043
|
dropped.forEach((drop, index) => {
|
|
35039
35044
|
const d = expectObject(drop, `dropped[${index}]`, errors);
|
|
35040
35045
|
if (!d) return;
|
|
35041
|
-
expectStringArray(d.
|
|
35046
|
+
expectStringArray(d.src, `dropped[${index}].src`, errors);
|
|
35042
35047
|
expectString(d.reason, `dropped[${index}].reason`, errors);
|
|
35043
35048
|
});
|
|
35044
35049
|
}
|
|
@@ -36319,7 +36324,7 @@ function readDashboardSpawnMarker(ocrDir) {
|
|
|
36319
36324
|
if (live.length > 1) {
|
|
36320
36325
|
console.error(
|
|
36321
36326
|
source_default.gray(
|
|
36322
|
-
`[state] ${live.length} concurrent
|
|
36327
|
+
`[state] ${live.length} concurrent external launches live; marker fallback is ambiguous \u2014 pass --dashboard-uid for linkage`
|
|
36323
36328
|
)
|
|
36324
36329
|
);
|
|
36325
36330
|
return null;
|
|
@@ -36343,7 +36348,7 @@ async function linkDashboardInvocation(ocrDir, sessionId, explicitUid, label) {
|
|
|
36343
36348
|
if (!dashboardUid) {
|
|
36344
36349
|
console.error(
|
|
36345
36350
|
source_default.gray(
|
|
36346
|
-
`[state ${label}] no
|
|
36351
|
+
`[state ${label}] no external-launch linkage available (flag, env var, and marker file all absent \u2014 CLI-only invocation)`
|
|
36347
36352
|
)
|
|
36348
36353
|
);
|
|
36349
36354
|
return;
|
|
@@ -36353,13 +36358,13 @@ async function linkDashboardInvocation(ocrDir, sessionId, explicitUid, label) {
|
|
|
36353
36358
|
linkDashboardInvocationToWorkflow(db, dashboardUid, sessionId);
|
|
36354
36359
|
console.error(
|
|
36355
36360
|
source_default.gray(
|
|
36356
|
-
`[state ${label}] linked workflow_id=${sessionId} \u2192
|
|
36361
|
+
`[state ${label}] linked workflow_id=${sessionId} \u2192 launcher uid=${dashboardUid}`
|
|
36357
36362
|
)
|
|
36358
36363
|
);
|
|
36359
36364
|
} catch (linkErr) {
|
|
36360
36365
|
console.error(
|
|
36361
36366
|
source_default.yellow(
|
|
36362
|
-
`Warning: failed to link
|
|
36367
|
+
`Warning: failed to link launcher command_execution to session: ${linkErr instanceof Error ? linkErr.message : String(linkErr)}`
|
|
36363
36368
|
)
|
|
36364
36369
|
);
|
|
36365
36370
|
}
|
|
@@ -36517,7 +36522,7 @@ var beginSubcommand = new Command("begin").description("Start or resume a workfl
|
|
|
36517
36522
|
return v;
|
|
36518
36523
|
}).option("--session-dir <dir>", "Session directory path (auto-resolved if omitted)").option(
|
|
36519
36524
|
"--dashboard-uid <uid>",
|
|
36520
|
-
"
|
|
36525
|
+
"External launcher command_executions uid to link this workflow to (takes precedence over OCR_DASHBOARD_EXECUTION_UID)"
|
|
36521
36526
|
).option("--json", "Output the result as JSON").action(
|
|
36522
36527
|
async (options) => {
|
|
36523
36528
|
const targetDir = process.cwd();
|
|
@@ -37425,12 +37430,10 @@ async function writeRoundArtifact(roundDir, relativePath, content) {
|
|
|
37425
37430
|
}
|
|
37426
37431
|
|
|
37427
37432
|
// src/lib/agent-orchestrator/context-prep.ts
|
|
37433
|
+
init_src();
|
|
37428
37434
|
import { mkdir as mkdir2, readFile, writeFile as writeFile2 } from "node:fs/promises";
|
|
37429
37435
|
import { existsSync as existsSync21 } from "node:fs";
|
|
37430
37436
|
import { dirname as dirname10, join as join25 } from "node:path";
|
|
37431
|
-
import { execFile } from "node:child_process";
|
|
37432
|
-
import { promisify } from "node:util";
|
|
37433
|
-
var execFileAsync = promisify(execFile);
|
|
37434
37437
|
var GIT_SUMMARY_LIMIT = 2e4;
|
|
37435
37438
|
var REVIEW_SNAPSHOT_EXCLUDES = [".ocr", ".opencode"];
|
|
37436
37439
|
async function prepareReviewContext(input) {
|
|
@@ -37622,9 +37625,10 @@ async function resolveDefaultRemoteBase(cwd) {
|
|
|
37622
37625
|
}
|
|
37623
37626
|
async function runGit(cwd, args, limit = GIT_SUMMARY_LIMIT) {
|
|
37624
37627
|
try {
|
|
37625
|
-
const { stdout, stderr } = await
|
|
37628
|
+
const { stdout, stderr } = await execBinaryAsync("git", args, {
|
|
37626
37629
|
cwd,
|
|
37627
|
-
maxBuffer: limit * 2
|
|
37630
|
+
maxBuffer: limit * 2,
|
|
37631
|
+
encoding: "utf8"
|
|
37628
37632
|
});
|
|
37629
37633
|
return truncate(`${stdout}${stderr ? `
|
|
37630
37634
|
${stderr}` : ""}`.trim(), limit);
|
|
@@ -38034,14 +38038,41 @@ async function reviewerPrompt(context, reviewer, promptPath, reviewPath, sharedP
|
|
|
38034
38038
|
"- Apply the reviewer persona file as your primary review lens.",
|
|
38035
38039
|
"- Use the review brief as the source of truth for changed files and scope.",
|
|
38036
38040
|
"- Inspect surrounding source code only when needed to validate a finding.",
|
|
38041
|
+
"- Rank by concrete risk: data loss, wrong persisted state, broken public contract, security, production performance, then testability.",
|
|
38037
38042
|
"",
|
|
38038
38043
|
"Output contract:",
|
|
38039
38044
|
`- Return review markdown through stdout for ${reviewPath}.`,
|
|
38045
|
+
"- Return only one fenced ```ocr-json block and no prose outside it.",
|
|
38046
|
+
"- Include maximum 10 findings, sorted by severity and production impact.",
|
|
38047
|
+
"- No introductions, no progress narration, no endpoint tables, no code snippets, no broad summaries.",
|
|
38048
|
+
"- Include critical, high, and medium findings. Include low only when it has concrete runtime/user impact. Exclude info/style/theoretical-only items.",
|
|
38049
|
+
"- Do not include fix instructions; aggregation and synthesis will produce fix direction after deduplication and validation.",
|
|
38050
|
+
"- Exclude any item that does not have concrete `files` and `evidence`.",
|
|
38040
38051
|
"- Do not write files directly.",
|
|
38041
38052
|
"- Do not claim skipped agents ran.",
|
|
38042
38053
|
"",
|
|
38043
38054
|
"Required ocr-json schema:",
|
|
38044
|
-
"-
|
|
38055
|
+
"- Output exactly this compact JSON shape inside the fenced block:",
|
|
38056
|
+
"",
|
|
38057
|
+
"```json",
|
|
38058
|
+
"{",
|
|
38059
|
+
' "findings": [',
|
|
38060
|
+
" {",
|
|
38061
|
+
' "sev": "high",',
|
|
38062
|
+
' "title": "Short finding title",',
|
|
38063
|
+
' "files": ["src/main/java/example/File.java:42"],',
|
|
38064
|
+
' "claim": "What may be wrong.",',
|
|
38065
|
+
' "evidence": "Concrete code evidence.",',
|
|
38066
|
+
' "impact": "Runtime/user/system impact if confirmed.",',
|
|
38067
|
+
' "confidence": "high"',
|
|
38068
|
+
" }",
|
|
38069
|
+
" ]",
|
|
38070
|
+
"}",
|
|
38071
|
+
"```",
|
|
38072
|
+
"",
|
|
38073
|
+
'- `sev` must be one of: "critical", "high", "medium", "low".',
|
|
38074
|
+
'- `confidence` must be one of: "high", "medium", "low".',
|
|
38075
|
+
"- Keep every string under roughly 240 characters.",
|
|
38045
38076
|
"",
|
|
38046
38077
|
"Forbidden behavior:",
|
|
38047
38078
|
`- Do not modify ${promptPath} or ${reviewPath}.`,
|
|
@@ -38151,6 +38182,11 @@ function pipelinePrompt(context, stage, agent, promptPath, artifactPath) {
|
|
|
38151
38182
|
"- Preserve markdown structure, headings, bullets, code spans, file paths, line numbers, and the fenced ```ocr-json block exactly as data.",
|
|
38152
38183
|
"- Do not translate JSON field names, enum values, file paths, code identifiers, stack traces, commands, or model names.",
|
|
38153
38184
|
"- Do not add new findings, remove findings, change severity/category/verdict, or change counts."
|
|
38185
|
+
] : stage === "aggregation" ? [
|
|
38186
|
+
"- Return only one fenced ```ocr-json block and no prose outside it.",
|
|
38187
|
+
"- Keep the output compact: at most 8 findings and at most 12 dropped entries.",
|
|
38188
|
+
"- Do not include code snippets, long quotes, markdown tables, or reviewer narrative.",
|
|
38189
|
+
"- Read the original reviewer files, but aggregate only their structured findings and concrete evidence."
|
|
38154
38190
|
] : ["- Include exactly one fenced ```ocr-json block."],
|
|
38155
38191
|
"- Do not write files directly.",
|
|
38156
38192
|
"",
|
|
@@ -38173,8 +38209,14 @@ function schemaHint(stage) {
|
|
|
38173
38209
|
if (stage === "aggregation") {
|
|
38174
38210
|
return [
|
|
38175
38211
|
"AggregationJson:",
|
|
38176
|
-
"- Output exactly this JSON shape inside one fenced ```ocr-json block.",
|
|
38212
|
+
"- Output exactly this compact JSON shape inside one fenced ```ocr-json block.",
|
|
38177
38213
|
"- Do not rename fields. Do not use markdown tables inside the JSON block.",
|
|
38214
|
+
"- Keep only high-signal findings that a developer or validation agent can act on.",
|
|
38215
|
+
"- Merge duplicates across reviewers into one finding with multiple `src` references.",
|
|
38216
|
+
"- Severity gate:",
|
|
38217
|
+
" - Keep critical, high, and medium findings.",
|
|
38218
|
+
" - Keep low only when duplicated by 2+ reviewers or when it has concrete production/runtime impact.",
|
|
38219
|
+
" - Drop info, style, theoretical-only, and future-extensibility-only items.",
|
|
38178
38220
|
"",
|
|
38179
38221
|
"```json",
|
|
38180
38222
|
"{",
|
|
@@ -38182,17 +38224,20 @@ function schemaHint(stage) {
|
|
|
38182
38224
|
" {",
|
|
38183
38225
|
' "id": "agg-1",',
|
|
38184
38226
|
' "title": "Short finding title",',
|
|
38185
|
-
' "
|
|
38227
|
+
' "src": ["architect-1:finding-or-heading"],',
|
|
38186
38228
|
' "signal": "keep",',
|
|
38187
38229
|
' "severity": "high",',
|
|
38188
|
-
' "
|
|
38189
|
-
' "
|
|
38190
|
-
' "
|
|
38230
|
+
' "files": ["src/main/java/example/File.java:42"],',
|
|
38231
|
+
' "claim": "What may be wrong, stated as a verifiable hypothesis.",',
|
|
38232
|
+
' "evidence": "Why reviewers believe this may be wrong.",',
|
|
38233
|
+
' "impact": "What user/system behavior would be affected if confirmed.",',
|
|
38234
|
+
' "validate": ["Check the write path for a uniqueness boundary."],',
|
|
38235
|
+
' "fix": "Concrete direction for the fix."',
|
|
38191
38236
|
" }",
|
|
38192
38237
|
" ],",
|
|
38193
38238
|
' "dropped": [',
|
|
38194
38239
|
" {",
|
|
38195
|
-
' "
|
|
38240
|
+
' "src": ["performance-1:finding-or-heading"],',
|
|
38196
38241
|
' "reason": "Why this reviewer finding is noise or duplicate."',
|
|
38197
38242
|
" }",
|
|
38198
38243
|
" ]",
|
|
@@ -38200,8 +38245,10 @@ function schemaHint(stage) {
|
|
|
38200
38245
|
"```",
|
|
38201
38246
|
"",
|
|
38202
38247
|
'- `signal` must be one of: "keep", "merge", "needs_validation", "likely_noise", "false_positive_candidate".',
|
|
38203
|
-
'- `severity` must be one of: "critical", "high", "medium", "low"
|
|
38204
|
-
"- `
|
|
38248
|
+
'- `severity` must be one of: "critical", "high", "medium", "low".',
|
|
38249
|
+
"- `src`, `files`, and `validate` must always be arrays of non-empty strings.",
|
|
38250
|
+
"- Limit each string field to roughly 320 characters. Limit arrays to the most relevant entries.",
|
|
38251
|
+
"- Prefer dropping low/info/style-only noise over producing an overlong aggregation."
|
|
38205
38252
|
].join("\n");
|
|
38206
38253
|
}
|
|
38207
38254
|
if (stage === "validation") {
|
|
@@ -38209,6 +38256,9 @@ function schemaHint(stage) {
|
|
|
38209
38256
|
"ValidationJson:",
|
|
38210
38257
|
"- Output exactly this JSON shape inside one fenced ```ocr-json block.",
|
|
38211
38258
|
"- Do not rename fields. Do not use markdown tables inside the JSON block.",
|
|
38259
|
+
"- Use aggregation `claim`, `evidence`, `files`, and `validate` as the checklist for each finding.",
|
|
38260
|
+
"- Verify claims against the actual code before confirming. Do not trust reviewer text without code evidence.",
|
|
38261
|
+
"- Put every aggregation finding into exactly one of `confirmed`, `downgraded`, or `rejected`.",
|
|
38212
38262
|
"",
|
|
38213
38263
|
"```json",
|
|
38214
38264
|
"{",
|
|
@@ -38249,6 +38299,8 @@ function schemaHint(stage) {
|
|
|
38249
38299
|
"SynthesisJson:",
|
|
38250
38300
|
"- Output exactly this JSON shape inside one fenced ```ocr-json block.",
|
|
38251
38301
|
"- Do not rename fields. Do not use markdown tables inside the JSON block.",
|
|
38302
|
+
"- Write developer-facing findings from validation results, not from unvalidated reviewer claims.",
|
|
38303
|
+
"- Include only confirmed and downgraded issues that a developer can act on.",
|
|
38252
38304
|
"",
|
|
38253
38305
|
"```json",
|
|
38254
38306
|
"{",
|
|
@@ -38344,7 +38396,7 @@ async function runReviewerPhase(input) {
|
|
|
38344
38396
|
prompt_path: request.promptPath,
|
|
38345
38397
|
meta_log: startLogPaths.meta
|
|
38346
38398
|
});
|
|
38347
|
-
const result = await input.runner.run(request, controller.signal);
|
|
38399
|
+
const result = normalizeProcessResult(await input.runner.run(request, controller.signal));
|
|
38348
38400
|
const logPaths = await writeProcessLogs(input.context.roundDir, request, result);
|
|
38349
38401
|
running.delete(request.id);
|
|
38350
38402
|
completed.add(request.id);
|
|
@@ -38361,7 +38413,7 @@ async function runReviewerPhase(input) {
|
|
|
38361
38413
|
if (vendorId) await journal.bindVendorId(agentSessionId, vendorId);
|
|
38362
38414
|
await journal.endInstance(agentSessionId, {
|
|
38363
38415
|
exitCode: result.exitCode,
|
|
38364
|
-
note: result.stderr.trim() ||
|
|
38416
|
+
note: result.stderr.trim() || failureNoteForResult(result)
|
|
38365
38417
|
});
|
|
38366
38418
|
return result;
|
|
38367
38419
|
});
|
|
@@ -38581,7 +38633,7 @@ async function runPipelineStages(input) {
|
|
|
38581
38633
|
progressTimer.unref?.();
|
|
38582
38634
|
let result;
|
|
38583
38635
|
try {
|
|
38584
|
-
result = await input.runner.run(request, new AbortController().signal);
|
|
38636
|
+
result = normalizeProcessResult(await input.runner.run(request, new AbortController().signal));
|
|
38585
38637
|
} finally {
|
|
38586
38638
|
clearInterval(progressTimer);
|
|
38587
38639
|
}
|
|
@@ -38682,7 +38734,7 @@ async function runUkrainianTranslation(input) {
|
|
|
38682
38734
|
progressTimer.unref?.();
|
|
38683
38735
|
let result;
|
|
38684
38736
|
try {
|
|
38685
|
-
result = await input.runner.run(request, new AbortController().signal);
|
|
38737
|
+
result = normalizeProcessResult(await input.runner.run(request, new AbortController().signal));
|
|
38686
38738
|
} finally {
|
|
38687
38739
|
clearInterval(progressTimer);
|
|
38688
38740
|
}
|
|
@@ -38902,6 +38954,24 @@ function readStartedAt(path2) {
|
|
|
38902
38954
|
function processOutput(result) {
|
|
38903
38955
|
return result.outputText ?? result.stdout;
|
|
38904
38956
|
}
|
|
38957
|
+
function normalizeProcessResult(result) {
|
|
38958
|
+
if (!hasOpenCodeLengthFinish(result.ndjsonEvents)) return result;
|
|
38959
|
+
return {
|
|
38960
|
+
...result,
|
|
38961
|
+
exitCode: result.exitCode === 0 ? 1 : result.exitCode
|
|
38962
|
+
};
|
|
38963
|
+
}
|
|
38964
|
+
function failureNoteForResult(result) {
|
|
38965
|
+
return hasOpenCodeLengthFinish(result.ndjsonEvents) ? "OpenCode stopped because the model hit the output limit." : void 0;
|
|
38966
|
+
}
|
|
38967
|
+
function hasOpenCodeLengthFinish(events) {
|
|
38968
|
+
return events.some((event) => {
|
|
38969
|
+
if (!isRecord2(event)) return false;
|
|
38970
|
+
const part = event.part;
|
|
38971
|
+
if (!isRecord2(part)) return false;
|
|
38972
|
+
return part.type === "step-finish" && part.reason === "length";
|
|
38973
|
+
});
|
|
38974
|
+
}
|
|
38905
38975
|
function extractUniqueSessionIds(events) {
|
|
38906
38976
|
const ids = /* @__PURE__ */ new Set();
|
|
38907
38977
|
for (const event of events) {
|
|
@@ -38940,6 +39010,14 @@ function buildFailureDiagnostic(result, request) {
|
|
|
38940
39010
|
const stdoutError = extractOpenCodeErrorMessage(result.ndjsonEvents);
|
|
38941
39011
|
const combined = [stderr, stdoutError].filter(Boolean).join("\n");
|
|
38942
39012
|
const model = request?.model ?? "";
|
|
39013
|
+
if (hasOpenCodeLengthFinish(result.ndjsonEvents)) {
|
|
39014
|
+
return {
|
|
39015
|
+
summary: "OpenCode stopped because the model hit the output limit (`step_finish.reason=length`). OCR treats this as failed because the review artifact may be truncated or missing.",
|
|
39016
|
+
hint: "Reduce agent output, keep only structured findings, or use a model/configuration that can complete the saved prompt without truncation.",
|
|
39017
|
+
stderr_excerpt: excerpt(stderr),
|
|
39018
|
+
stdout_excerpt: excerpt(result.stdout)
|
|
39019
|
+
};
|
|
39020
|
+
}
|
|
38943
39021
|
if (/session not found/i.test(combined)) {
|
|
38944
39022
|
return {
|
|
38945
39023
|
summary: 'OpenCode reported "Session not found" while running this process agent. This is an OpenCode subprocess/session error, not an OCR decision to simulate or skip reviewers.',
|
|
@@ -39037,7 +39115,7 @@ function newSessionId() {
|
|
|
39037
39115
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
39038
39116
|
return `${date}-opencode-process-review-${Date.now()}`;
|
|
39039
39117
|
}
|
|
39040
|
-
var runAgentsSubcommand = new Command("run-agents").description("Run OCR review through OpenCode process agents").argument("[target]", "Target path for fresh
|
|
39118
|
+
var runAgentsSubcommand = new Command("run-agents").description("Run OCR review through OpenCode process agents").argument("[target]", "Target path for fresh review mode", ".").option("--session-id <workflow-session-id>", "Prepared workflow session id").option("--round <n>", "Prepared round number", (value) => Number.parseInt(value, 10)).option("--fresh", "Create a fresh workflow session before running process agents").option("--requirements <text-or-path>", "Inline requirements text or path to a requirements file").option("--team <json>", "JSON ReviewerInstance[] override for this run").option("--foreground", "Run in the current process instead of detaching a background worker").option("--background", "Detach and return immediately; not for normal OpenCode UI progress").addOption(new Option("--worker", "Internal detached worker mode").hideHelp()).action(
|
|
39041
39119
|
async (target, options) => {
|
|
39042
39120
|
const targetDir = process.cwd();
|
|
39043
39121
|
requireOcrSetup(targetDir);
|
|
@@ -39433,7 +39511,7 @@ var reviewCommand = new Command("review").description("Run or resume an OCR revi
|
|
|
39433
39511
|
if (!options.resume) {
|
|
39434
39512
|
console.error(
|
|
39435
39513
|
source_default.yellow(
|
|
39436
|
-
"Running a fresh review from
|
|
39514
|
+
"Running a fresh review from this wrapper is not yet supported \u2014 use your AI CLI's `/ocr-review` slash command or run `ocr review run-agents --fresh`."
|
|
39437
39515
|
)
|
|
39438
39516
|
);
|
|
39439
39517
|
console.error(
|
|
@@ -39710,76 +39788,9 @@ var updateCommand = new Command("update").description("Update OCR assets after p
|
|
|
39710
39788
|
console.log();
|
|
39711
39789
|
});
|
|
39712
39790
|
|
|
39713
|
-
// src/commands/dashboard.ts
|
|
39714
|
-
import { existsSync as existsSync25 } from "node:fs";
|
|
39715
|
-
import { join as join30, dirname as dirname12 } from "node:path";
|
|
39716
|
-
import { fileURLToPath } from "node:url";
|
|
39717
|
-
init_src();
|
|
39718
|
-
init_db();
|
|
39719
|
-
var __filename = fileURLToPath(import.meta.url);
|
|
39720
|
-
var __dirname = dirname12(__filename);
|
|
39721
|
-
function resolveServerPath() {
|
|
39722
|
-
return join30(__dirname, "dashboard", "server.js");
|
|
39723
|
-
}
|
|
39724
|
-
var dashboardCommand = new Command("dashboard").description("Start the OCR dashboard web interface").option("-p, --port <port>", "Port to run the server on", "4173").option("--no-open", "Don't open the browser automatically").action(
|
|
39725
|
-
async (options) => {
|
|
39726
|
-
const targetDir = process.cwd();
|
|
39727
|
-
requireOcrSetup(targetDir);
|
|
39728
|
-
const port = parseInt(options.port, 10);
|
|
39729
|
-
if (isNaN(port) || port < 1 || port > 65535) {
|
|
39730
|
-
console.error(source_default.red(`Error: Invalid port "${options.port}". Must be 1-65535.`));
|
|
39731
|
-
process.exit(1);
|
|
39732
|
-
}
|
|
39733
|
-
const ocrDir = join30(targetDir, ".ocr");
|
|
39734
|
-
try {
|
|
39735
|
-
await ensureDatabase(ocrDir);
|
|
39736
|
-
closeAllDatabases();
|
|
39737
|
-
} catch (err) {
|
|
39738
|
-
console.error(source_default.red("Error: Failed to initialize database."));
|
|
39739
|
-
console.error(
|
|
39740
|
-
source_default.dim(
|
|
39741
|
-
` ${err instanceof Error ? err.message : String(err)}`
|
|
39742
|
-
)
|
|
39743
|
-
);
|
|
39744
|
-
process.exit(1);
|
|
39745
|
-
}
|
|
39746
|
-
const serverPath = resolveServerPath();
|
|
39747
|
-
if (!existsSync25(serverPath)) {
|
|
39748
|
-
console.error(source_default.red("Error: Dashboard server bundle not found."));
|
|
39749
|
-
console.error(
|
|
39750
|
-
source_default.dim(` Expected at: ${serverPath}`)
|
|
39751
|
-
);
|
|
39752
|
-
console.error(
|
|
39753
|
-
source_default.dim(" This may indicate a broken installation. Try reinstalling:")
|
|
39754
|
-
);
|
|
39755
|
-
console.error(source_default.white(" npm install -g @open-code-review/cli"));
|
|
39756
|
-
process.exit(1);
|
|
39757
|
-
}
|
|
39758
|
-
process.env.NODE_ENV = "production";
|
|
39759
|
-
console.log();
|
|
39760
|
-
console.log(source_default.bold(" OCR Dashboard"));
|
|
39761
|
-
console.log();
|
|
39762
|
-
try {
|
|
39763
|
-
const { startServer } = await importModule(serverPath);
|
|
39764
|
-
await startServer({ port, open: options.open });
|
|
39765
|
-
} catch (err) {
|
|
39766
|
-
console.error(source_default.red("Error: Failed to start dashboard server."));
|
|
39767
|
-
console.error(
|
|
39768
|
-
source_default.dim(
|
|
39769
|
-
` ${err instanceof Error ? err.message : String(err)}`
|
|
39770
|
-
)
|
|
39771
|
-
);
|
|
39772
|
-
process.exit(1);
|
|
39773
|
-
}
|
|
39774
|
-
console.log();
|
|
39775
|
-
console.log(source_default.dim(" Press Ctrl+C to stop"));
|
|
39776
|
-
console.log();
|
|
39777
|
-
}
|
|
39778
|
-
);
|
|
39779
|
-
|
|
39780
39791
|
// src/commands/doctor.ts
|
|
39781
|
-
import { existsSync as
|
|
39782
|
-
import { join as
|
|
39792
|
+
import { existsSync as existsSync25 } from "node:fs";
|
|
39793
|
+
import { join as join30 } from "node:path";
|
|
39783
39794
|
init_db();
|
|
39784
39795
|
function printStorageEngine(probeWriteEnabled) {
|
|
39785
39796
|
console.log();
|
|
@@ -39836,10 +39847,10 @@ var doctorCommand = new Command("doctor").description("Check OCR installation an
|
|
|
39836
39847
|
console.log(source_default.bold(" OCR Installation"));
|
|
39837
39848
|
console.log();
|
|
39838
39849
|
const ocrStatus = checkOcrSetup(targetDir);
|
|
39839
|
-
const configPath =
|
|
39840
|
-
const dbPath =
|
|
39841
|
-
const hasConfig =
|
|
39842
|
-
const hasDb =
|
|
39850
|
+
const configPath = join30(targetDir, ".ocr", "config.yaml");
|
|
39851
|
+
const dbPath = join30(targetDir, ".ocr", "data", "ocr.db");
|
|
39852
|
+
const hasConfig = existsSync25(configPath);
|
|
39853
|
+
const hasDb = existsSync25(dbPath);
|
|
39843
39854
|
const ocrChecks = [
|
|
39844
39855
|
{ label: ".ocr/skills/", ok: ocrStatus.hasSkills },
|
|
39845
39856
|
{ label: ".ocr/sessions/", ok: ocrStatus.hasSessions },
|
|
@@ -39908,7 +39919,7 @@ var doctorCommand = new Command("doctor").description("Check OCR installation an
|
|
|
39908
39919
|
console.log(source_default.green(" \u2713 Ready for code review"));
|
|
39909
39920
|
console.log(
|
|
39910
39921
|
source_default.dim(
|
|
39911
|
-
" Install Claude Code or OpenCode for
|
|
39922
|
+
" Install Claude Code or OpenCode for AI review commands"
|
|
39912
39923
|
)
|
|
39913
39924
|
);
|
|
39914
39925
|
}
|
|
@@ -39916,8 +39927,8 @@ var doctorCommand = new Command("doctor").description("Check OCR installation an
|
|
|
39916
39927
|
});
|
|
39917
39928
|
|
|
39918
39929
|
// src/commands/db.ts
|
|
39919
|
-
import { existsSync as
|
|
39920
|
-
import { join as
|
|
39930
|
+
import { existsSync as existsSync26, readFileSync as readFileSync18 } from "node:fs";
|
|
39931
|
+
import { join as join31 } from "node:path";
|
|
39921
39932
|
init_src();
|
|
39922
39933
|
init_db();
|
|
39923
39934
|
function fail4(message) {
|
|
@@ -39927,10 +39938,10 @@ function fail4(message) {
|
|
|
39927
39938
|
function resolveOcrDir() {
|
|
39928
39939
|
const targetDir = process.cwd();
|
|
39929
39940
|
requireOcrSetup(targetDir);
|
|
39930
|
-
return
|
|
39941
|
+
return join31(targetDir, ".ocr");
|
|
39931
39942
|
}
|
|
39932
39943
|
function dbPathFor(ocrDir) {
|
|
39933
|
-
return
|
|
39944
|
+
return join31(ocrDir, "data", "ocr.db");
|
|
39934
39945
|
}
|
|
39935
39946
|
function formatBytes(n) {
|
|
39936
39947
|
if (n < 1024) return `${n} B`;
|
|
@@ -39943,9 +39954,9 @@ function formatBytes(n) {
|
|
|
39943
39954
|
}
|
|
39944
39955
|
return `${v.toFixed(v >= 100 ? 0 : 1)} ${units[i]}`;
|
|
39945
39956
|
}
|
|
39946
|
-
function
|
|
39947
|
-
const pidFile =
|
|
39948
|
-
if (!
|
|
39957
|
+
function liveOcrOwnerPid(ocrDir) {
|
|
39958
|
+
const pidFile = join31(ocrDir, "data", "dashboard.pid");
|
|
39959
|
+
if (!existsSync26(pidFile)) return null;
|
|
39949
39960
|
try {
|
|
39950
39961
|
const pid = parseInt(readFileSync18(pidFile, "utf-8").trim(), 10);
|
|
39951
39962
|
if (!Number.isNaN(pid) && isProcessAlive(pid)) return pid;
|
|
@@ -39954,10 +39965,10 @@ function liveDashboardPid(ocrDir) {
|
|
|
39954
39965
|
return null;
|
|
39955
39966
|
}
|
|
39956
39967
|
function guardExclusive(ocrDir, force, op) {
|
|
39957
|
-
const pid =
|
|
39968
|
+
const pid = liveOcrOwnerPid(ocrDir);
|
|
39958
39969
|
if (pid !== null && !force) {
|
|
39959
39970
|
fail4(
|
|
39960
|
-
`
|
|
39971
|
+
`another OCR process appears to be running (PID ${pid}); ${op} needs exclusive access to the database.
|
|
39961
39972
|
Stop it first, or pass --force to proceed anyway.`
|
|
39962
39973
|
);
|
|
39963
39974
|
}
|
|
@@ -40025,7 +40036,7 @@ function printHealth(report) {
|
|
|
40025
40036
|
function needsFix(report) {
|
|
40026
40037
|
return !report.integrityOk || report.fkViolations.length > 0 || report.markdownDuplicateRows > 0 || report.orphanTempFiles.some((f) => f.reapable) || report.reclaimableBytes > 0;
|
|
40027
40038
|
}
|
|
40028
|
-
var doctorSubcommand = new Command("doctor").description("Report database health; --fix repairs orphans/dupes and VACUUMs").option("--fix", "apply repairs: FK-orphan sweep, dedup, temp reap, VACUUM").option("--no-snapshot", "skip the pre-fix snapshot (with --fix)").option("--force", "proceed even if
|
|
40039
|
+
var doctorSubcommand = new Command("doctor").description("Report database health; --fix repairs orphans/dupes and VACUUMs").option("--fix", "apply repairs: FK-orphan sweep, dedup, temp reap, VACUUM").option("--no-snapshot", "skip the pre-fix snapshot (with --fix)").option("--force", "proceed even if another live OCR process owns the database").option("--json", "emit the health report as JSON (implies no --fix)").action(
|
|
40029
40040
|
async (options) => {
|
|
40030
40041
|
const ocrDir = resolveOcrDir();
|
|
40031
40042
|
const dbPath = dbPathFor(ocrDir);
|
|
@@ -40104,7 +40115,7 @@ var doctorSubcommand = new Command("doctor").description("Report database health
|
|
|
40104
40115
|
console.log();
|
|
40105
40116
|
}
|
|
40106
40117
|
);
|
|
40107
|
-
var vacuumSubcommand = new Command("vacuum").description("Checkpoint the WAL and VACUUM the database (snapshot-first)").option("--no-snapshot", "skip the pre-vacuum snapshot").option("--force", "proceed even if
|
|
40118
|
+
var vacuumSubcommand = new Command("vacuum").description("Checkpoint the WAL and VACUUM the database (snapshot-first)").option("--no-snapshot", "skip the pre-vacuum snapshot").option("--force", "proceed even if another live OCR process owns the database").action(async (options) => {
|
|
40108
40119
|
const ocrDir = resolveOcrDir();
|
|
40109
40120
|
const dbPath = dbPathFor(ocrDir);
|
|
40110
40121
|
guardExclusive(ocrDir, options.force ?? false, "vacuum");
|
|
@@ -40129,7 +40140,7 @@ var pruneSubcommand = new Command("prune").description(
|
|
|
40129
40140
|
"--older-than <days>",
|
|
40130
40141
|
"only prune closed sessions quiet for more than D days",
|
|
40131
40142
|
(v) => parseInt(v, 10)
|
|
40132
|
-
).option("--dry-run", "show what would be pruned without deleting").option("--force", "proceed even if
|
|
40143
|
+
).option("--dry-run", "show what would be pruned without deleting").option("--force", "proceed even if another live OCR process owns the database").action(
|
|
40133
40144
|
async (options) => {
|
|
40134
40145
|
const ocrDir = resolveOcrDir();
|
|
40135
40146
|
const dbPath = dbPathFor(ocrDir);
|
|
@@ -40201,7 +40212,7 @@ var pruneBackupsSubcommand = new Command("prune-backups").description("Delete ol
|
|
|
40201
40212
|
1
|
|
40202
40213
|
).option("--force", "permit --keep 0 (removing the last backup / safety net)").option("--dry-run", "show what would be deleted without deleting").action(async (options) => {
|
|
40203
40214
|
const ocrDir = resolveOcrDir();
|
|
40204
|
-
const dataDir =
|
|
40215
|
+
const dataDir = join31(ocrDir, "data");
|
|
40205
40216
|
const invalid = validatePruneBackupsOptions(options);
|
|
40206
40217
|
if (invalid !== null) {
|
|
40207
40218
|
fail4(invalid);
|
|
@@ -40238,7 +40249,7 @@ var dbCommand = new Command("db").description("Inspect and maintain the OCR SQLi
|
|
|
40238
40249
|
|
|
40239
40250
|
// src/commands/reviewers.ts
|
|
40240
40251
|
import { writeFileSync as writeFileSync10, renameSync as renameSync2 } from "node:fs";
|
|
40241
|
-
import { join as
|
|
40252
|
+
import { join as join32 } from "node:path";
|
|
40242
40253
|
init_src();
|
|
40243
40254
|
async function readStdin3() {
|
|
40244
40255
|
const chunks = [];
|
|
@@ -40334,17 +40345,17 @@ function validateReviewersMeta(data) {
|
|
|
40334
40345
|
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) => {
|
|
40335
40346
|
const targetDir = process.cwd();
|
|
40336
40347
|
requireOcrSetup(targetDir);
|
|
40337
|
-
const ocrDir =
|
|
40348
|
+
const ocrDir = join32(targetDir, ".ocr");
|
|
40338
40349
|
if (!options.stdin) {
|
|
40339
40350
|
try {
|
|
40340
|
-
const reviewersDir =
|
|
40341
|
-
const configPath =
|
|
40351
|
+
const reviewersDir = join32(ocrDir, "skills", "references", "reviewers");
|
|
40352
|
+
const configPath = join32(ocrDir, "config.yaml");
|
|
40342
40353
|
const meta = generateReviewersMeta(reviewersDir, configPath);
|
|
40343
40354
|
if (!meta || meta.reviewers.length === 0) {
|
|
40344
40355
|
console.error(source_default.yellow("No reviewer files found in .ocr/skills/references/reviewers/"));
|
|
40345
40356
|
process.exit(1);
|
|
40346
40357
|
}
|
|
40347
|
-
const metaPath =
|
|
40358
|
+
const metaPath = join32(ocrDir, "reviewers-meta.json");
|
|
40348
40359
|
const tmpPath = metaPath + ".tmp";
|
|
40349
40360
|
writeFileSync10(tmpPath, JSON.stringify(meta, null, 2) + "\n");
|
|
40350
40361
|
renameSync2(tmpPath, metaPath);
|
|
@@ -40374,7 +40385,7 @@ var syncSubcommand2 = new Command("sync").description("Sync reviewers-meta.json
|
|
|
40374
40385
|
throw new Error("Invalid JSON on stdin");
|
|
40375
40386
|
}
|
|
40376
40387
|
const meta = validateReviewersMeta(parsed);
|
|
40377
|
-
const metaPath =
|
|
40388
|
+
const metaPath = join32(ocrDir, "reviewers-meta.json");
|
|
40378
40389
|
const tmpPath = metaPath + ".tmp";
|
|
40379
40390
|
writeFileSync10(tmpPath, JSON.stringify(meta, null, 2) + "\n");
|
|
40380
40391
|
renameSync2(tmpPath, metaPath);
|
|
@@ -40450,12 +40461,12 @@ var hostCommand = new Command("host").description("Inspect host (AI CLI) capabil
|
|
|
40450
40461
|
|
|
40451
40462
|
// src/lib/update-check.ts
|
|
40452
40463
|
import { homedir } from "node:os";
|
|
40453
|
-
import { join as
|
|
40464
|
+
import { join as join33 } from "node:path";
|
|
40454
40465
|
import { readFileSync as readFileSync19, writeFileSync as writeFileSync11, mkdirSync as mkdirSync9 } from "node:fs";
|
|
40455
40466
|
var PACKAGE_NAME = "@open-code-review/cli";
|
|
40456
40467
|
var REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
|
|
40457
|
-
var CACHE_DIR2 =
|
|
40458
|
-
var CACHE_FILE =
|
|
40468
|
+
var CACHE_DIR2 = join33(homedir(), ".ocr");
|
|
40469
|
+
var CACHE_FILE = join33(CACHE_DIR2, "update-check.json");
|
|
40459
40470
|
var CHECK_INTERVAL_MS = 4 * 60 * 60 * 1e3;
|
|
40460
40471
|
var FETCH_TIMEOUT_MS = 3e3;
|
|
40461
40472
|
function readCache(cacheFile) {
|
|
@@ -40467,7 +40478,7 @@ function readCache(cacheFile) {
|
|
|
40467
40478
|
}
|
|
40468
40479
|
function writeCache(cacheFile, cache2) {
|
|
40469
40480
|
try {
|
|
40470
|
-
mkdirSync9(
|
|
40481
|
+
mkdirSync9(join33(cacheFile, ".."), { recursive: true });
|
|
40471
40482
|
writeFileSync11(cacheFile, JSON.stringify(cache2));
|
|
40472
40483
|
} catch {
|
|
40473
40484
|
}
|
|
@@ -40488,7 +40499,7 @@ async function checkForUpdate(currentVersion, options) {
|
|
|
40488
40499
|
if (process.env.CI || process.env.OCR_NO_UPDATE_CHECK) {
|
|
40489
40500
|
return null;
|
|
40490
40501
|
}
|
|
40491
|
-
const cacheFile =
|
|
40502
|
+
const cacheFile = join33(options?.cacheDir ?? CACHE_DIR2, "update-check.json");
|
|
40492
40503
|
try {
|
|
40493
40504
|
const cache2 = readCache(cacheFile);
|
|
40494
40505
|
if (cache2 && Date.now() - cache2.lastCheck < CHECK_INTERVAL_MS) {
|
|
@@ -40532,7 +40543,7 @@ ${line2}
|
|
|
40532
40543
|
}
|
|
40533
40544
|
|
|
40534
40545
|
// src/index.ts
|
|
40535
|
-
var HUMAN_COMMANDS = /* @__PURE__ */ new Set(["init", "update", "doctor", "
|
|
40546
|
+
var HUMAN_COMMANDS = /* @__PURE__ */ new Set(["init", "update", "doctor", "progress"]);
|
|
40536
40547
|
var subcommand = process.argv[2];
|
|
40537
40548
|
var updateCheck = subcommand && HUMAN_COMMANDS.has(subcommand) ? checkForUpdate(CLI_VERSION) : null;
|
|
40538
40549
|
var program2 = new Command();
|
|
@@ -40545,7 +40556,6 @@ program2.addCommand(modelsCommand);
|
|
|
40545
40556
|
program2.addCommand(teamCommand);
|
|
40546
40557
|
program2.addCommand(reviewCommand);
|
|
40547
40558
|
program2.addCommand(updateCommand);
|
|
40548
|
-
program2.addCommand(dashboardCommand);
|
|
40549
40559
|
program2.addCommand(doctorCommand);
|
|
40550
40560
|
program2.addCommand(dbCommand);
|
|
40551
40561
|
program2.addCommand(reviewersCommand);
|