@nk070281sjv/cli 2.3.22 → 2.3.24
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 +144 -151
- 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.24" : 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,15 +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
|
-
expectStringArray(f.
|
|
35032
|
+
expectEnum(f.severity, VALID_AGGREGATION_SEVERITIES, `findings[${index}].severity`, errors);
|
|
35033
|
+
expectStringArray(f.files, `findings[${index}].files`, errors);
|
|
35032
35034
|
expectString(f.claim, `findings[${index}].claim`, errors);
|
|
35033
35035
|
expectString(f.evidence, `findings[${index}].evidence`, errors);
|
|
35034
|
-
expectString(f.
|
|
35035
|
-
expectStringArray(f.
|
|
35036
|
-
expectString(f.
|
|
35036
|
+
expectString(f.impact, `findings[${index}].impact`, errors);
|
|
35037
|
+
expectStringArray(f.validate, `findings[${index}].validate`, errors);
|
|
35038
|
+
expectString(f.fix, `findings[${index}].fix`, errors);
|
|
35037
35039
|
});
|
|
35038
35040
|
}
|
|
35039
35041
|
const dropped = expectArray(obj.dropped, "dropped", errors);
|
|
@@ -35041,7 +35043,7 @@ function validateAggregationJson(value) {
|
|
|
35041
35043
|
dropped.forEach((drop, index) => {
|
|
35042
35044
|
const d = expectObject(drop, `dropped[${index}]`, errors);
|
|
35043
35045
|
if (!d) return;
|
|
35044
|
-
expectStringArray(d.
|
|
35046
|
+
expectStringArray(d.src, `dropped[${index}].src`, errors);
|
|
35045
35047
|
expectString(d.reason, `dropped[${index}].reason`, errors);
|
|
35046
35048
|
});
|
|
35047
35049
|
}
|
|
@@ -36322,7 +36324,7 @@ function readDashboardSpawnMarker(ocrDir) {
|
|
|
36322
36324
|
if (live.length > 1) {
|
|
36323
36325
|
console.error(
|
|
36324
36326
|
source_default.gray(
|
|
36325
|
-
`[state] ${live.length} concurrent
|
|
36327
|
+
`[state] ${live.length} concurrent external launches live; marker fallback is ambiguous \u2014 pass --dashboard-uid for linkage`
|
|
36326
36328
|
)
|
|
36327
36329
|
);
|
|
36328
36330
|
return null;
|
|
@@ -36346,7 +36348,7 @@ async function linkDashboardInvocation(ocrDir, sessionId, explicitUid, label) {
|
|
|
36346
36348
|
if (!dashboardUid) {
|
|
36347
36349
|
console.error(
|
|
36348
36350
|
source_default.gray(
|
|
36349
|
-
`[state ${label}] no
|
|
36351
|
+
`[state ${label}] no external-launch linkage available (flag, env var, and marker file all absent \u2014 CLI-only invocation)`
|
|
36350
36352
|
)
|
|
36351
36353
|
);
|
|
36352
36354
|
return;
|
|
@@ -36356,13 +36358,13 @@ async function linkDashboardInvocation(ocrDir, sessionId, explicitUid, label) {
|
|
|
36356
36358
|
linkDashboardInvocationToWorkflow(db, dashboardUid, sessionId);
|
|
36357
36359
|
console.error(
|
|
36358
36360
|
source_default.gray(
|
|
36359
|
-
`[state ${label}] linked workflow_id=${sessionId} \u2192
|
|
36361
|
+
`[state ${label}] linked workflow_id=${sessionId} \u2192 launcher uid=${dashboardUid}`
|
|
36360
36362
|
)
|
|
36361
36363
|
);
|
|
36362
36364
|
} catch (linkErr) {
|
|
36363
36365
|
console.error(
|
|
36364
36366
|
source_default.yellow(
|
|
36365
|
-
`Warning: failed to link
|
|
36367
|
+
`Warning: failed to link launcher command_execution to session: ${linkErr instanceof Error ? linkErr.message : String(linkErr)}`
|
|
36366
36368
|
)
|
|
36367
36369
|
);
|
|
36368
36370
|
}
|
|
@@ -36520,7 +36522,7 @@ var beginSubcommand = new Command("begin").description("Start or resume a workfl
|
|
|
36520
36522
|
return v;
|
|
36521
36523
|
}).option("--session-dir <dir>", "Session directory path (auto-resolved if omitted)").option(
|
|
36522
36524
|
"--dashboard-uid <uid>",
|
|
36523
|
-
"
|
|
36525
|
+
"External launcher command_executions uid to link this workflow to (takes precedence over OCR_DASHBOARD_EXECUTION_UID)"
|
|
36524
36526
|
).option("--json", "Output the result as JSON").action(
|
|
36525
36527
|
async (options) => {
|
|
36526
36528
|
const targetDir = process.cwd();
|
|
@@ -37428,12 +37430,10 @@ async function writeRoundArtifact(roundDir, relativePath, content) {
|
|
|
37428
37430
|
}
|
|
37429
37431
|
|
|
37430
37432
|
// src/lib/agent-orchestrator/context-prep.ts
|
|
37433
|
+
init_src();
|
|
37431
37434
|
import { mkdir as mkdir2, readFile, writeFile as writeFile2 } from "node:fs/promises";
|
|
37432
37435
|
import { existsSync as existsSync21 } from "node:fs";
|
|
37433
37436
|
import { dirname as dirname10, join as join25 } from "node:path";
|
|
37434
|
-
import { execFile } from "node:child_process";
|
|
37435
|
-
import { promisify } from "node:util";
|
|
37436
|
-
var execFileAsync = promisify(execFile);
|
|
37437
37437
|
var GIT_SUMMARY_LIMIT = 2e4;
|
|
37438
37438
|
var REVIEW_SNAPSHOT_EXCLUDES = [".ocr", ".opencode"];
|
|
37439
37439
|
async function prepareReviewContext(input) {
|
|
@@ -37625,9 +37625,10 @@ async function resolveDefaultRemoteBase(cwd) {
|
|
|
37625
37625
|
}
|
|
37626
37626
|
async function runGit(cwd, args, limit = GIT_SUMMARY_LIMIT) {
|
|
37627
37627
|
try {
|
|
37628
|
-
const { stdout, stderr } = await
|
|
37628
|
+
const { stdout, stderr } = await execBinaryAsync("git", args, {
|
|
37629
37629
|
cwd,
|
|
37630
|
-
maxBuffer: limit * 2
|
|
37630
|
+
maxBuffer: limit * 2,
|
|
37631
|
+
encoding: "utf8"
|
|
37631
37632
|
});
|
|
37632
37633
|
return truncate(`${stdout}${stderr ? `
|
|
37633
37634
|
${stderr}` : ""}`.trim(), limit);
|
|
@@ -38037,14 +38038,43 @@ async function reviewerPrompt(context, reviewer, promptPath, reviewPath, sharedP
|
|
|
38037
38038
|
"- Apply the reviewer persona file as your primary review lens.",
|
|
38038
38039
|
"- Use the review brief as the source of truth for changed files and scope.",
|
|
38039
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.",
|
|
38042
|
+
"- Persona focus areas are for detecting issues only; this output contract overrides any persona request to propose fixes or broad guidance.",
|
|
38040
38043
|
"",
|
|
38041
38044
|
"Output contract:",
|
|
38042
38045
|
`- Return review markdown through stdout for ${reviewPath}.`,
|
|
38046
|
+
"- Return only one fenced ```ocr-json block and no prose outside it.",
|
|
38047
|
+
"- Include maximum 5 findings, sorted by severity and production impact.",
|
|
38048
|
+
"- No introductions, no progress narration, no endpoint tables, no code snippets, no broad summaries.",
|
|
38049
|
+
"- Include critical, high, and medium findings. Include low only when it has concrete runtime/user impact. Exclude info/style/theoretical-only items.",
|
|
38050
|
+
"- Do not write fix instructions, suggested patches, implementation recipes, or remediation plans.",
|
|
38051
|
+
"- Exclude any item that does not have concrete `files` and `evidence`.",
|
|
38043
38052
|
"- Do not write files directly.",
|
|
38044
38053
|
"- Do not claim skipped agents ran.",
|
|
38045
38054
|
"",
|
|
38046
38055
|
"Required ocr-json schema:",
|
|
38047
|
-
"-
|
|
38056
|
+
"- Output exactly this compact JSON shape inside the fenced block:",
|
|
38057
|
+
"",
|
|
38058
|
+
"```json",
|
|
38059
|
+
"{",
|
|
38060
|
+
' "findings": [',
|
|
38061
|
+
" {",
|
|
38062
|
+
' "sev": "high",',
|
|
38063
|
+
' "title": "Short finding title",',
|
|
38064
|
+
' "files": ["src/main/java/example/File.java:42"],',
|
|
38065
|
+
' "claim": "What may be wrong.",',
|
|
38066
|
+
' "evidence": "Concrete code evidence.",',
|
|
38067
|
+
' "impact": "Runtime/user/system impact if confirmed.",',
|
|
38068
|
+
' "confidence": "high"',
|
|
38069
|
+
" }",
|
|
38070
|
+
" ]",
|
|
38071
|
+
"}",
|
|
38072
|
+
"```",
|
|
38073
|
+
"",
|
|
38074
|
+
'- `sev` must be one of: "critical", "high", "medium", "low".',
|
|
38075
|
+
'- `confidence` must be one of: "high", "medium", "low".',
|
|
38076
|
+
"- Keep title/claim/impact under roughly 180 characters each.",
|
|
38077
|
+
"- Keep evidence under roughly 260 characters and cite only the strongest code signal.",
|
|
38048
38078
|
"",
|
|
38049
38079
|
"Forbidden behavior:",
|
|
38050
38080
|
`- Do not modify ${promptPath} or ${reviewPath}.`,
|
|
@@ -38157,7 +38187,8 @@ function pipelinePrompt(context, stage, agent, promptPath, artifactPath) {
|
|
|
38157
38187
|
] : stage === "aggregation" ? [
|
|
38158
38188
|
"- Return only one fenced ```ocr-json block and no prose outside it.",
|
|
38159
38189
|
"- Keep the output compact: at most 8 findings and at most 12 dropped entries.",
|
|
38160
|
-
"- Do not include code snippets, long quotes, markdown tables, or reviewer narrative."
|
|
38190
|
+
"- Do not include code snippets, long quotes, markdown tables, or reviewer narrative.",
|
|
38191
|
+
"- Read the original reviewer files, but aggregate only their structured findings and concrete evidence."
|
|
38161
38192
|
] : ["- Include exactly one fenced ```ocr-json block."],
|
|
38162
38193
|
"- Do not write files directly.",
|
|
38163
38194
|
"",
|
|
@@ -38183,7 +38214,11 @@ function schemaHint(stage) {
|
|
|
38183
38214
|
"- Output exactly this compact JSON shape inside one fenced ```ocr-json block.",
|
|
38184
38215
|
"- Do not rename fields. Do not use markdown tables inside the JSON block.",
|
|
38185
38216
|
"- Keep only high-signal findings that a developer or validation agent can act on.",
|
|
38186
|
-
"- Merge duplicates across reviewers into one finding with multiple `
|
|
38217
|
+
"- Merge duplicates across reviewers into one finding with multiple `src` references.",
|
|
38218
|
+
"- Severity gate:",
|
|
38219
|
+
" - Keep critical, high, and medium findings.",
|
|
38220
|
+
" - Keep low only when duplicated by 2+ reviewers or when it has concrete production/runtime impact.",
|
|
38221
|
+
" - Drop info, style, theoretical-only, and future-extensibility-only items.",
|
|
38187
38222
|
"",
|
|
38188
38223
|
"```json",
|
|
38189
38224
|
"{",
|
|
@@ -38191,20 +38226,20 @@ function schemaHint(stage) {
|
|
|
38191
38226
|
" {",
|
|
38192
38227
|
' "id": "agg-1",',
|
|
38193
38228
|
' "title": "Short finding title",',
|
|
38194
|
-
' "
|
|
38229
|
+
' "src": ["architect-1:finding-or-heading"],',
|
|
38195
38230
|
' "signal": "keep",',
|
|
38196
38231
|
' "severity": "high",',
|
|
38197
|
-
' "
|
|
38232
|
+
' "files": ["src/main/java/example/File.java:42"],',
|
|
38198
38233
|
' "claim": "What may be wrong, stated as a verifiable hypothesis.",',
|
|
38199
38234
|
' "evidence": "Why reviewers believe this may be wrong.",',
|
|
38200
|
-
' "
|
|
38201
|
-
' "
|
|
38202
|
-
' "
|
|
38235
|
+
' "impact": "What user/system behavior would be affected if confirmed.",',
|
|
38236
|
+
' "validate": ["Check the write path for a uniqueness boundary."],',
|
|
38237
|
+
' "fix": "Concrete direction for the fix."',
|
|
38203
38238
|
" }",
|
|
38204
38239
|
" ],",
|
|
38205
38240
|
' "dropped": [',
|
|
38206
38241
|
" {",
|
|
38207
|
-
' "
|
|
38242
|
+
' "src": ["performance-1:finding-or-heading"],',
|
|
38208
38243
|
' "reason": "Why this reviewer finding is noise or duplicate."',
|
|
38209
38244
|
" }",
|
|
38210
38245
|
" ]",
|
|
@@ -38212,8 +38247,8 @@ function schemaHint(stage) {
|
|
|
38212
38247
|
"```",
|
|
38213
38248
|
"",
|
|
38214
38249
|
'- `signal` must be one of: "keep", "merge", "needs_validation", "likely_noise", "false_positive_candidate".',
|
|
38215
|
-
'- `severity` must be one of: "critical", "high", "medium", "low"
|
|
38216
|
-
"- `
|
|
38250
|
+
'- `severity` must be one of: "critical", "high", "medium", "low".',
|
|
38251
|
+
"- `src`, `files`, and `validate` must always be arrays of non-empty strings.",
|
|
38217
38252
|
"- Limit each string field to roughly 320 characters. Limit arrays to the most relevant entries.",
|
|
38218
38253
|
"- Prefer dropping low/info/style-only noise over producing an overlong aggregation."
|
|
38219
38254
|
].join("\n");
|
|
@@ -38223,7 +38258,7 @@ function schemaHint(stage) {
|
|
|
38223
38258
|
"ValidationJson:",
|
|
38224
38259
|
"- Output exactly this JSON shape inside one fenced ```ocr-json block.",
|
|
38225
38260
|
"- Do not rename fields. Do not use markdown tables inside the JSON block.",
|
|
38226
|
-
"- Use aggregation `claim`, `evidence`, `
|
|
38261
|
+
"- Use aggregation `claim`, `evidence`, `files`, and `validate` as the checklist for each finding.",
|
|
38227
38262
|
"- Verify claims against the actual code before confirming. Do not trust reviewer text without code evidence.",
|
|
38228
38263
|
"- Put every aggregation finding into exactly one of `confirmed`, `downgraded`, or `rejected`.",
|
|
38229
38264
|
"",
|
|
@@ -38363,7 +38398,7 @@ async function runReviewerPhase(input) {
|
|
|
38363
38398
|
prompt_path: request.promptPath,
|
|
38364
38399
|
meta_log: startLogPaths.meta
|
|
38365
38400
|
});
|
|
38366
|
-
const result = await input.runner.run(request, controller.signal);
|
|
38401
|
+
const result = normalizeProcessResult(await input.runner.run(request, controller.signal));
|
|
38367
38402
|
const logPaths = await writeProcessLogs(input.context.roundDir, request, result);
|
|
38368
38403
|
running.delete(request.id);
|
|
38369
38404
|
completed.add(request.id);
|
|
@@ -38380,7 +38415,7 @@ async function runReviewerPhase(input) {
|
|
|
38380
38415
|
if (vendorId) await journal.bindVendorId(agentSessionId, vendorId);
|
|
38381
38416
|
await journal.endInstance(agentSessionId, {
|
|
38382
38417
|
exitCode: result.exitCode,
|
|
38383
|
-
note: result.stderr.trim() ||
|
|
38418
|
+
note: result.stderr.trim() || failureNoteForResult(result)
|
|
38384
38419
|
});
|
|
38385
38420
|
return result;
|
|
38386
38421
|
});
|
|
@@ -38600,7 +38635,7 @@ async function runPipelineStages(input) {
|
|
|
38600
38635
|
progressTimer.unref?.();
|
|
38601
38636
|
let result;
|
|
38602
38637
|
try {
|
|
38603
|
-
result = await input.runner.run(request, new AbortController().signal);
|
|
38638
|
+
result = normalizeProcessResult(await input.runner.run(request, new AbortController().signal));
|
|
38604
38639
|
} finally {
|
|
38605
38640
|
clearInterval(progressTimer);
|
|
38606
38641
|
}
|
|
@@ -38701,7 +38736,7 @@ async function runUkrainianTranslation(input) {
|
|
|
38701
38736
|
progressTimer.unref?.();
|
|
38702
38737
|
let result;
|
|
38703
38738
|
try {
|
|
38704
|
-
result = await input.runner.run(request, new AbortController().signal);
|
|
38739
|
+
result = normalizeProcessResult(await input.runner.run(request, new AbortController().signal));
|
|
38705
38740
|
} finally {
|
|
38706
38741
|
clearInterval(progressTimer);
|
|
38707
38742
|
}
|
|
@@ -38921,6 +38956,24 @@ function readStartedAt(path2) {
|
|
|
38921
38956
|
function processOutput(result) {
|
|
38922
38957
|
return result.outputText ?? result.stdout;
|
|
38923
38958
|
}
|
|
38959
|
+
function normalizeProcessResult(result) {
|
|
38960
|
+
if (!hasOpenCodeLengthFinish(result.ndjsonEvents)) return result;
|
|
38961
|
+
return {
|
|
38962
|
+
...result,
|
|
38963
|
+
exitCode: result.exitCode === 0 ? 1 : result.exitCode
|
|
38964
|
+
};
|
|
38965
|
+
}
|
|
38966
|
+
function failureNoteForResult(result) {
|
|
38967
|
+
return hasOpenCodeLengthFinish(result.ndjsonEvents) ? "OpenCode stopped because the model hit the output limit." : void 0;
|
|
38968
|
+
}
|
|
38969
|
+
function hasOpenCodeLengthFinish(events) {
|
|
38970
|
+
return events.some((event) => {
|
|
38971
|
+
if (!isRecord2(event)) return false;
|
|
38972
|
+
const part = event.part;
|
|
38973
|
+
if (!isRecord2(part)) return false;
|
|
38974
|
+
return part.type === "step-finish" && part.reason === "length";
|
|
38975
|
+
});
|
|
38976
|
+
}
|
|
38924
38977
|
function extractUniqueSessionIds(events) {
|
|
38925
38978
|
const ids = /* @__PURE__ */ new Set();
|
|
38926
38979
|
for (const event of events) {
|
|
@@ -38959,6 +39012,14 @@ function buildFailureDiagnostic(result, request) {
|
|
|
38959
39012
|
const stdoutError = extractOpenCodeErrorMessage(result.ndjsonEvents);
|
|
38960
39013
|
const combined = [stderr, stdoutError].filter(Boolean).join("\n");
|
|
38961
39014
|
const model = request?.model ?? "";
|
|
39015
|
+
if (hasOpenCodeLengthFinish(result.ndjsonEvents)) {
|
|
39016
|
+
return {
|
|
39017
|
+
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.",
|
|
39018
|
+
hint: "Reduce agent output, keep only structured findings, or use a model/configuration that can complete the saved prompt without truncation.",
|
|
39019
|
+
stderr_excerpt: excerpt(stderr),
|
|
39020
|
+
stdout_excerpt: excerpt(result.stdout)
|
|
39021
|
+
};
|
|
39022
|
+
}
|
|
38962
39023
|
if (/session not found/i.test(combined)) {
|
|
38963
39024
|
return {
|
|
38964
39025
|
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.',
|
|
@@ -39056,7 +39117,7 @@ function newSessionId() {
|
|
|
39056
39117
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
39057
39118
|
return `${date}-opencode-process-review-${Date.now()}`;
|
|
39058
39119
|
}
|
|
39059
|
-
var runAgentsSubcommand = new Command("run-agents").description("Run OCR review through OpenCode process agents").argument("[target]", "Target path for fresh
|
|
39120
|
+
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(
|
|
39060
39121
|
async (target, options) => {
|
|
39061
39122
|
const targetDir = process.cwd();
|
|
39062
39123
|
requireOcrSetup(targetDir);
|
|
@@ -39452,7 +39513,7 @@ var reviewCommand = new Command("review").description("Run or resume an OCR revi
|
|
|
39452
39513
|
if (!options.resume) {
|
|
39453
39514
|
console.error(
|
|
39454
39515
|
source_default.yellow(
|
|
39455
|
-
"Running a fresh review from
|
|
39516
|
+
"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`."
|
|
39456
39517
|
)
|
|
39457
39518
|
);
|
|
39458
39519
|
console.error(
|
|
@@ -39729,76 +39790,9 @@ var updateCommand = new Command("update").description("Update OCR assets after p
|
|
|
39729
39790
|
console.log();
|
|
39730
39791
|
});
|
|
39731
39792
|
|
|
39732
|
-
// src/commands/dashboard.ts
|
|
39733
|
-
import { existsSync as existsSync25 } from "node:fs";
|
|
39734
|
-
import { join as join30, dirname as dirname12 } from "node:path";
|
|
39735
|
-
import { fileURLToPath } from "node:url";
|
|
39736
|
-
init_src();
|
|
39737
|
-
init_db();
|
|
39738
|
-
var __filename = fileURLToPath(import.meta.url);
|
|
39739
|
-
var __dirname = dirname12(__filename);
|
|
39740
|
-
function resolveServerPath() {
|
|
39741
|
-
return join30(__dirname, "dashboard", "server.js");
|
|
39742
|
-
}
|
|
39743
|
-
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(
|
|
39744
|
-
async (options) => {
|
|
39745
|
-
const targetDir = process.cwd();
|
|
39746
|
-
requireOcrSetup(targetDir);
|
|
39747
|
-
const port = parseInt(options.port, 10);
|
|
39748
|
-
if (isNaN(port) || port < 1 || port > 65535) {
|
|
39749
|
-
console.error(source_default.red(`Error: Invalid port "${options.port}". Must be 1-65535.`));
|
|
39750
|
-
process.exit(1);
|
|
39751
|
-
}
|
|
39752
|
-
const ocrDir = join30(targetDir, ".ocr");
|
|
39753
|
-
try {
|
|
39754
|
-
await ensureDatabase(ocrDir);
|
|
39755
|
-
closeAllDatabases();
|
|
39756
|
-
} catch (err) {
|
|
39757
|
-
console.error(source_default.red("Error: Failed to initialize database."));
|
|
39758
|
-
console.error(
|
|
39759
|
-
source_default.dim(
|
|
39760
|
-
` ${err instanceof Error ? err.message : String(err)}`
|
|
39761
|
-
)
|
|
39762
|
-
);
|
|
39763
|
-
process.exit(1);
|
|
39764
|
-
}
|
|
39765
|
-
const serverPath = resolveServerPath();
|
|
39766
|
-
if (!existsSync25(serverPath)) {
|
|
39767
|
-
console.error(source_default.red("Error: Dashboard server bundle not found."));
|
|
39768
|
-
console.error(
|
|
39769
|
-
source_default.dim(` Expected at: ${serverPath}`)
|
|
39770
|
-
);
|
|
39771
|
-
console.error(
|
|
39772
|
-
source_default.dim(" This may indicate a broken installation. Try reinstalling:")
|
|
39773
|
-
);
|
|
39774
|
-
console.error(source_default.white(" npm install -g @open-code-review/cli"));
|
|
39775
|
-
process.exit(1);
|
|
39776
|
-
}
|
|
39777
|
-
process.env.NODE_ENV = "production";
|
|
39778
|
-
console.log();
|
|
39779
|
-
console.log(source_default.bold(" OCR Dashboard"));
|
|
39780
|
-
console.log();
|
|
39781
|
-
try {
|
|
39782
|
-
const { startServer } = await importModule(serverPath);
|
|
39783
|
-
await startServer({ port, open: options.open });
|
|
39784
|
-
} catch (err) {
|
|
39785
|
-
console.error(source_default.red("Error: Failed to start dashboard server."));
|
|
39786
|
-
console.error(
|
|
39787
|
-
source_default.dim(
|
|
39788
|
-
` ${err instanceof Error ? err.message : String(err)}`
|
|
39789
|
-
)
|
|
39790
|
-
);
|
|
39791
|
-
process.exit(1);
|
|
39792
|
-
}
|
|
39793
|
-
console.log();
|
|
39794
|
-
console.log(source_default.dim(" Press Ctrl+C to stop"));
|
|
39795
|
-
console.log();
|
|
39796
|
-
}
|
|
39797
|
-
);
|
|
39798
|
-
|
|
39799
39793
|
// src/commands/doctor.ts
|
|
39800
|
-
import { existsSync as
|
|
39801
|
-
import { join as
|
|
39794
|
+
import { existsSync as existsSync25 } from "node:fs";
|
|
39795
|
+
import { join as join30 } from "node:path";
|
|
39802
39796
|
init_db();
|
|
39803
39797
|
function printStorageEngine(probeWriteEnabled) {
|
|
39804
39798
|
console.log();
|
|
@@ -39855,10 +39849,10 @@ var doctorCommand = new Command("doctor").description("Check OCR installation an
|
|
|
39855
39849
|
console.log(source_default.bold(" OCR Installation"));
|
|
39856
39850
|
console.log();
|
|
39857
39851
|
const ocrStatus = checkOcrSetup(targetDir);
|
|
39858
|
-
const configPath =
|
|
39859
|
-
const dbPath =
|
|
39860
|
-
const hasConfig =
|
|
39861
|
-
const hasDb =
|
|
39852
|
+
const configPath = join30(targetDir, ".ocr", "config.yaml");
|
|
39853
|
+
const dbPath = join30(targetDir, ".ocr", "data", "ocr.db");
|
|
39854
|
+
const hasConfig = existsSync25(configPath);
|
|
39855
|
+
const hasDb = existsSync25(dbPath);
|
|
39862
39856
|
const ocrChecks = [
|
|
39863
39857
|
{ label: ".ocr/skills/", ok: ocrStatus.hasSkills },
|
|
39864
39858
|
{ label: ".ocr/sessions/", ok: ocrStatus.hasSessions },
|
|
@@ -39927,7 +39921,7 @@ var doctorCommand = new Command("doctor").description("Check OCR installation an
|
|
|
39927
39921
|
console.log(source_default.green(" \u2713 Ready for code review"));
|
|
39928
39922
|
console.log(
|
|
39929
39923
|
source_default.dim(
|
|
39930
|
-
" Install Claude Code or OpenCode for
|
|
39924
|
+
" Install Claude Code or OpenCode for AI review commands"
|
|
39931
39925
|
)
|
|
39932
39926
|
);
|
|
39933
39927
|
}
|
|
@@ -39935,8 +39929,8 @@ var doctorCommand = new Command("doctor").description("Check OCR installation an
|
|
|
39935
39929
|
});
|
|
39936
39930
|
|
|
39937
39931
|
// src/commands/db.ts
|
|
39938
|
-
import { existsSync as
|
|
39939
|
-
import { join as
|
|
39932
|
+
import { existsSync as existsSync26, readFileSync as readFileSync18 } from "node:fs";
|
|
39933
|
+
import { join as join31 } from "node:path";
|
|
39940
39934
|
init_src();
|
|
39941
39935
|
init_db();
|
|
39942
39936
|
function fail4(message) {
|
|
@@ -39946,10 +39940,10 @@ function fail4(message) {
|
|
|
39946
39940
|
function resolveOcrDir() {
|
|
39947
39941
|
const targetDir = process.cwd();
|
|
39948
39942
|
requireOcrSetup(targetDir);
|
|
39949
|
-
return
|
|
39943
|
+
return join31(targetDir, ".ocr");
|
|
39950
39944
|
}
|
|
39951
39945
|
function dbPathFor(ocrDir) {
|
|
39952
|
-
return
|
|
39946
|
+
return join31(ocrDir, "data", "ocr.db");
|
|
39953
39947
|
}
|
|
39954
39948
|
function formatBytes(n) {
|
|
39955
39949
|
if (n < 1024) return `${n} B`;
|
|
@@ -39962,9 +39956,9 @@ function formatBytes(n) {
|
|
|
39962
39956
|
}
|
|
39963
39957
|
return `${v.toFixed(v >= 100 ? 0 : 1)} ${units[i]}`;
|
|
39964
39958
|
}
|
|
39965
|
-
function
|
|
39966
|
-
const pidFile =
|
|
39967
|
-
if (!
|
|
39959
|
+
function liveOcrOwnerPid(ocrDir) {
|
|
39960
|
+
const pidFile = join31(ocrDir, "data", "dashboard.pid");
|
|
39961
|
+
if (!existsSync26(pidFile)) return null;
|
|
39968
39962
|
try {
|
|
39969
39963
|
const pid = parseInt(readFileSync18(pidFile, "utf-8").trim(), 10);
|
|
39970
39964
|
if (!Number.isNaN(pid) && isProcessAlive(pid)) return pid;
|
|
@@ -39973,10 +39967,10 @@ function liveDashboardPid(ocrDir) {
|
|
|
39973
39967
|
return null;
|
|
39974
39968
|
}
|
|
39975
39969
|
function guardExclusive(ocrDir, force, op) {
|
|
39976
|
-
const pid =
|
|
39970
|
+
const pid = liveOcrOwnerPid(ocrDir);
|
|
39977
39971
|
if (pid !== null && !force) {
|
|
39978
39972
|
fail4(
|
|
39979
|
-
`
|
|
39973
|
+
`another OCR process appears to be running (PID ${pid}); ${op} needs exclusive access to the database.
|
|
39980
39974
|
Stop it first, or pass --force to proceed anyway.`
|
|
39981
39975
|
);
|
|
39982
39976
|
}
|
|
@@ -40044,7 +40038,7 @@ function printHealth(report) {
|
|
|
40044
40038
|
function needsFix(report) {
|
|
40045
40039
|
return !report.integrityOk || report.fkViolations.length > 0 || report.markdownDuplicateRows > 0 || report.orphanTempFiles.some((f) => f.reapable) || report.reclaimableBytes > 0;
|
|
40046
40040
|
}
|
|
40047
|
-
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
|
|
40041
|
+
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(
|
|
40048
40042
|
async (options) => {
|
|
40049
40043
|
const ocrDir = resolveOcrDir();
|
|
40050
40044
|
const dbPath = dbPathFor(ocrDir);
|
|
@@ -40123,7 +40117,7 @@ var doctorSubcommand = new Command("doctor").description("Report database health
|
|
|
40123
40117
|
console.log();
|
|
40124
40118
|
}
|
|
40125
40119
|
);
|
|
40126
|
-
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
|
|
40120
|
+
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) => {
|
|
40127
40121
|
const ocrDir = resolveOcrDir();
|
|
40128
40122
|
const dbPath = dbPathFor(ocrDir);
|
|
40129
40123
|
guardExclusive(ocrDir, options.force ?? false, "vacuum");
|
|
@@ -40148,7 +40142,7 @@ var pruneSubcommand = new Command("prune").description(
|
|
|
40148
40142
|
"--older-than <days>",
|
|
40149
40143
|
"only prune closed sessions quiet for more than D days",
|
|
40150
40144
|
(v) => parseInt(v, 10)
|
|
40151
|
-
).option("--dry-run", "show what would be pruned without deleting").option("--force", "proceed even if
|
|
40145
|
+
).option("--dry-run", "show what would be pruned without deleting").option("--force", "proceed even if another live OCR process owns the database").action(
|
|
40152
40146
|
async (options) => {
|
|
40153
40147
|
const ocrDir = resolveOcrDir();
|
|
40154
40148
|
const dbPath = dbPathFor(ocrDir);
|
|
@@ -40220,7 +40214,7 @@ var pruneBackupsSubcommand = new Command("prune-backups").description("Delete ol
|
|
|
40220
40214
|
1
|
|
40221
40215
|
).option("--force", "permit --keep 0 (removing the last backup / safety net)").option("--dry-run", "show what would be deleted without deleting").action(async (options) => {
|
|
40222
40216
|
const ocrDir = resolveOcrDir();
|
|
40223
|
-
const dataDir =
|
|
40217
|
+
const dataDir = join31(ocrDir, "data");
|
|
40224
40218
|
const invalid = validatePruneBackupsOptions(options);
|
|
40225
40219
|
if (invalid !== null) {
|
|
40226
40220
|
fail4(invalid);
|
|
@@ -40257,7 +40251,7 @@ var dbCommand = new Command("db").description("Inspect and maintain the OCR SQLi
|
|
|
40257
40251
|
|
|
40258
40252
|
// src/commands/reviewers.ts
|
|
40259
40253
|
import { writeFileSync as writeFileSync10, renameSync as renameSync2 } from "node:fs";
|
|
40260
|
-
import { join as
|
|
40254
|
+
import { join as join32 } from "node:path";
|
|
40261
40255
|
init_src();
|
|
40262
40256
|
async function readStdin3() {
|
|
40263
40257
|
const chunks = [];
|
|
@@ -40353,17 +40347,17 @@ function validateReviewersMeta(data) {
|
|
|
40353
40347
|
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) => {
|
|
40354
40348
|
const targetDir = process.cwd();
|
|
40355
40349
|
requireOcrSetup(targetDir);
|
|
40356
|
-
const ocrDir =
|
|
40350
|
+
const ocrDir = join32(targetDir, ".ocr");
|
|
40357
40351
|
if (!options.stdin) {
|
|
40358
40352
|
try {
|
|
40359
|
-
const reviewersDir =
|
|
40360
|
-
const configPath =
|
|
40353
|
+
const reviewersDir = join32(ocrDir, "skills", "references", "reviewers");
|
|
40354
|
+
const configPath = join32(ocrDir, "config.yaml");
|
|
40361
40355
|
const meta = generateReviewersMeta(reviewersDir, configPath);
|
|
40362
40356
|
if (!meta || meta.reviewers.length === 0) {
|
|
40363
40357
|
console.error(source_default.yellow("No reviewer files found in .ocr/skills/references/reviewers/"));
|
|
40364
40358
|
process.exit(1);
|
|
40365
40359
|
}
|
|
40366
|
-
const metaPath =
|
|
40360
|
+
const metaPath = join32(ocrDir, "reviewers-meta.json");
|
|
40367
40361
|
const tmpPath = metaPath + ".tmp";
|
|
40368
40362
|
writeFileSync10(tmpPath, JSON.stringify(meta, null, 2) + "\n");
|
|
40369
40363
|
renameSync2(tmpPath, metaPath);
|
|
@@ -40393,7 +40387,7 @@ var syncSubcommand2 = new Command("sync").description("Sync reviewers-meta.json
|
|
|
40393
40387
|
throw new Error("Invalid JSON on stdin");
|
|
40394
40388
|
}
|
|
40395
40389
|
const meta = validateReviewersMeta(parsed);
|
|
40396
|
-
const metaPath =
|
|
40390
|
+
const metaPath = join32(ocrDir, "reviewers-meta.json");
|
|
40397
40391
|
const tmpPath = metaPath + ".tmp";
|
|
40398
40392
|
writeFileSync10(tmpPath, JSON.stringify(meta, null, 2) + "\n");
|
|
40399
40393
|
renameSync2(tmpPath, metaPath);
|
|
@@ -40469,12 +40463,12 @@ var hostCommand = new Command("host").description("Inspect host (AI CLI) capabil
|
|
|
40469
40463
|
|
|
40470
40464
|
// src/lib/update-check.ts
|
|
40471
40465
|
import { homedir } from "node:os";
|
|
40472
|
-
import { join as
|
|
40466
|
+
import { join as join33 } from "node:path";
|
|
40473
40467
|
import { readFileSync as readFileSync19, writeFileSync as writeFileSync11, mkdirSync as mkdirSync9 } from "node:fs";
|
|
40474
40468
|
var PACKAGE_NAME = "@open-code-review/cli";
|
|
40475
40469
|
var REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
|
|
40476
|
-
var CACHE_DIR2 =
|
|
40477
|
-
var CACHE_FILE =
|
|
40470
|
+
var CACHE_DIR2 = join33(homedir(), ".ocr");
|
|
40471
|
+
var CACHE_FILE = join33(CACHE_DIR2, "update-check.json");
|
|
40478
40472
|
var CHECK_INTERVAL_MS = 4 * 60 * 60 * 1e3;
|
|
40479
40473
|
var FETCH_TIMEOUT_MS = 3e3;
|
|
40480
40474
|
function readCache(cacheFile) {
|
|
@@ -40486,7 +40480,7 @@ function readCache(cacheFile) {
|
|
|
40486
40480
|
}
|
|
40487
40481
|
function writeCache(cacheFile, cache2) {
|
|
40488
40482
|
try {
|
|
40489
|
-
mkdirSync9(
|
|
40483
|
+
mkdirSync9(join33(cacheFile, ".."), { recursive: true });
|
|
40490
40484
|
writeFileSync11(cacheFile, JSON.stringify(cache2));
|
|
40491
40485
|
} catch {
|
|
40492
40486
|
}
|
|
@@ -40507,7 +40501,7 @@ async function checkForUpdate(currentVersion, options) {
|
|
|
40507
40501
|
if (process.env.CI || process.env.OCR_NO_UPDATE_CHECK) {
|
|
40508
40502
|
return null;
|
|
40509
40503
|
}
|
|
40510
|
-
const cacheFile =
|
|
40504
|
+
const cacheFile = join33(options?.cacheDir ?? CACHE_DIR2, "update-check.json");
|
|
40511
40505
|
try {
|
|
40512
40506
|
const cache2 = readCache(cacheFile);
|
|
40513
40507
|
if (cache2 && Date.now() - cache2.lastCheck < CHECK_INTERVAL_MS) {
|
|
@@ -40551,7 +40545,7 @@ ${line2}
|
|
|
40551
40545
|
}
|
|
40552
40546
|
|
|
40553
40547
|
// src/index.ts
|
|
40554
|
-
var HUMAN_COMMANDS = /* @__PURE__ */ new Set(["init", "update", "doctor", "
|
|
40548
|
+
var HUMAN_COMMANDS = /* @__PURE__ */ new Set(["init", "update", "doctor", "progress"]);
|
|
40555
40549
|
var subcommand = process.argv[2];
|
|
40556
40550
|
var updateCheck = subcommand && HUMAN_COMMANDS.has(subcommand) ? checkForUpdate(CLI_VERSION) : null;
|
|
40557
40551
|
var program2 = new Command();
|
|
@@ -40564,7 +40558,6 @@ program2.addCommand(modelsCommand);
|
|
|
40564
40558
|
program2.addCommand(teamCommand);
|
|
40565
40559
|
program2.addCommand(reviewCommand);
|
|
40566
40560
|
program2.addCommand(updateCommand);
|
|
40567
|
-
program2.addCommand(dashboardCommand);
|
|
40568
40561
|
program2.addCommand(doctorCommand);
|
|
40569
40562
|
program2.addCommand(dbCommand);
|
|
40570
40563
|
program2.addCommand(reviewersCommand);
|