@open-code-review/cli 1.9.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dashboard/server.js +409 -213
- package/dist/index.js +251 -121
- package/dist/lib/db/index.js +128 -17
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -16307,6 +16307,14 @@ var init_migrations = __esm({
|
|
|
16307
16307
|
sql: `
|
|
16308
16308
|
ALTER TABLE map_runs ADD COLUMN source TEXT DEFAULT NULL;
|
|
16309
16309
|
ALTER TABLE map_runs ADD COLUMN section_count INTEGER DEFAULT 0;
|
|
16310
|
+
`
|
|
16311
|
+
},
|
|
16312
|
+
{
|
|
16313
|
+
version: 9,
|
|
16314
|
+
description: "Add uid column to command_executions for JSONL-backed recovery",
|
|
16315
|
+
sql: `
|
|
16316
|
+
ALTER TABLE command_executions ADD COLUMN uid TEXT;
|
|
16317
|
+
CREATE UNIQUE INDEX idx_command_executions_uid ON command_executions(uid);
|
|
16310
16318
|
`
|
|
16311
16319
|
}
|
|
16312
16320
|
];
|
|
@@ -16428,14 +16436,121 @@ var init_queries = __esm({
|
|
|
16428
16436
|
}
|
|
16429
16437
|
});
|
|
16430
16438
|
|
|
16439
|
+
// src/lib/db/command-log.ts
|
|
16440
|
+
import { appendFileSync, existsSync as existsSync9, mkdirSync as mkdirSync3, readFileSync as readFileSync8, renameSync, writeFileSync as writeFileSync6 } from "node:fs";
|
|
16441
|
+
import { dirname as dirname4, join as join11 } from "node:path";
|
|
16442
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
16443
|
+
function generateCommandUid() {
|
|
16444
|
+
return randomUUID2();
|
|
16445
|
+
}
|
|
16446
|
+
function cacheDir(ocrDir) {
|
|
16447
|
+
return join11(ocrDir, "data", CACHE_DIR);
|
|
16448
|
+
}
|
|
16449
|
+
function commandLogPath(ocrDir) {
|
|
16450
|
+
return join11(cacheDir(ocrDir), FILENAME);
|
|
16451
|
+
}
|
|
16452
|
+
function appendCommandLog(ocrDir, entry) {
|
|
16453
|
+
try {
|
|
16454
|
+
const filePath = commandLogPath(ocrDir);
|
|
16455
|
+
const dir = dirname4(filePath);
|
|
16456
|
+
if (!existsSync9(dir)) mkdirSync3(dir, { recursive: true });
|
|
16457
|
+
const line = JSON.stringify(entry) + "\n";
|
|
16458
|
+
appendFileSync(filePath, line, { encoding: "utf-8" });
|
|
16459
|
+
if (approxLineCount >= 0) approxLineCount++;
|
|
16460
|
+
rotateIfNeeded(filePath);
|
|
16461
|
+
} catch {
|
|
16462
|
+
}
|
|
16463
|
+
}
|
|
16464
|
+
function readCommandLog(ocrDir) {
|
|
16465
|
+
const filePath = commandLogPath(ocrDir);
|
|
16466
|
+
if (!existsSync9(filePath)) return [];
|
|
16467
|
+
const content = readFileSync8(filePath, "utf-8");
|
|
16468
|
+
const entries = [];
|
|
16469
|
+
for (const line of content.split("\n")) {
|
|
16470
|
+
if (!line.trim()) continue;
|
|
16471
|
+
try {
|
|
16472
|
+
entries.push(JSON.parse(line));
|
|
16473
|
+
} catch {
|
|
16474
|
+
}
|
|
16475
|
+
}
|
|
16476
|
+
return entries;
|
|
16477
|
+
}
|
|
16478
|
+
function replayCommandLog(db, ocrDir) {
|
|
16479
|
+
const entries = readCommandLog(ocrDir);
|
|
16480
|
+
if (entries.length === 0) return 0;
|
|
16481
|
+
const latest = /* @__PURE__ */ new Map();
|
|
16482
|
+
for (const entry of entries) {
|
|
16483
|
+
if (!entry.uid || !entry.command || !entry.started_at) continue;
|
|
16484
|
+
const existing = latest.get(entry.uid);
|
|
16485
|
+
if (!existing || entry.event !== "start") {
|
|
16486
|
+
latest.set(entry.uid, entry);
|
|
16487
|
+
}
|
|
16488
|
+
}
|
|
16489
|
+
let imported = 0;
|
|
16490
|
+
for (const entry of latest.values()) {
|
|
16491
|
+
if (entry.event === "start" && !entry.finished_at) continue;
|
|
16492
|
+
const existing = db.exec(
|
|
16493
|
+
"SELECT COUNT(*) as c FROM command_executions WHERE uid = ?",
|
|
16494
|
+
[entry.uid]
|
|
16495
|
+
);
|
|
16496
|
+
if ((existing[0]?.values[0]?.[0] ?? 0) > 0) continue;
|
|
16497
|
+
db.run(
|
|
16498
|
+
`INSERT INTO command_executions
|
|
16499
|
+
(uid, command, args, exit_code, started_at, finished_at, pid, is_detached)
|
|
16500
|
+
VALUES (?, ?, ?, ?, ?, ?, NULL, ?)`,
|
|
16501
|
+
[
|
|
16502
|
+
entry.uid,
|
|
16503
|
+
entry.command,
|
|
16504
|
+
entry.args,
|
|
16505
|
+
entry.exit_code,
|
|
16506
|
+
entry.started_at,
|
|
16507
|
+
entry.finished_at,
|
|
16508
|
+
entry.is_detached
|
|
16509
|
+
]
|
|
16510
|
+
);
|
|
16511
|
+
imported++;
|
|
16512
|
+
}
|
|
16513
|
+
return imported;
|
|
16514
|
+
}
|
|
16515
|
+
function rotateIfNeeded(filePath) {
|
|
16516
|
+
try {
|
|
16517
|
+
if (approxLineCount >= 0 && approxLineCount <= MAX_LINES) return;
|
|
16518
|
+
const content = readFileSync8(filePath, "utf-8");
|
|
16519
|
+
const lines = content.split("\n").filter((l) => l.trim());
|
|
16520
|
+
approxLineCount = lines.length;
|
|
16521
|
+
if (approxLineCount <= MAX_LINES) return;
|
|
16522
|
+
const kept = lines.slice(lines.length - KEEP_LINES);
|
|
16523
|
+
const tmpPath = `${filePath}.${process.pid}.tmp`;
|
|
16524
|
+
writeFileSync6(tmpPath, kept.join("\n") + "\n", { encoding: "utf-8" });
|
|
16525
|
+
renameSync(tmpPath, filePath);
|
|
16526
|
+
approxLineCount = KEEP_LINES;
|
|
16527
|
+
} catch {
|
|
16528
|
+
}
|
|
16529
|
+
}
|
|
16530
|
+
var CACHE_DIR, FILENAME, MAX_LINES, KEEP_LINES, approxLineCount;
|
|
16531
|
+
var init_command_log = __esm({
|
|
16532
|
+
"src/lib/db/command-log.ts"() {
|
|
16533
|
+
"use strict";
|
|
16534
|
+
CACHE_DIR = ".cache";
|
|
16535
|
+
FILENAME = "command-history.jsonl";
|
|
16536
|
+
MAX_LINES = 5e3;
|
|
16537
|
+
KEEP_LINES = 4e3;
|
|
16538
|
+
approxLineCount = -1;
|
|
16539
|
+
}
|
|
16540
|
+
});
|
|
16541
|
+
|
|
16431
16542
|
// src/lib/db/index.ts
|
|
16432
16543
|
var db_exports = {};
|
|
16433
16544
|
__export(db_exports, {
|
|
16434
16545
|
MIGRATIONS: () => MIGRATIONS,
|
|
16546
|
+
appendCommandLog: () => appendCommandLog,
|
|
16435
16547
|
applyPragmas: () => applyPragmas,
|
|
16548
|
+
cacheDir: () => cacheDir,
|
|
16436
16549
|
closeAllDatabases: () => closeAllDatabases,
|
|
16437
16550
|
closeDatabase: () => closeDatabase,
|
|
16551
|
+
commandLogPath: () => commandLogPath,
|
|
16438
16552
|
ensureDatabase: () => ensureDatabase,
|
|
16553
|
+
generateCommandUid: () => generateCommandUid,
|
|
16439
16554
|
getAllSessions: () => getAllSessions,
|
|
16440
16555
|
getDb: () => getDb,
|
|
16441
16556
|
getEventsForSession: () => getEventsForSession,
|
|
@@ -16446,20 +16561,22 @@ __export(db_exports, {
|
|
|
16446
16561
|
insertSession: () => insertSession,
|
|
16447
16562
|
locateWasm: () => locateWasm,
|
|
16448
16563
|
openDatabase: () => openDatabase,
|
|
16564
|
+
readCommandLog: () => readCommandLog,
|
|
16565
|
+
replayCommandLog: () => replayCommandLog,
|
|
16449
16566
|
resultToRow: () => resultToRow,
|
|
16450
16567
|
resultToRows: () => resultToRows,
|
|
16451
16568
|
runMigrations: () => runMigrations,
|
|
16452
16569
|
saveDatabase: () => saveDatabase,
|
|
16453
16570
|
updateSession: () => updateSession
|
|
16454
16571
|
});
|
|
16455
|
-
import { existsSync as
|
|
16456
|
-
import { dirname as
|
|
16572
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync4, readFileSync as readFileSync9, renameSync as renameSync2, writeFileSync as writeFileSync7 } from "node:fs";
|
|
16573
|
+
import { dirname as dirname5, join as join12 } from "node:path";
|
|
16457
16574
|
import { createRequire as createRequire2 } from "node:module";
|
|
16458
16575
|
import initSqlJs from "sql.js";
|
|
16459
16576
|
function locateWasm() {
|
|
16460
16577
|
const require3 = createRequire2(import.meta.url);
|
|
16461
16578
|
const sqlJsPath = require3.resolve("sql.js");
|
|
16462
|
-
return
|
|
16579
|
+
return join12(dirname5(sqlJsPath), "sql-wasm.wasm");
|
|
16463
16580
|
}
|
|
16464
16581
|
function applyPragmas(db) {
|
|
16465
16582
|
db.run("PRAGMA foreign_keys = ON;");
|
|
@@ -16471,7 +16588,7 @@ async function openDatabase(dbPath) {
|
|
|
16471
16588
|
if (cached) {
|
|
16472
16589
|
return cached;
|
|
16473
16590
|
}
|
|
16474
|
-
const wasmBuffer =
|
|
16591
|
+
const wasmBuffer = readFileSync9(locateWasm());
|
|
16475
16592
|
const wasmBinary = wasmBuffer.buffer.slice(
|
|
16476
16593
|
wasmBuffer.byteOffset,
|
|
16477
16594
|
wasmBuffer.byteOffset + wasmBuffer.byteLength
|
|
@@ -16480,8 +16597,8 @@ async function openDatabase(dbPath) {
|
|
|
16480
16597
|
wasmBinary
|
|
16481
16598
|
});
|
|
16482
16599
|
let db;
|
|
16483
|
-
if (
|
|
16484
|
-
const fileBuffer =
|
|
16600
|
+
if (existsSync10(dbPath)) {
|
|
16601
|
+
const fileBuffer = readFileSync9(dbPath);
|
|
16485
16602
|
db = new SQL.Database(fileBuffer);
|
|
16486
16603
|
} else {
|
|
16487
16604
|
db = new SQL.Database();
|
|
@@ -16492,24 +16609,24 @@ async function openDatabase(dbPath) {
|
|
|
16492
16609
|
}
|
|
16493
16610
|
function saveDatabase(db, dbPath) {
|
|
16494
16611
|
const data = db.export();
|
|
16495
|
-
const dir =
|
|
16496
|
-
if (!
|
|
16497
|
-
|
|
16612
|
+
const dir = dirname5(dbPath);
|
|
16613
|
+
if (!existsSync10(dir)) {
|
|
16614
|
+
mkdirSync4(dir, { recursive: true });
|
|
16498
16615
|
}
|
|
16499
|
-
const tmpPath = dbPath
|
|
16500
|
-
|
|
16501
|
-
|
|
16616
|
+
const tmpPath = `${dbPath}.${process.pid}.tmp`;
|
|
16617
|
+
writeFileSync7(tmpPath, Buffer.from(data));
|
|
16618
|
+
renameSync2(tmpPath, dbPath);
|
|
16502
16619
|
}
|
|
16503
16620
|
async function getDb(ocrDir) {
|
|
16504
|
-
const dbPath =
|
|
16621
|
+
const dbPath = join12(ocrDir, "data", "ocr.db");
|
|
16505
16622
|
return openDatabase(dbPath);
|
|
16506
16623
|
}
|
|
16507
16624
|
async function ensureDatabase(ocrDir) {
|
|
16508
|
-
const dataDir =
|
|
16509
|
-
if (!
|
|
16510
|
-
|
|
16625
|
+
const dataDir = join12(ocrDir, "data");
|
|
16626
|
+
if (!existsSync10(dataDir)) {
|
|
16627
|
+
mkdirSync4(dataDir, { recursive: true });
|
|
16511
16628
|
}
|
|
16512
|
-
const dbPath =
|
|
16629
|
+
const dbPath = join12(dataDir, "ocr.db");
|
|
16513
16630
|
const db = await openDatabase(dbPath);
|
|
16514
16631
|
runMigrations(db);
|
|
16515
16632
|
saveDatabase(db, dbPath);
|
|
@@ -16536,6 +16653,7 @@ var init_db = __esm({
|
|
|
16536
16653
|
init_queries();
|
|
16537
16654
|
init_migrations();
|
|
16538
16655
|
init_result_mapper();
|
|
16656
|
+
init_command_log();
|
|
16539
16657
|
connections = /* @__PURE__ */ new Map();
|
|
16540
16658
|
}
|
|
16541
16659
|
});
|
|
@@ -20776,7 +20894,7 @@ ${hint}
|
|
|
20776
20894
|
}
|
|
20777
20895
|
|
|
20778
20896
|
// src/lib/version.ts
|
|
20779
|
-
var CLI_VERSION = true ? "1.
|
|
20897
|
+
var CLI_VERSION = true ? "1.10.0" : createRequire(import.meta.url)("../../package.json").version;
|
|
20780
20898
|
|
|
20781
20899
|
// src/lib/deps.ts
|
|
20782
20900
|
import { execFileSync } from "node:child_process";
|
|
@@ -21816,9 +21934,9 @@ var NodeFsHandler = class {
|
|
|
21816
21934
|
if (this.fsw.closed) {
|
|
21817
21935
|
return;
|
|
21818
21936
|
}
|
|
21819
|
-
const
|
|
21937
|
+
const dirname7 = sysPath.dirname(file);
|
|
21820
21938
|
const basename8 = sysPath.basename(file);
|
|
21821
|
-
const parent = this.fsw._getWatchedDir(
|
|
21939
|
+
const parent = this.fsw._getWatchedDir(dirname7);
|
|
21822
21940
|
let prevStats = stats;
|
|
21823
21941
|
if (parent.has(basename8))
|
|
21824
21942
|
return;
|
|
@@ -21845,7 +21963,7 @@ var NodeFsHandler = class {
|
|
|
21845
21963
|
prevStats = newStats2;
|
|
21846
21964
|
}
|
|
21847
21965
|
} catch (error) {
|
|
21848
|
-
this.fsw._remove(
|
|
21966
|
+
this.fsw._remove(dirname7, basename8);
|
|
21849
21967
|
}
|
|
21850
21968
|
} else if (parent.has(basename8)) {
|
|
21851
21969
|
const at = newStats.atimeMs;
|
|
@@ -22778,8 +22896,8 @@ function watch(paths, options = {}) {
|
|
|
22778
22896
|
}
|
|
22779
22897
|
|
|
22780
22898
|
// src/commands/progress.ts
|
|
22781
|
-
import { existsSync as
|
|
22782
|
-
import { join as
|
|
22899
|
+
import { existsSync as existsSync11, readdirSync as readdirSync5, statSync } from "node:fs";
|
|
22900
|
+
import { join as join13, basename as basename7 } from "node:path";
|
|
22783
22901
|
|
|
22784
22902
|
// ../../node_modules/.pnpm/log-update@7.0.2/node_modules/log-update/index.js
|
|
22785
22903
|
import process12 from "node:process";
|
|
@@ -24415,15 +24533,15 @@ function debounce(fn, delay) {
|
|
|
24415
24533
|
};
|
|
24416
24534
|
}
|
|
24417
24535
|
function findLatestActiveSession(sessionsDir) {
|
|
24418
|
-
if (!
|
|
24536
|
+
if (!existsSync11(sessionsDir)) {
|
|
24419
24537
|
return null;
|
|
24420
24538
|
}
|
|
24421
24539
|
const sessions = readdirSync5(sessionsDir).filter((name) => {
|
|
24422
|
-
const sessionPath =
|
|
24540
|
+
const sessionPath = join13(sessionsDir, name);
|
|
24423
24541
|
return statSync(sessionPath).isDirectory();
|
|
24424
24542
|
}).sort().reverse();
|
|
24425
24543
|
for (const session of sessions) {
|
|
24426
|
-
const sessionPath =
|
|
24544
|
+
const sessionPath = join13(sessionsDir, session);
|
|
24427
24545
|
if (isSessionActive(sessionPath)) {
|
|
24428
24546
|
return session;
|
|
24429
24547
|
}
|
|
@@ -24438,8 +24556,8 @@ function getStrategyForSession(sessionPath, explicitWorkflow) {
|
|
|
24438
24556
|
return getStrategy(workflowType) ?? null;
|
|
24439
24557
|
}
|
|
24440
24558
|
async function initProgressDb(ocrDir) {
|
|
24441
|
-
const dbPath =
|
|
24442
|
-
if (!
|
|
24559
|
+
const dbPath = join13(ocrDir, "data", "ocr.db");
|
|
24560
|
+
if (!existsSync11(dbPath)) {
|
|
24443
24561
|
return;
|
|
24444
24562
|
}
|
|
24445
24563
|
try {
|
|
@@ -24464,11 +24582,11 @@ var progressCommand = new Command("progress").description("Watch real-time progr
|
|
|
24464
24582
|
const targetDir = process.cwd();
|
|
24465
24583
|
requireOcrSetup(targetDir);
|
|
24466
24584
|
const sessionsDir = ensureSessionsDir(targetDir);
|
|
24467
|
-
const ocrDir =
|
|
24585
|
+
const ocrDir = join13(targetDir, ".ocr");
|
|
24468
24586
|
await initProgressDb(ocrDir);
|
|
24469
24587
|
if (options.session) {
|
|
24470
|
-
const sessionPath =
|
|
24471
|
-
if (!
|
|
24588
|
+
const sessionPath = join13(sessionsDir, options.session);
|
|
24589
|
+
if (!existsSync11(sessionPath)) {
|
|
24472
24590
|
console.error(source_default.red(`Session not found: ${options.session}`));
|
|
24473
24591
|
process.exit(1);
|
|
24474
24592
|
}
|
|
@@ -24529,7 +24647,7 @@ var progressCommand = new Command("progress").description("Watch real-time progr
|
|
|
24529
24647
|
return;
|
|
24530
24648
|
}
|
|
24531
24649
|
let currentSession = findLatestActiveSession(sessionsDir);
|
|
24532
|
-
let currentSessionPath = currentSession ?
|
|
24650
|
+
let currentSessionPath = currentSession ? join13(sessionsDir, currentSession) : null;
|
|
24533
24651
|
let sessionWatcher = null;
|
|
24534
24652
|
const preservedStartTimes = {
|
|
24535
24653
|
review: void 0,
|
|
@@ -24537,11 +24655,11 @@ var progressCommand = new Command("progress").description("Watch real-time progr
|
|
|
24537
24655
|
};
|
|
24538
24656
|
let currentStrategy = null;
|
|
24539
24657
|
const updateDisplayImpl = () => {
|
|
24540
|
-
if (!currentSessionPath || !
|
|
24658
|
+
if (!currentSessionPath || !existsSync11(currentSessionPath) || !isSessionActive(currentSessionPath)) {
|
|
24541
24659
|
const latestActive = findLatestActiveSession(sessionsDir);
|
|
24542
24660
|
if (latestActive && latestActive !== currentSession) {
|
|
24543
24661
|
currentSession = latestActive;
|
|
24544
|
-
currentSessionPath =
|
|
24662
|
+
currentSessionPath = join13(sessionsDir, latestActive);
|
|
24545
24663
|
preservedStartTimes.review = void 0;
|
|
24546
24664
|
preservedStartTimes.map = void 0;
|
|
24547
24665
|
currentStrategy = null;
|
|
@@ -24554,7 +24672,7 @@ var progressCommand = new Command("progress").description("Watch real-time progr
|
|
|
24554
24672
|
currentStrategy = null;
|
|
24555
24673
|
}
|
|
24556
24674
|
}
|
|
24557
|
-
if (currentSessionPath &&
|
|
24675
|
+
if (currentSessionPath && existsSync11(currentSessionPath)) {
|
|
24558
24676
|
if (!options.workflow) {
|
|
24559
24677
|
const activeWorkflows = detectActiveWorkflows(currentSessionPath);
|
|
24560
24678
|
if (activeWorkflows.length > 1) {
|
|
@@ -24608,15 +24726,15 @@ var progressCommand = new Command("progress").description("Watch real-time progr
|
|
|
24608
24726
|
watchSession(currentSessionPath);
|
|
24609
24727
|
}
|
|
24610
24728
|
const timerInterval = setInterval(updateDisplay, 1e3);
|
|
24611
|
-
const watchDir =
|
|
24729
|
+
const watchDir = existsSync11(ocrDir) ? ocrDir : targetDir;
|
|
24612
24730
|
const dirWatcher = watch(watchDir, {
|
|
24613
24731
|
persistent: true,
|
|
24614
24732
|
ignoreInitial: true,
|
|
24615
24733
|
depth: 3
|
|
24616
24734
|
});
|
|
24617
24735
|
dirWatcher.on("addDir", (dirPath) => {
|
|
24618
|
-
const parentDir =
|
|
24619
|
-
const isDirectChild = parentDir.endsWith("sessions") || parentDir.endsWith(
|
|
24736
|
+
const parentDir = join13(dirPath, "..");
|
|
24737
|
+
const isDirectChild = parentDir.endsWith("sessions") || parentDir.endsWith(join13(".ocr", "sessions"));
|
|
24620
24738
|
if (isDirectChild && !dirPath.endsWith("sessions")) {
|
|
24621
24739
|
const newSession = basename7(dirPath);
|
|
24622
24740
|
currentSession = newSession;
|
|
@@ -24718,34 +24836,34 @@ function renderCombinedProgress(sessionPath, preservedStartTimes, ocrDir) {
|
|
|
24718
24836
|
}
|
|
24719
24837
|
|
|
24720
24838
|
// src/commands/state.ts
|
|
24721
|
-
import { existsSync as
|
|
24722
|
-
import { join as
|
|
24839
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync6 } from "node:fs";
|
|
24840
|
+
import { join as join15 } from "node:path";
|
|
24723
24841
|
|
|
24724
24842
|
// src/lib/state/index.ts
|
|
24725
24843
|
init_db();
|
|
24726
24844
|
import {
|
|
24727
|
-
existsSync as
|
|
24728
|
-
mkdirSync as
|
|
24845
|
+
existsSync as existsSync12,
|
|
24846
|
+
mkdirSync as mkdirSync5,
|
|
24729
24847
|
readdirSync as readdirSync6,
|
|
24730
|
-
readFileSync as
|
|
24848
|
+
readFileSync as readFileSync10,
|
|
24731
24849
|
statSync as statSync2,
|
|
24732
|
-
writeFileSync as
|
|
24850
|
+
writeFileSync as writeFileSync8
|
|
24733
24851
|
} from "node:fs";
|
|
24734
|
-
import { join as
|
|
24852
|
+
import { join as join14 } from "node:path";
|
|
24735
24853
|
async function stateInit(params) {
|
|
24736
24854
|
const { sessionId, branch, workflowType, sessionDir, ocrDir } = params;
|
|
24737
24855
|
const db = await ensureDatabase(ocrDir);
|
|
24738
|
-
const dbPath =
|
|
24856
|
+
const dbPath = join14(ocrDir, "data", "ocr.db");
|
|
24739
24857
|
const existing = getSession(db, sessionId);
|
|
24740
24858
|
if (existing) {
|
|
24741
|
-
const roundsDir =
|
|
24859
|
+
const roundsDir = join14(sessionDir, "rounds");
|
|
24742
24860
|
let nextRound = 1;
|
|
24743
|
-
if (
|
|
24861
|
+
if (existsSync12(roundsDir)) {
|
|
24744
24862
|
const roundDirs = readdirSync6(roundsDir).filter((d) => /^round-\d+$/.test(d)).map((d) => parseInt(d.replace("round-", ""), 10)).sort((a, b) => a - b);
|
|
24745
24863
|
if (roundDirs.length > 0) {
|
|
24746
24864
|
const highest = roundDirs[roundDirs.length - 1];
|
|
24747
|
-
const hasFinal =
|
|
24748
|
-
|
|
24865
|
+
const hasFinal = existsSync12(
|
|
24866
|
+
join14(roundsDir, `round-${highest}`, "final.md")
|
|
24749
24867
|
);
|
|
24750
24868
|
nextRound = hasFinal ? highest + 1 : highest;
|
|
24751
24869
|
}
|
|
@@ -24789,7 +24907,7 @@ async function stateInit(params) {
|
|
|
24789
24907
|
async function stateTransition(params) {
|
|
24790
24908
|
const { sessionId, phase, phaseNumber, round, mapRun, ocrDir } = params;
|
|
24791
24909
|
const db = await ensureDatabase(ocrDir);
|
|
24792
|
-
const dbPath =
|
|
24910
|
+
const dbPath = join14(ocrDir, "data", "ocr.db");
|
|
24793
24911
|
const existing = getSession(db, sessionId);
|
|
24794
24912
|
if (!existing) {
|
|
24795
24913
|
throw new Error(`Session not found: ${sessionId}`);
|
|
@@ -24822,7 +24940,7 @@ async function stateTransition(params) {
|
|
|
24822
24940
|
async function stateClose(params) {
|
|
24823
24941
|
const { sessionId, ocrDir } = params;
|
|
24824
24942
|
const db = await ensureDatabase(ocrDir);
|
|
24825
|
-
const dbPath =
|
|
24943
|
+
const dbPath = join14(ocrDir, "data", "ocr.db");
|
|
24826
24944
|
const existing = getSession(db, sessionId);
|
|
24827
24945
|
if (!existing) {
|
|
24828
24946
|
throw new Error(`Session not found: ${sessionId}`);
|
|
@@ -24889,10 +25007,10 @@ async function resolveActiveSession(ocrDir) {
|
|
|
24889
25007
|
}
|
|
24890
25008
|
function readJsonFromSource(params) {
|
|
24891
25009
|
if (params.source === "file") {
|
|
24892
|
-
if (!
|
|
25010
|
+
if (!existsSync12(params.filePath)) {
|
|
24893
25011
|
throw new Error(`File not found: ${params.filePath}`);
|
|
24894
25012
|
}
|
|
24895
|
-
return
|
|
25013
|
+
return readFileSync10(params.filePath, "utf-8");
|
|
24896
25014
|
}
|
|
24897
25015
|
return params.data;
|
|
24898
25016
|
}
|
|
@@ -25026,7 +25144,7 @@ function computeRoundCounts(meta) {
|
|
|
25026
25144
|
async function stateRoundComplete(params) {
|
|
25027
25145
|
const { ocrDir } = params;
|
|
25028
25146
|
const db = await ensureDatabase(ocrDir);
|
|
25029
|
-
const dbPath =
|
|
25147
|
+
const dbPath = join14(ocrDir, "data", "ocr.db");
|
|
25030
25148
|
const rawJsonString = readJsonFromSource(params);
|
|
25031
25149
|
const label = params.source === "file" ? params.filePath : "stdin";
|
|
25032
25150
|
const raw = parseRawJson(rawJsonString, label);
|
|
@@ -25036,10 +25154,10 @@ async function stateRoundComplete(params) {
|
|
|
25036
25154
|
const roundNumber = params.round ?? session.current_round;
|
|
25037
25155
|
let metaPath;
|
|
25038
25156
|
if (params.source === "stdin") {
|
|
25039
|
-
const roundDir =
|
|
25040
|
-
|
|
25041
|
-
metaPath =
|
|
25042
|
-
|
|
25157
|
+
const roundDir = join14(session.session_dir, "rounds", `round-${roundNumber}`);
|
|
25158
|
+
mkdirSync5(roundDir, { recursive: true });
|
|
25159
|
+
metaPath = join14(roundDir, "round-meta.json");
|
|
25160
|
+
writeFileSync8(metaPath, JSON.stringify(meta, null, 2));
|
|
25043
25161
|
}
|
|
25044
25162
|
insertEvent(db, {
|
|
25045
25163
|
session_id: session.id,
|
|
@@ -25120,7 +25238,7 @@ function computeMapCounts(meta) {
|
|
|
25120
25238
|
async function stateMapComplete(params) {
|
|
25121
25239
|
const { ocrDir } = params;
|
|
25122
25240
|
const db = await ensureDatabase(ocrDir);
|
|
25123
|
-
const dbPath =
|
|
25241
|
+
const dbPath = join14(ocrDir, "data", "ocr.db");
|
|
25124
25242
|
const rawJsonString = readJsonFromSource(params);
|
|
25125
25243
|
const label = params.source === "file" ? params.filePath : "stdin";
|
|
25126
25244
|
const raw = parseRawJson(rawJsonString, label);
|
|
@@ -25130,10 +25248,10 @@ async function stateMapComplete(params) {
|
|
|
25130
25248
|
const mapRunNumber = params.mapRun ?? session.current_map_run;
|
|
25131
25249
|
let metaPath;
|
|
25132
25250
|
if (params.source === "stdin") {
|
|
25133
|
-
const runDir =
|
|
25134
|
-
|
|
25135
|
-
metaPath =
|
|
25136
|
-
|
|
25251
|
+
const runDir = join14(session.session_dir, "map", "runs", `run-${mapRunNumber}`);
|
|
25252
|
+
mkdirSync5(runDir, { recursive: true });
|
|
25253
|
+
metaPath = join14(runDir, "map-meta.json");
|
|
25254
|
+
writeFileSync8(metaPath, JSON.stringify(meta, null, 2));
|
|
25137
25255
|
}
|
|
25138
25256
|
insertEvent(db, {
|
|
25139
25257
|
session_id: session.id,
|
|
@@ -25152,24 +25270,24 @@ async function stateMapComplete(params) {
|
|
|
25152
25270
|
}
|
|
25153
25271
|
async function stateSync(ocrDir) {
|
|
25154
25272
|
const db = await ensureDatabase(ocrDir);
|
|
25155
|
-
const dbPath =
|
|
25156
|
-
const sessionsRoot =
|
|
25157
|
-
if (!
|
|
25273
|
+
const dbPath = join14(ocrDir, "data", "ocr.db");
|
|
25274
|
+
const sessionsRoot = join14(ocrDir, "sessions");
|
|
25275
|
+
if (!existsSync12(sessionsRoot)) {
|
|
25158
25276
|
return 0;
|
|
25159
25277
|
}
|
|
25160
25278
|
const entries = readdirSync6(sessionsRoot).filter((name) => {
|
|
25161
|
-
const fullPath =
|
|
25279
|
+
const fullPath = join14(sessionsRoot, name);
|
|
25162
25280
|
return statSync2(fullPath).isDirectory();
|
|
25163
25281
|
});
|
|
25164
25282
|
let synced = 0;
|
|
25165
25283
|
for (const dirName of entries) {
|
|
25166
|
-
const dirPath =
|
|
25284
|
+
const dirPath = join14(sessionsRoot, dirName);
|
|
25167
25285
|
const existing = getSession(db, dirName);
|
|
25168
25286
|
if (existing) {
|
|
25169
25287
|
continue;
|
|
25170
25288
|
}
|
|
25171
|
-
const hasRoundsDir =
|
|
25172
|
-
const hasMapDir =
|
|
25289
|
+
const hasRoundsDir = existsSync12(join14(dirPath, "rounds"));
|
|
25290
|
+
const hasMapDir = existsSync12(join14(dirPath, "map"));
|
|
25173
25291
|
const workflowType = hasMapDir && !hasRoundsDir ? "map" : "review";
|
|
25174
25292
|
const branchMatch = dirName.match(/^\d{4}-\d{2}-\d{2}-(.+)$/);
|
|
25175
25293
|
const branch = branchMatch?.[1] ?? dirName;
|
|
@@ -25199,6 +25317,8 @@ async function stateSync(ocrDir) {
|
|
|
25199
25317
|
}
|
|
25200
25318
|
|
|
25201
25319
|
// src/commands/state.ts
|
|
25320
|
+
init_command_log();
|
|
25321
|
+
init_db();
|
|
25202
25322
|
async function readStdin() {
|
|
25203
25323
|
const chunks = [];
|
|
25204
25324
|
for await (const chunk of process.stdin) {
|
|
@@ -25225,10 +25345,10 @@ var initSubcommand = new Command("init").description("Initialize a new OCR sessi
|
|
|
25225
25345
|
async (options) => {
|
|
25226
25346
|
const targetDir = process.cwd();
|
|
25227
25347
|
requireOcrSetup(targetDir);
|
|
25228
|
-
const ocrDir =
|
|
25229
|
-
const sessionDir = options.sessionDir ??
|
|
25230
|
-
if (!
|
|
25231
|
-
|
|
25348
|
+
const ocrDir = join15(targetDir, ".ocr");
|
|
25349
|
+
const sessionDir = options.sessionDir ?? join15(ocrDir, "sessions", options.sessionId);
|
|
25350
|
+
if (!existsSync13(sessionDir)) {
|
|
25351
|
+
mkdirSync6(sessionDir, { recursive: true });
|
|
25232
25352
|
}
|
|
25233
25353
|
try {
|
|
25234
25354
|
const sessionId = await stateInit({
|
|
@@ -25253,7 +25373,7 @@ var transitionSubcommand = new Command("transition").description("Transition ses
|
|
|
25253
25373
|
async (options) => {
|
|
25254
25374
|
const targetDir = process.cwd();
|
|
25255
25375
|
requireOcrSetup(targetDir);
|
|
25256
|
-
const ocrDir =
|
|
25376
|
+
const ocrDir = join15(targetDir, ".ocr");
|
|
25257
25377
|
const VALID_PHASES = /* @__PURE__ */ new Set([
|
|
25258
25378
|
"context",
|
|
25259
25379
|
"change-context",
|
|
@@ -25297,7 +25417,7 @@ var transitionSubcommand = new Command("transition").description("Transition ses
|
|
|
25297
25417
|
var closeSubcommand = new Command("close").description("Close a session").option("--session-id <id>", "Session ID (auto-detects latest active if omitted)").action(async (options) => {
|
|
25298
25418
|
const targetDir = process.cwd();
|
|
25299
25419
|
requireOcrSetup(targetDir);
|
|
25300
|
-
const ocrDir =
|
|
25420
|
+
const ocrDir = join15(targetDir, ".ocr");
|
|
25301
25421
|
try {
|
|
25302
25422
|
const sessionId = options.sessionId ?? (await resolveActiveSession(ocrDir)).id;
|
|
25303
25423
|
await stateClose({
|
|
@@ -25317,7 +25437,7 @@ var closeSubcommand = new Command("close").description("Close a session").option
|
|
|
25317
25437
|
var showSubcommand = new Command("show").description("Show current session state").option("--session-id <id>", "Session ID (defaults to latest active)").option("--json", "Output as JSON").action(async (options) => {
|
|
25318
25438
|
const targetDir = process.cwd();
|
|
25319
25439
|
requireOcrSetup(targetDir);
|
|
25320
|
-
const ocrDir =
|
|
25440
|
+
const ocrDir = join15(targetDir, ".ocr");
|
|
25321
25441
|
try {
|
|
25322
25442
|
const result = await stateShow(ocrDir, options.sessionId);
|
|
25323
25443
|
if (!result) {
|
|
@@ -25386,10 +25506,20 @@ var showSubcommand = new Command("show").description("Show current session state
|
|
|
25386
25506
|
var syncSubcommand = new Command("sync").description("Rebuild session state from filesystem artifacts").action(async () => {
|
|
25387
25507
|
const targetDir = process.cwd();
|
|
25388
25508
|
requireOcrSetup(targetDir);
|
|
25389
|
-
const ocrDir =
|
|
25509
|
+
const ocrDir = join15(targetDir, ".ocr");
|
|
25390
25510
|
try {
|
|
25391
25511
|
const synced = await stateSync(ocrDir);
|
|
25392
25512
|
console.log(`Synced ${synced} session${synced !== 1 ? "s" : ""} from filesystem.`);
|
|
25513
|
+
const db = await getDb(ocrDir);
|
|
25514
|
+
const countResult = db.exec("SELECT COUNT(*) as c FROM command_executions");
|
|
25515
|
+
const totalCmds = countResult[0]?.values[0]?.[0] ?? 0;
|
|
25516
|
+
if (totalCmds === 0) {
|
|
25517
|
+
const recovered = replayCommandLog(db, ocrDir);
|
|
25518
|
+
if (recovered > 0) {
|
|
25519
|
+
saveDatabase(db, join15(ocrDir, "data", "ocr.db"));
|
|
25520
|
+
console.log(`Recovered ${recovered} command${recovered !== 1 ? "s" : ""} from backup log.`);
|
|
25521
|
+
}
|
|
25522
|
+
}
|
|
25393
25523
|
} catch (error) {
|
|
25394
25524
|
console.error(
|
|
25395
25525
|
source_default.red(
|
|
@@ -25403,7 +25533,7 @@ var roundCompleteSubcommand = new Command("round-complete").description("Import
|
|
|
25403
25533
|
async (options) => {
|
|
25404
25534
|
const targetDir = process.cwd();
|
|
25405
25535
|
requireOcrSetup(targetDir);
|
|
25406
|
-
const ocrDir =
|
|
25536
|
+
const ocrDir = join15(targetDir, ".ocr");
|
|
25407
25537
|
if (!options.file && !options.stdin) {
|
|
25408
25538
|
console.error(source_default.red("Error: Provide either --file <path> or --stdin"));
|
|
25409
25539
|
process.exit(1);
|
|
@@ -25452,7 +25582,7 @@ var mapCompleteSubcommand = new Command("map-complete").description("Import stru
|
|
|
25452
25582
|
async (options) => {
|
|
25453
25583
|
const targetDir = process.cwd();
|
|
25454
25584
|
requireOcrSetup(targetDir);
|
|
25455
|
-
const ocrDir =
|
|
25585
|
+
const ocrDir = join15(targetDir, ".ocr");
|
|
25456
25586
|
if (!options.file && !options.stdin) {
|
|
25457
25587
|
console.error(source_default.red("Error: Provide either --file <path> or --stdin"));
|
|
25458
25588
|
process.exit(1);
|
|
@@ -25500,16 +25630,16 @@ var mapCompleteSubcommand = new Command("map-complete").description("Import stru
|
|
|
25500
25630
|
var stateCommand = new Command("state").description("Manage OCR session state").addCommand(initSubcommand).addCommand(transitionSubcommand).addCommand(closeSubcommand).addCommand(showSubcommand).addCommand(syncSubcommand).addCommand(roundCompleteSubcommand).addCommand(mapCompleteSubcommand);
|
|
25501
25631
|
|
|
25502
25632
|
// src/commands/update.ts
|
|
25503
|
-
import { existsSync as
|
|
25504
|
-
import { join as
|
|
25633
|
+
import { existsSync as existsSync14 } from "node:fs";
|
|
25634
|
+
import { join as join16 } from "node:path";
|
|
25505
25635
|
function detectConfiguredTools(targetDir) {
|
|
25506
25636
|
return AI_TOOLS.filter((tool) => {
|
|
25507
25637
|
if (tool.commandStrategy === "subdirectory") {
|
|
25508
|
-
const ocrDir =
|
|
25509
|
-
return
|
|
25638
|
+
const ocrDir = join16(targetDir, tool.commandsDir, "ocr");
|
|
25639
|
+
return existsSync14(ocrDir);
|
|
25510
25640
|
} else {
|
|
25511
|
-
const reviewCmd =
|
|
25512
|
-
return
|
|
25641
|
+
const reviewCmd = join16(targetDir, tool.commandsDir, "ocr-review.md");
|
|
25642
|
+
return existsSync14(reviewCmd);
|
|
25513
25643
|
}
|
|
25514
25644
|
});
|
|
25515
25645
|
}
|
|
@@ -25583,7 +25713,7 @@ var updateCommand = new Command("update").description("Update OCR assets after p
|
|
|
25583
25713
|
const result = installForTool(tool, targetDir);
|
|
25584
25714
|
results.push(result);
|
|
25585
25715
|
}
|
|
25586
|
-
ensureGitignore(
|
|
25716
|
+
ensureGitignore(join16(targetDir, ".ocr"));
|
|
25587
25717
|
spinner.stop();
|
|
25588
25718
|
const successful = results.filter((r) => r.success);
|
|
25589
25719
|
const failed = results.filter((r) => !r.success);
|
|
@@ -25619,10 +25749,10 @@ var updateCommand = new Command("update").description("Update OCR assets after p
|
|
|
25619
25749
|
if (updateInject) {
|
|
25620
25750
|
if (options.dryRun) {
|
|
25621
25751
|
console.log(source_default.dim(" Would update:"));
|
|
25622
|
-
if (
|
|
25752
|
+
if (existsSync14(join16(targetDir, "AGENTS.md"))) {
|
|
25623
25753
|
console.log(source_default.dim(" \u2022 AGENTS.md (OCR managed block)"));
|
|
25624
25754
|
}
|
|
25625
|
-
if (
|
|
25755
|
+
if (existsSync14(join16(targetDir, "CLAUDE.md"))) {
|
|
25626
25756
|
console.log(source_default.dim(" \u2022 CLAUDE.md (OCR managed block)"));
|
|
25627
25757
|
}
|
|
25628
25758
|
console.log();
|
|
@@ -25654,14 +25784,14 @@ var updateCommand = new Command("update").description("Update OCR assets after p
|
|
|
25654
25784
|
});
|
|
25655
25785
|
|
|
25656
25786
|
// src/commands/dashboard.ts
|
|
25657
|
-
import { existsSync as
|
|
25658
|
-
import { join as
|
|
25787
|
+
import { existsSync as existsSync15 } from "node:fs";
|
|
25788
|
+
import { join as join17, dirname as dirname6 } from "node:path";
|
|
25659
25789
|
import { fileURLToPath } from "node:url";
|
|
25660
25790
|
init_db();
|
|
25661
25791
|
var __filename = fileURLToPath(import.meta.url);
|
|
25662
|
-
var __dirname =
|
|
25792
|
+
var __dirname = dirname6(__filename);
|
|
25663
25793
|
function resolveServerPath() {
|
|
25664
|
-
return
|
|
25794
|
+
return join17(__dirname, "dashboard", "server.js");
|
|
25665
25795
|
}
|
|
25666
25796
|
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(
|
|
25667
25797
|
async (options) => {
|
|
@@ -25672,7 +25802,7 @@ var dashboardCommand = new Command("dashboard").description("Start the OCR dashb
|
|
|
25672
25802
|
console.error(source_default.red(`Error: Invalid port "${options.port}". Must be 1-65535.`));
|
|
25673
25803
|
process.exit(1);
|
|
25674
25804
|
}
|
|
25675
|
-
const ocrDir =
|
|
25805
|
+
const ocrDir = join17(targetDir, ".ocr");
|
|
25676
25806
|
try {
|
|
25677
25807
|
await ensureDatabase(ocrDir);
|
|
25678
25808
|
closeAllDatabases();
|
|
@@ -25686,7 +25816,7 @@ var dashboardCommand = new Command("dashboard").description("Start the OCR dashb
|
|
|
25686
25816
|
process.exit(1);
|
|
25687
25817
|
}
|
|
25688
25818
|
const serverPath = resolveServerPath();
|
|
25689
|
-
if (!
|
|
25819
|
+
if (!existsSync15(serverPath)) {
|
|
25690
25820
|
console.error(source_default.red("Error: Dashboard server bundle not found."));
|
|
25691
25821
|
console.error(
|
|
25692
25822
|
source_default.dim(` Expected at: ${serverPath}`)
|
|
@@ -25720,8 +25850,8 @@ var dashboardCommand = new Command("dashboard").description("Start the OCR dashb
|
|
|
25720
25850
|
);
|
|
25721
25851
|
|
|
25722
25852
|
// src/commands/doctor.ts
|
|
25723
|
-
import { existsSync as
|
|
25724
|
-
import { join as
|
|
25853
|
+
import { existsSync as existsSync16 } from "node:fs";
|
|
25854
|
+
import { join as join18 } from "node:path";
|
|
25725
25855
|
var doctorCommand = new Command("doctor").description("Check OCR installation and verify all dependencies").action(() => {
|
|
25726
25856
|
printHeader();
|
|
25727
25857
|
const targetDir = process.cwd();
|
|
@@ -25735,10 +25865,10 @@ var doctorCommand = new Command("doctor").description("Check OCR installation an
|
|
|
25735
25865
|
console.log(source_default.bold(" OCR Installation"));
|
|
25736
25866
|
console.log();
|
|
25737
25867
|
const ocrStatus = checkOcrSetup(targetDir);
|
|
25738
|
-
const configPath =
|
|
25739
|
-
const dbPath =
|
|
25740
|
-
const hasConfig =
|
|
25741
|
-
const hasDb =
|
|
25868
|
+
const configPath = join18(targetDir, ".ocr", "config.yaml");
|
|
25869
|
+
const dbPath = join18(targetDir, ".ocr", "data", "ocr.db");
|
|
25870
|
+
const hasConfig = existsSync16(configPath);
|
|
25871
|
+
const hasDb = existsSync16(dbPath);
|
|
25742
25872
|
const ocrChecks = [
|
|
25743
25873
|
{ label: ".ocr/skills/", ok: ocrStatus.hasSkills },
|
|
25744
25874
|
{ label: ".ocr/sessions/", ok: ocrStatus.hasSessions },
|
|
@@ -25812,8 +25942,8 @@ var doctorCommand = new Command("doctor").description("Check OCR installation an
|
|
|
25812
25942
|
});
|
|
25813
25943
|
|
|
25814
25944
|
// src/commands/reviewers.ts
|
|
25815
|
-
import { writeFileSync as
|
|
25816
|
-
import { join as
|
|
25945
|
+
import { writeFileSync as writeFileSync9, renameSync as renameSync3 } from "node:fs";
|
|
25946
|
+
import { join as join19 } from "node:path";
|
|
25817
25947
|
async function readStdin2() {
|
|
25818
25948
|
const chunks = [];
|
|
25819
25949
|
for await (const chunk of process.stdin) {
|
|
@@ -25876,20 +26006,20 @@ function validateReviewersMeta(data) {
|
|
|
25876
26006
|
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) => {
|
|
25877
26007
|
const targetDir = process.cwd();
|
|
25878
26008
|
requireOcrSetup(targetDir);
|
|
25879
|
-
const ocrDir =
|
|
26009
|
+
const ocrDir = join19(targetDir, ".ocr");
|
|
25880
26010
|
if (!options.stdin) {
|
|
25881
26011
|
try {
|
|
25882
|
-
const reviewersDir =
|
|
25883
|
-
const configPath =
|
|
26012
|
+
const reviewersDir = join19(ocrDir, "skills", "references", "reviewers");
|
|
26013
|
+
const configPath = join19(ocrDir, "config.yaml");
|
|
25884
26014
|
const meta = generateReviewersMeta(reviewersDir, configPath);
|
|
25885
26015
|
if (!meta || meta.reviewers.length === 0) {
|
|
25886
26016
|
console.error(source_default.yellow("No reviewer files found in .ocr/skills/references/reviewers/"));
|
|
25887
26017
|
process.exit(1);
|
|
25888
26018
|
}
|
|
25889
|
-
const metaPath =
|
|
26019
|
+
const metaPath = join19(ocrDir, "reviewers-meta.json");
|
|
25890
26020
|
const tmpPath = metaPath + ".tmp";
|
|
25891
|
-
|
|
25892
|
-
|
|
26021
|
+
writeFileSync9(tmpPath, JSON.stringify(meta, null, 2) + "\n");
|
|
26022
|
+
renameSync3(tmpPath, metaPath);
|
|
25893
26023
|
const tierCounts = meta.reviewers.reduce(
|
|
25894
26024
|
(acc, r) => {
|
|
25895
26025
|
acc[r.tier] = (acc[r.tier] ?? 0) + 1;
|
|
@@ -25916,10 +26046,10 @@ var syncSubcommand2 = new Command("sync").description("Sync reviewers-meta.json
|
|
|
25916
26046
|
throw new Error("Invalid JSON on stdin");
|
|
25917
26047
|
}
|
|
25918
26048
|
const meta = validateReviewersMeta(parsed);
|
|
25919
|
-
const metaPath =
|
|
26049
|
+
const metaPath = join19(ocrDir, "reviewers-meta.json");
|
|
25920
26050
|
const tmpPath = metaPath + ".tmp";
|
|
25921
|
-
|
|
25922
|
-
|
|
26051
|
+
writeFileSync9(tmpPath, JSON.stringify(meta, null, 2) + "\n");
|
|
26052
|
+
renameSync3(tmpPath, metaPath);
|
|
25923
26053
|
const tierCounts = meta.reviewers.reduce(
|
|
25924
26054
|
(acc, r) => {
|
|
25925
26055
|
acc[r.tier] = (acc[r.tier] ?? 0) + 1;
|
|
@@ -25944,25 +26074,25 @@ var reviewersCommand = new Command("reviewers").description("Manage OCR reviewer
|
|
|
25944
26074
|
|
|
25945
26075
|
// src/lib/update-check.ts
|
|
25946
26076
|
import { homedir } from "node:os";
|
|
25947
|
-
import { join as
|
|
25948
|
-
import { readFileSync as
|
|
26077
|
+
import { join as join20 } from "node:path";
|
|
26078
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync10, mkdirSync as mkdirSync7 } from "node:fs";
|
|
25949
26079
|
var PACKAGE_NAME = "@open-code-review/cli";
|
|
25950
26080
|
var REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
|
|
25951
|
-
var
|
|
25952
|
-
var CACHE_FILE =
|
|
26081
|
+
var CACHE_DIR2 = join20(homedir(), ".ocr");
|
|
26082
|
+
var CACHE_FILE = join20(CACHE_DIR2, "update-check.json");
|
|
25953
26083
|
var CHECK_INTERVAL_MS = 4 * 60 * 60 * 1e3;
|
|
25954
26084
|
var FETCH_TIMEOUT_MS = 3e3;
|
|
25955
26085
|
function readCache(cacheFile) {
|
|
25956
26086
|
try {
|
|
25957
|
-
return JSON.parse(
|
|
26087
|
+
return JSON.parse(readFileSync11(cacheFile, "utf-8"));
|
|
25958
26088
|
} catch {
|
|
25959
26089
|
return null;
|
|
25960
26090
|
}
|
|
25961
26091
|
}
|
|
25962
26092
|
function writeCache(cacheFile, cache) {
|
|
25963
26093
|
try {
|
|
25964
|
-
|
|
25965
|
-
|
|
26094
|
+
mkdirSync7(join20(cacheFile, ".."), { recursive: true });
|
|
26095
|
+
writeFileSync10(cacheFile, JSON.stringify(cache));
|
|
25966
26096
|
} catch {
|
|
25967
26097
|
}
|
|
25968
26098
|
}
|
|
@@ -25982,7 +26112,7 @@ async function checkForUpdate(currentVersion, options) {
|
|
|
25982
26112
|
if (process.env.CI || process.env.OCR_NO_UPDATE_CHECK) {
|
|
25983
26113
|
return null;
|
|
25984
26114
|
}
|
|
25985
|
-
const cacheFile =
|
|
26115
|
+
const cacheFile = join20(options?.cacheDir ?? CACHE_DIR2, "update-check.json");
|
|
25986
26116
|
try {
|
|
25987
26117
|
const cache = readCache(cacheFile);
|
|
25988
26118
|
if (cache && Date.now() - cache.lastCheck < CHECK_INTERVAL_MS) {
|