@nk070281sjv/cli 2.3.7 → 2.3.8

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.
Files changed (2) hide show
  1. package/dist/index.js +306 -20
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -30779,7 +30779,7 @@ ${hint}
30779
30779
  }
30780
30780
 
30781
30781
  // src/lib/version.ts
30782
- var CLI_VERSION = true ? "2.3.7" : createRequire(import.meta.url)("../../package.json").version;
30782
+ var CLI_VERSION = true ? "2.3.8" : createRequire(import.meta.url)("../../package.json").version;
30783
30783
 
30784
30784
  // src/lib/deps.ts
30785
30785
  init_src();
@@ -37218,7 +37218,15 @@ var teamCommand = new Command("team").description("Resolve and persist team comp
37218
37218
  // src/commands/review.ts
37219
37219
  init_src();
37220
37220
  import { join as join28 } from "node:path";
37221
- import { existsSync as existsSync23, readFileSync as readFileSync17 } from "node:fs";
37221
+ import {
37222
+ closeSync,
37223
+ existsSync as existsSync23,
37224
+ mkdirSync as mkdirSync8,
37225
+ openSync,
37226
+ readdirSync as readdirSync9,
37227
+ readFileSync as readFileSync17,
37228
+ writeFileSync as writeFileSync9
37229
+ } from "node:fs";
37222
37230
  init_db();
37223
37231
 
37224
37232
  // ../shared/config/src/pipeline-config.ts
@@ -37413,6 +37421,7 @@ import { execFile } from "node:child_process";
37413
37421
  import { promisify } from "node:util";
37414
37422
  var execFileAsync = promisify(execFile);
37415
37423
  var GIT_SNAPSHOT_LIMIT = 2e4;
37424
+ var REVIEW_SNAPSHOT_EXCLUDES = [".ocr", ".opencode"];
37416
37425
  async function prepareReviewContext(input) {
37417
37426
  const roundDir = join25(input.sessionDir, "rounds", `round-${input.round}`);
37418
37427
  await mkdir2(roundDir, { recursive: true });
@@ -37444,7 +37453,7 @@ async function prepareReviewContext(input) {
37444
37453
  "## Scope",
37445
37454
  "",
37446
37455
  "Review the current working tree changes. Focus on changed files and the unchanged code needed to validate those changes.",
37447
- "Do not review generated OCR session artifacts under `.ocr/sessions/` unless they are explicitly part of the requested change.",
37456
+ "Ignore local AI tooling/config churn under `.ocr/` and `.opencode/` unless the user explicitly asks to review OCR/OpenCode setup changes.",
37448
37457
  "",
37449
37458
  ...gitSnapshot ? [
37450
37459
  "## Git Status",
@@ -37517,17 +37526,20 @@ async function prepareReviewContext(input) {
37517
37526
  async function collectGitSnapshot(cwd) {
37518
37527
  const [status, cachedFiles, worktreeFiles, diffStat] = await Promise.all([
37519
37528
  runGit(cwd, ["status", "--short"]),
37520
- runGit(cwd, ["diff", "--cached", "--name-only"]),
37521
- runGit(cwd, ["diff", "--name-only", "HEAD"]),
37522
- runGit(cwd, ["diff", "--stat", "HEAD"])
37529
+ runGit(cwd, ["diff", "--cached", "--name-only", "--", ...gitReviewPathspec()]),
37530
+ runGit(cwd, ["diff", "--name-only", "HEAD", "--", ...gitReviewPathspec()]),
37531
+ runGit(cwd, ["diff", "--stat", "HEAD", "--", ...gitReviewPathspec()])
37523
37532
  ]);
37524
37533
  return {
37525
- status,
37526
- changedFiles: uniqueLines(`${cachedFiles}
37527
- ${worktreeFiles}`),
37534
+ status: filterIgnoredStatusLines(status),
37535
+ changedFiles: filterIgnoredPaths(uniqueLines(`${cachedFiles}
37536
+ ${worktreeFiles}`)),
37528
37537
  diffStat
37529
37538
  };
37530
37539
  }
37540
+ function gitReviewPathspec() {
37541
+ return [".", ...REVIEW_SNAPSHOT_EXCLUDES.map((path2) => `:(exclude)${path2}`)];
37542
+ }
37531
37543
  async function runGit(cwd, args) {
37532
37544
  try {
37533
37545
  const { stdout, stderr } = await execFileAsync("git", args, {
@@ -37547,6 +37559,21 @@ function uniqueLines(value) {
37547
37559
  const lines = value.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
37548
37560
  return [...new Set(lines)].join("\n");
37549
37561
  }
37562
+ function filterIgnoredStatusLines(value) {
37563
+ return value.split(/\r?\n/).filter((line) => {
37564
+ const pathPart = line.slice(3).trim();
37565
+ return !isIgnoredReviewPath(pathPart);
37566
+ }).join("\n");
37567
+ }
37568
+ function filterIgnoredPaths(value) {
37569
+ return value.split(/\r?\n/).filter((line) => !isIgnoredReviewPath(line.trim())).join("\n");
37570
+ }
37571
+ function isIgnoredReviewPath(path2) {
37572
+ const normalized = path2.replace(/^"|"$/g, "");
37573
+ return REVIEW_SNAPSHOT_EXCLUDES.some(
37574
+ (ignored) => normalized === ignored || normalized.startsWith(`${ignored}/`)
37575
+ );
37576
+ }
37550
37577
  function truncate(value) {
37551
37578
  if (value.length <= GIT_SNAPSHOT_LIMIT) return value;
37552
37579
  return `${value.slice(0, GIT_SNAPSHOT_LIMIT)}
@@ -38038,7 +38065,7 @@ async function runReviewerPhase(input) {
38038
38065
  total: requests.length,
38039
38066
  running: [...running].sort()
38040
38067
  });
38041
- }, 3e4);
38068
+ }, 15e3);
38042
38069
  progressTimer.unref?.();
38043
38070
  const promises = reviewerRequests.map(async ({ reviewer, request }) => {
38044
38071
  const agentSessionId = await journal.startInstance({
@@ -38174,7 +38201,12 @@ async function runOpenCodeProcessAgentReview(input) {
38174
38201
  round: input.round,
38175
38202
  reviewers: snapshot.resolvedTeam.reviewers.length
38176
38203
  });
38177
- emit({ event: "reviews:start", session_id: input.sessionId, round: input.round });
38204
+ emit({
38205
+ event: "reviews:start",
38206
+ session_id: input.sessionId,
38207
+ round: input.round,
38208
+ reviewers: snapshot.resolvedTeam.reviewers.length
38209
+ });
38178
38210
  const reviewerResult = await runReviewerPhase({
38179
38211
  context,
38180
38212
  resolvedTeam: snapshot.resolvedTeam,
@@ -38268,7 +38300,21 @@ async function runPipelineStages(input) {
38268
38300
  prompt_path: request.promptPath,
38269
38301
  meta_log: startLogPaths.meta
38270
38302
  });
38271
- const result = await input.runner.run(request, new AbortController().signal);
38303
+ const progressTimer = setInterval(() => {
38304
+ emit({
38305
+ event: "agent:progress",
38306
+ phase: stage,
38307
+ id: request.id,
38308
+ status: "running"
38309
+ });
38310
+ }, 15e3);
38311
+ progressTimer.unref?.();
38312
+ let result;
38313
+ try {
38314
+ result = await input.runner.run(request, new AbortController().signal);
38315
+ } finally {
38316
+ clearInterval(progressTimer);
38317
+ }
38272
38318
  const logPaths = await writeProcessLogs(input.context.roundDir, request, result);
38273
38319
  emit({
38274
38320
  event: "agent:complete",
@@ -38542,12 +38588,15 @@ function newSessionId() {
38542
38588
  const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
38543
38589
  return `${date}-opencode-process-review-${Date.now()}`;
38544
38590
  }
38545
- var runAgentsSubcommand = new Command("run-agents").description("Run OCR review through OpenCode process agents").argument("[target]", "Target path for fresh dashboard 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").action(
38591
+ var runAgentsSubcommand = new Command("run-agents").description("Run OCR review through OpenCode process agents").argument("[target]", "Target path for fresh dashboard 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").addOption(new Option("--worker", "Internal detached worker mode").hideHelp()).action(
38546
38592
  async (target, options) => {
38547
38593
  const targetDir = process.cwd();
38548
38594
  requireOcrSetup(targetDir);
38549
38595
  const ocrDir = join28(targetDir, ".ocr");
38550
38596
  const db = await ensureDatabase(ocrDir);
38597
+ let sessionDirForMeta;
38598
+ let roundForMeta;
38599
+ const modeForMeta = options.worker ? "worker" : options.foreground ? "foreground" : "detached";
38551
38600
  try {
38552
38601
  let sessionId = options.sessionId;
38553
38602
  let round = options.round;
@@ -38578,6 +38627,33 @@ var runAgentsSubcommand = new Command("run-agents").description("Run OCR review
38578
38627
  round = round ?? session.current_round;
38579
38628
  sessionDir = session.session_dir;
38580
38629
  }
38630
+ sessionDirForMeta = sessionDir;
38631
+ roundForMeta = round;
38632
+ if (!options.foreground && !options.worker) {
38633
+ const spawned = spawnDetachedRunAgents({
38634
+ targetDir,
38635
+ target,
38636
+ sessionId,
38637
+ sessionDir,
38638
+ round,
38639
+ requirements: options.requirements,
38640
+ team: options.team
38641
+ });
38642
+ console.log(`OCR review started in background.`);
38643
+ console.log(`Session: ${sessionId}`);
38644
+ console.log(`Round: ${round}`);
38645
+ console.log(`PID: ${spawned.pid}`);
38646
+ console.log(`Progress: ocr review watch --session-id ${sessionId}`);
38647
+ console.log(`Status: ocr review status --session-id ${sessionId}`);
38648
+ console.log(`Artifacts: ${sessionDir}`);
38649
+ return;
38650
+ }
38651
+ writeRunMeta(sessionDir, round, {
38652
+ status: "running",
38653
+ mode: options.worker ? "worker" : "foreground",
38654
+ pid: process.pid,
38655
+ started_at: (/* @__PURE__ */ new Date()).toISOString()
38656
+ });
38581
38657
  const { team } = loadTeamConfig(ocrDir);
38582
38658
  const override = options.team ? parseTeamOverride(options.team) : void 0;
38583
38659
  const reviewers = resolveTeamComposition(team, override);
@@ -38591,18 +38667,226 @@ var runAgentsSubcommand = new Command("run-agents").description("Run OCR review
38591
38667
  pipelineAgents,
38592
38668
  requirements: readRequirements(options.requirements),
38593
38669
  journal: new PersistenceAgentLifecycleJournal(ocrDir),
38594
- emit: (event) => console.log(JSON.stringify(event))
38670
+ emit: (event) => {
38671
+ console.log(JSON.stringify(event));
38672
+ renderRunAgentsProgress(event);
38673
+ }
38595
38674
  });
38596
38675
  if (!result.ok) {
38676
+ writeRunMeta(sessionDir, round, {
38677
+ status: "failed",
38678
+ mode: options.worker ? "worker" : "foreground",
38679
+ pid: process.pid,
38680
+ completed_at: (/* @__PURE__ */ new Date()).toISOString(),
38681
+ errors: result.errors
38682
+ });
38597
38683
  for (const error of result.errors) console.error(source_default.red(error));
38598
38684
  process.exit(1);
38599
38685
  }
38686
+ writeRunMeta(sessionDir, round, {
38687
+ status: "completed",
38688
+ mode: options.worker ? "worker" : "foreground",
38689
+ pid: process.pid,
38690
+ completed_at: (/* @__PURE__ */ new Date()).toISOString()
38691
+ });
38600
38692
  console.log(JSON.stringify({ event: "review:complete", session_id: sessionId, round }));
38601
38693
  } catch (error) {
38694
+ if (sessionDirForMeta && roundForMeta) {
38695
+ writeRunMeta(sessionDirForMeta, roundForMeta, {
38696
+ status: "failed",
38697
+ mode: modeForMeta,
38698
+ pid: process.pid,
38699
+ completed_at: (/* @__PURE__ */ new Date()).toISOString(),
38700
+ errors: [error instanceof Error ? error.message : "Failed to run OpenCode process-agent review"]
38701
+ });
38702
+ }
38602
38703
  fail3(error instanceof Error ? error.message : "Failed to run OpenCode process-agent review");
38603
38704
  }
38604
38705
  }
38605
38706
  );
38707
+ var statusSubcommand2 = new Command("status").description("Show process-agent review status").requiredOption("--session-id <workflow-session-id>", "Workflow session id").option("--round <n>", "Round number", (value) => Number.parseInt(value, 10)).action(async (options) => {
38708
+ const targetDir = process.cwd();
38709
+ requireOcrSetup(targetDir);
38710
+ const ocrDir = join28(targetDir, ".ocr");
38711
+ const db = await ensureDatabase(ocrDir);
38712
+ const session = getSession(db, options.sessionId);
38713
+ if (!session) fail3(`Workflow session not found: ${options.sessionId}`);
38714
+ renderReviewStatus(session.session_dir, options.round ?? session.current_round);
38715
+ });
38716
+ var watchSubcommand = new Command("watch").description("Watch process-agent review progress").requiredOption("--session-id <workflow-session-id>", "Workflow session id").option("--round <n>", "Round number", (value) => Number.parseInt(value, 10)).option("--interval <seconds>", "Refresh interval", (value) => Number.parseInt(value, 10), 2).action(async (options) => {
38717
+ const targetDir = process.cwd();
38718
+ requireOcrSetup(targetDir);
38719
+ const ocrDir = join28(targetDir, ".ocr");
38720
+ const db = await ensureDatabase(ocrDir);
38721
+ const session = getSession(db, options.sessionId);
38722
+ if (!session) fail3(`Workflow session not found: ${options.sessionId}`);
38723
+ const round = options.round ?? session.current_round;
38724
+ renderReviewStatus(session.session_dir, round);
38725
+ setInterval(() => {
38726
+ process.stdout.write("\x1Bc");
38727
+ renderReviewStatus(session.session_dir, round);
38728
+ }, Math.max(1, options.interval) * 1e3);
38729
+ });
38730
+ function spawnDetachedRunAgents(input) {
38731
+ const roundDir = join28(input.sessionDir, "rounds", `round-${input.round}`);
38732
+ mkdirSync8(join28(roundDir, "process-logs"), { recursive: true });
38733
+ const stdoutPath = join28(roundDir, "process-logs", "run-agents-worker.stdout.log");
38734
+ const stderrPath = join28(roundDir, "process-logs", "run-agents-worker.stderr.log");
38735
+ const outFd = openSync(stdoutPath, "a");
38736
+ const errFd = openSync(stderrPath, "a");
38737
+ const entrypoint = process.argv[1];
38738
+ if (!entrypoint) fail3("Cannot locate OCR CLI entrypoint for background worker.");
38739
+ const args = [
38740
+ entrypoint,
38741
+ "review",
38742
+ "run-agents",
38743
+ input.target,
38744
+ "--session-id",
38745
+ input.sessionId,
38746
+ "--round",
38747
+ String(input.round),
38748
+ "--worker",
38749
+ "--foreground",
38750
+ ...input.requirements ? ["--requirements", input.requirements] : [],
38751
+ ...input.team ? ["--team", input.team] : []
38752
+ ];
38753
+ const child = spawnBinary(process.execPath, args, {
38754
+ cwd: input.targetDir,
38755
+ detached: true,
38756
+ stdio: ["ignore", outFd, errFd]
38757
+ });
38758
+ child.unref();
38759
+ closeSync(outFd);
38760
+ closeSync(errFd);
38761
+ writeRunMeta(input.sessionDir, input.round, {
38762
+ status: "spawned",
38763
+ mode: "detached",
38764
+ pid: child.pid,
38765
+ started_at: (/* @__PURE__ */ new Date()).toISOString(),
38766
+ stdout_log: stdoutPath,
38767
+ stderr_log: stderrPath
38768
+ });
38769
+ return { pid: child.pid };
38770
+ }
38771
+ function writeRunMeta(sessionDir, round, patch) {
38772
+ const roundDir = join28(sessionDir, "rounds", `round-${round}`);
38773
+ mkdirSync8(roundDir, { recursive: true });
38774
+ const path2 = join28(roundDir, "run-meta.json");
38775
+ let current = { schema_version: 1 };
38776
+ if (existsSync23(path2)) {
38777
+ try {
38778
+ const parsed = JSON.parse(readFileSync17(path2, "utf-8"));
38779
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
38780
+ current = parsed;
38781
+ }
38782
+ } catch {
38783
+ current = { schema_version: 1 };
38784
+ }
38785
+ }
38786
+ writeFileSync9(path2, JSON.stringify({ ...current, ...patch }, null, 2), "utf-8");
38787
+ }
38788
+ function renderReviewStatus(sessionDir, round) {
38789
+ const roundDir = join28(sessionDir, "rounds", `round-${round}`);
38790
+ const processLogsDir = join28(roundDir, "process-logs");
38791
+ const runMeta = readJson(join28(roundDir, "run-meta.json"));
38792
+ console.log(source_default.bold(`OCR review status: ${sessionDir}`));
38793
+ console.log(`Round: ${round}`);
38794
+ if (runMeta) {
38795
+ const pid = typeof runMeta.pid === "number" ? runMeta.pid : void 0;
38796
+ console.log(
38797
+ `Runner: ${String(runMeta.status ?? "unknown")}${pid ? ` pid=${pid} live=${isPidLive(pid) ? "yes" : "no"}` : ""}`
38798
+ );
38799
+ }
38800
+ const metas = existsSync23(processLogsDir) ? readdirMetaFiles(processLogsDir).map((path2) => readJson(path2)).filter(isRecord3) : [];
38801
+ const reviewers = metas.filter((meta) => meta.phase === "reviews");
38802
+ const completedReviewers = reviewers.filter((meta) => meta.status === "completed");
38803
+ const runningReviewers = reviewers.filter((meta) => meta.status === "running");
38804
+ console.log(`Reviews: ${completedReviewers.length}/${reviewers.length || "?"} complete`);
38805
+ if (runningReviewers.length > 0) {
38806
+ console.log(`Running reviewers: ${runningReviewers.map((meta) => meta.id).join(", ")}`);
38807
+ }
38808
+ for (const phase of ["aggregation", "validation", "synthesis"]) {
38809
+ const meta = metas.find((item) => item.id === phase);
38810
+ console.log(`Pipeline ${phase}: ${String(meta?.status ?? "pending")}`);
38811
+ }
38812
+ if (existsSync23(join28(roundDir, "final.md"))) {
38813
+ console.log(source_default.green(`Final: ${join28(roundDir, "final.md")}`));
38814
+ }
38815
+ }
38816
+ function readdirMetaFiles(dir) {
38817
+ return existsSync23(dir) ? Array.from(new Set(readdirSync9(dir))).filter((name) => name.endsWith(".meta.json")).sort().map((name) => join28(dir, name)) : [];
38818
+ }
38819
+ function readJson(path2) {
38820
+ if (!existsSync23(path2)) return void 0;
38821
+ try {
38822
+ const parsed = JSON.parse(readFileSync17(path2, "utf-8"));
38823
+ return isRecord3(parsed) ? parsed : void 0;
38824
+ } catch {
38825
+ return void 0;
38826
+ }
38827
+ }
38828
+ function isPidLive(pid) {
38829
+ try {
38830
+ process.kill(pid, 0);
38831
+ return true;
38832
+ } catch {
38833
+ return false;
38834
+ }
38835
+ }
38836
+ function isRecord3(value) {
38837
+ return typeof value === "object" && value !== null && !Array.isArray(value);
38838
+ }
38839
+ function renderRunAgentsProgress(event) {
38840
+ const name = typeof event.event === "string" ? event.event : "";
38841
+ if (name === "reviews:start") {
38842
+ console.error(
38843
+ source_default.cyan(
38844
+ `OCR reviewers started: ${String(event.reviewers ?? "?")} agents running in parallel.`
38845
+ )
38846
+ );
38847
+ return;
38848
+ }
38849
+ if (name === "agent:start") {
38850
+ console.error(
38851
+ source_default.dim(
38852
+ `OCR agent started: ${String(event.id ?? "?")} (${String(event.phase ?? "?")}, ${String(event.model ?? "?")})`
38853
+ )
38854
+ );
38855
+ return;
38856
+ }
38857
+ if (name === "reviews:progress") {
38858
+ const running = Array.isArray(event.running) ? event.running.join(", ") : "?";
38859
+ console.error(
38860
+ source_default.cyan(
38861
+ `OCR reviews progress: ${String(event.completed ?? "?")}/${String(event.total ?? "?")} complete; running: ${running || "none"}`
38862
+ )
38863
+ );
38864
+ return;
38865
+ }
38866
+ if (name === "agent:complete") {
38867
+ console.error(
38868
+ source_default.green(
38869
+ `OCR agent completed: ${String(event.id ?? "?")} exit=${String(event.exit_code ?? "?")}`
38870
+ )
38871
+ );
38872
+ return;
38873
+ }
38874
+ if (name === "agent:progress") {
38875
+ console.error(
38876
+ source_default.cyan(
38877
+ `OCR agent still running: ${String(event.id ?? "?")} (${String(event.phase ?? "?")})`
38878
+ )
38879
+ );
38880
+ return;
38881
+ }
38882
+ if (name === "pipeline:start") {
38883
+ console.error(source_default.cyan("OCR pipeline started: aggregation -> validation -> synthesis."));
38884
+ return;
38885
+ }
38886
+ if (name === "pipeline:complete") {
38887
+ console.error(source_default.green("OCR pipeline complete."));
38888
+ }
38889
+ }
38606
38890
  var CONTROL_PROMPT = "Resume this OCR review: run `ocr state status --json` and act on `next_action`, continuing forward from `current_phase` without redoing completed phases.";
38607
38891
  var reviewCommand = new Command("review").description("Run or resume an OCR review").option("--resume <workflow-id>", "Resume a prior review by its workflow session id").action(async (options) => {
38608
38892
  if (!options.resume) {
@@ -38723,6 +39007,8 @@ var reviewCommand = new Command("review").description("Run or resume an OCR revi
38723
39007
  });
38724
39008
  });
38725
39009
  reviewCommand.addCommand(runAgentsSubcommand);
39010
+ reviewCommand.addCommand(statusSubcommand2);
39011
+ reviewCommand.addCommand(watchSubcommand);
38726
39012
 
38727
39013
  // src/commands/update.ts
38728
39014
  import { existsSync as existsSync24 } from "node:fs";
@@ -39409,7 +39695,7 @@ var pruneBackupsSubcommand = new Command("prune-backups").description("Delete ol
39409
39695
  var dbCommand = new Command("db").description("Inspect and maintain the OCR SQLite database").addCommand(doctorSubcommand).addCommand(vacuumSubcommand).addCommand(pruneSubcommand).addCommand(pruneBackupsSubcommand);
39410
39696
 
39411
39697
  // src/commands/reviewers.ts
39412
- import { writeFileSync as writeFileSync9, renameSync as renameSync2 } from "node:fs";
39698
+ import { writeFileSync as writeFileSync10, renameSync as renameSync2 } from "node:fs";
39413
39699
  import { join as join33 } from "node:path";
39414
39700
  init_src();
39415
39701
  async function readStdin3() {
@@ -39518,7 +39804,7 @@ var syncSubcommand2 = new Command("sync").description("Sync reviewers-meta.json
39518
39804
  }
39519
39805
  const metaPath = join33(ocrDir, "reviewers-meta.json");
39520
39806
  const tmpPath = metaPath + ".tmp";
39521
- writeFileSync9(tmpPath, JSON.stringify(meta, null, 2) + "\n");
39807
+ writeFileSync10(tmpPath, JSON.stringify(meta, null, 2) + "\n");
39522
39808
  renameSync2(tmpPath, metaPath);
39523
39809
  const tierCounts = meta.reviewers.reduce(
39524
39810
  (acc, r) => {
@@ -39548,7 +39834,7 @@ var syncSubcommand2 = new Command("sync").description("Sync reviewers-meta.json
39548
39834
  const meta = validateReviewersMeta(parsed);
39549
39835
  const metaPath = join33(ocrDir, "reviewers-meta.json");
39550
39836
  const tmpPath = metaPath + ".tmp";
39551
- writeFileSync9(tmpPath, JSON.stringify(meta, null, 2) + "\n");
39837
+ writeFileSync10(tmpPath, JSON.stringify(meta, null, 2) + "\n");
39552
39838
  renameSync2(tmpPath, metaPath);
39553
39839
  const tierCounts = meta.reviewers.reduce(
39554
39840
  (acc, r) => {
@@ -39623,7 +39909,7 @@ var hostCommand = new Command("host").description("Inspect host (AI CLI) capabil
39623
39909
  // src/lib/update-check.ts
39624
39910
  import { homedir } from "node:os";
39625
39911
  import { join as join34 } from "node:path";
39626
- import { readFileSync as readFileSync19, writeFileSync as writeFileSync10, mkdirSync as mkdirSync8 } from "node:fs";
39912
+ import { readFileSync as readFileSync19, writeFileSync as writeFileSync11, mkdirSync as mkdirSync9 } from "node:fs";
39627
39913
  var PACKAGE_NAME = "@open-code-review/cli";
39628
39914
  var REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
39629
39915
  var CACHE_DIR2 = join34(homedir(), ".ocr");
@@ -39639,8 +39925,8 @@ function readCache(cacheFile) {
39639
39925
  }
39640
39926
  function writeCache(cacheFile, cache2) {
39641
39927
  try {
39642
- mkdirSync8(join34(cacheFile, ".."), { recursive: true });
39643
- writeFileSync10(cacheFile, JSON.stringify(cache2));
39928
+ mkdirSync9(join34(cacheFile, ".."), { recursive: true });
39929
+ writeFileSync11(cacheFile, JSON.stringify(cache2));
39644
39930
  } catch {
39645
39931
  }
39646
39932
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nk070281sjv/cli",
3
- "version": "2.3.7",
3
+ "version": "2.3.8",
4
4
  "description": "CLI for Open Code Review - Multi-environment setup and progress tracking",
5
5
  "type": "module",
6
6
  "bin": {
@@ -37,7 +37,7 @@
37
37
  },
38
38
  "dependencies": {
39
39
  "@inquirer/prompts": "^7.2.0",
40
- "@nk070281sjv/agents": "2.3.7",
40
+ "@nk070281sjv/agents": "2.3.8",
41
41
  "chalk": "^5.4.1",
42
42
  "chokidar": "^4.0.3",
43
43
  "commander": "^13.0.0",