@unerr-ai/unerr 0.2.2 → 0.2.3

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 (3) hide show
  1. package/README.md +31 -46
  2. package/dist/cli.js +528 -550
  3. package/package.json +2 -1
package/dist/cli.js CHANGED
@@ -1803,6 +1803,163 @@ var init_git_review = __esm({
1803
1803
  }
1804
1804
  });
1805
1805
 
1806
+ // src/intelligence/local-snapshot.ts
1807
+ var local_snapshot_exports = {};
1808
+ __export(local_snapshot_exports, {
1809
+ getSnapshotMeta: () => getSnapshotMeta,
1810
+ loadLocalSnapshot: () => loadLocalSnapshot,
1811
+ persistLocalSnapshot: () => persistLocalSnapshot,
1812
+ shouldReindex: () => shouldReindex,
1813
+ snapshotPath: () => snapshotPath
1814
+ });
1815
+ import {
1816
+ existsSync as existsSync2,
1817
+ mkdirSync,
1818
+ readFileSync as readFileSync2,
1819
+ readdirSync as readdirSync2,
1820
+ statSync,
1821
+ writeFileSync
1822
+ } from "fs";
1823
+ import { join as join2 } from "path";
1824
+ function snapshotPath(projectRoot) {
1825
+ return join2(projectRoot, ".unerr", "snapshots", SNAPSHOT_FILENAME);
1826
+ }
1827
+ function getSnapshotMeta(projectRoot) {
1828
+ const path7 = snapshotPath(projectRoot);
1829
+ return { path: path7, exists: existsSync2(path7) };
1830
+ }
1831
+ function shouldReindex(projectRoot) {
1832
+ const dbPath = join2(projectRoot, ".unerr", "graph.db");
1833
+ const snPath = snapshotPath(projectRoot);
1834
+ let referenceMtime = null;
1835
+ if (existsSync2(dbPath)) {
1836
+ try {
1837
+ referenceMtime = statSync(dbPath).mtimeMs;
1838
+ } catch {
1839
+ }
1840
+ }
1841
+ if (referenceMtime === null && existsSync2(snPath)) {
1842
+ try {
1843
+ referenceMtime = statSync(snPath).mtimeMs;
1844
+ } catch {
1845
+ }
1846
+ }
1847
+ if (referenceMtime === null) return true;
1848
+ return hasNewerSource(projectRoot, referenceMtime);
1849
+ }
1850
+ async function persistLocalSnapshot(projectRoot, repoId, entities, edges) {
1851
+ const snapshotsDir = join2(projectRoot, ".unerr", "snapshots");
1852
+ mkdirSync(snapshotsDir, { recursive: true });
1853
+ const envelope = {
1854
+ version: 1,
1855
+ repoId,
1856
+ orgId: "local",
1857
+ entities,
1858
+ edges,
1859
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString()
1860
+ };
1861
+ const { pack } = await import("msgpackr");
1862
+ const { gzipSync: gzipSync3 } = await import("zlib");
1863
+ const packed = pack(envelope);
1864
+ const compressed = gzipSync3(packed);
1865
+ const path7 = snapshotPath(projectRoot);
1866
+ writeFileSync(path7, compressed);
1867
+ return path7;
1868
+ }
1869
+ async function loadLocalSnapshot(projectRoot, graphStore) {
1870
+ const path7 = snapshotPath(projectRoot);
1871
+ if (!existsSync2(path7)) return false;
1872
+ try {
1873
+ const { unpack } = await import("msgpackr");
1874
+ const { gunzipSync: gunzipSync2 } = await import("zlib");
1875
+ const raw = readFileSync2(path7);
1876
+ const buffer = gunzipSync2(raw);
1877
+ const envelope = unpack(buffer);
1878
+ await graphStore.loadSnapshot(envelope);
1879
+ return true;
1880
+ } catch {
1881
+ return false;
1882
+ }
1883
+ }
1884
+ function hasNewerSource(projectRoot, snapshotMtime) {
1885
+ return scanDirForNewer(projectRoot, snapshotMtime);
1886
+ }
1887
+ function scanDirForNewer(dir, threshold) {
1888
+ let entries;
1889
+ try {
1890
+ entries = readdirSync2(dir);
1891
+ } catch {
1892
+ return false;
1893
+ }
1894
+ for (const entry of entries) {
1895
+ if (EXCLUDED_DIRS.has(entry)) continue;
1896
+ if (entry.startsWith(".") && entry !== ".") continue;
1897
+ const fullPath = join2(dir, entry);
1898
+ let stat2;
1899
+ try {
1900
+ stat2 = statSync(fullPath);
1901
+ } catch {
1902
+ continue;
1903
+ }
1904
+ if (stat2.isDirectory()) {
1905
+ if (scanDirForNewer(fullPath, threshold)) return true;
1906
+ } else if (stat2.isFile()) {
1907
+ const ext = fullPath.slice(fullPath.lastIndexOf(".")).toLowerCase();
1908
+ if (SOURCE_EXTENSIONS.has(ext) && stat2.mtimeMs > threshold) {
1909
+ return true;
1910
+ }
1911
+ }
1912
+ }
1913
+ return false;
1914
+ }
1915
+ var SNAPSHOT_FILENAME, SOURCE_EXTENSIONS, EXCLUDED_DIRS;
1916
+ var init_local_snapshot = __esm({
1917
+ "src/intelligence/local-snapshot.ts"() {
1918
+ "use strict";
1919
+ SNAPSHOT_FILENAME = "graph.msgpack.gz";
1920
+ SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
1921
+ ".ts",
1922
+ ".tsx",
1923
+ ".js",
1924
+ ".jsx",
1925
+ ".mjs",
1926
+ ".cjs",
1927
+ ".py",
1928
+ ".go",
1929
+ ".java",
1930
+ ".rs",
1931
+ ".c",
1932
+ ".h",
1933
+ ".cpp",
1934
+ ".cc",
1935
+ ".cxx",
1936
+ ".hpp"
1937
+ ]);
1938
+ EXCLUDED_DIRS = /* @__PURE__ */ new Set([
1939
+ "node_modules",
1940
+ "dist",
1941
+ "build",
1942
+ "out",
1943
+ ".git",
1944
+ ".hg",
1945
+ ".svn",
1946
+ "coverage",
1947
+ "__pycache__",
1948
+ ".mypy_cache",
1949
+ ".pytest_cache",
1950
+ "vendor",
1951
+ "target",
1952
+ ".next",
1953
+ ".nuxt",
1954
+ ".output",
1955
+ ".unerr",
1956
+ ".cache",
1957
+ ".turbo",
1958
+ ".parcel-cache"
1959
+ ]);
1960
+ }
1961
+ });
1962
+
1806
1963
  // src/intelligence/indexer/test-detector.ts
1807
1964
  import { basename } from "path";
1808
1965
  function isTestFile(filePath) {
@@ -3050,8 +3207,8 @@ var local_graph_exports = {};
3050
3207
  __export(local_graph_exports, {
3051
3208
  CozoGraphStore: () => CozoGraphStore
3052
3209
  });
3053
- import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
3054
- import { join as join2 } from "path";
3210
+ import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
3211
+ import { join as join3 } from "path";
3055
3212
  function matchGlob(filePath, glob) {
3056
3213
  const regex = glob.replace(/\./g, "\\.").replace(/\*\*/g, "{{GLOBSTAR}}").replace(/\*/g, "[^/]*").replace(/\{\{GLOBSTAR\}\}/g, ".*");
3057
3214
  return new RegExp(`^${regex}$`).test(filePath);
@@ -3063,8 +3220,8 @@ var init_local_graph = __esm({
3063
3220
  init_community_detection();
3064
3221
  init_cozo_schema();
3065
3222
  init_search_index();
3066
- QUERY_TIMEOUT_MS = 2e3;
3067
- WRITE_TIMEOUT_MS = 1e4;
3223
+ QUERY_TIMEOUT_MS = 12e3;
3224
+ WRITE_TIMEOUT_MS = 6e4;
3068
3225
  CozoGraphStore = class _CozoGraphStore {
3069
3226
  db;
3070
3227
  loaded = false;
@@ -3123,10 +3280,10 @@ var init_local_graph = __esm({
3123
3280
  */
3124
3281
  static async create(db, projectRoot) {
3125
3282
  if (projectRoot) {
3126
- const pidPath2 = join2(projectRoot, ".unerr", "state", "proxy.pid");
3127
- if (existsSync2(pidPath2)) {
3283
+ const pidPath2 = join3(projectRoot, ".unerr", "state", "proxy.pid");
3284
+ if (existsSync3(pidPath2)) {
3128
3285
  try {
3129
- const raw = readFileSync2(pidPath2, "utf-8").trim();
3286
+ const raw = readFileSync3(pidPath2, "utf-8").trim();
3130
3287
  let ownerPid;
3131
3288
  if (raw.startsWith("{")) {
3132
3289
  const data = JSON.parse(raw);
@@ -5305,13 +5462,13 @@ var init_local_graph = __esm({
5305
5462
  });
5306
5463
 
5307
5464
  // src/intelligence/facts-schema.ts
5308
- import { existsSync as existsSync3, mkdirSync } from "fs";
5309
- import { join as join3 } from "path";
5465
+ import { existsSync as existsSync4, mkdirSync as mkdirSync2 } from "fs";
5466
+ import { join as join4 } from "path";
5310
5467
  async function openFactsDb(projectRoot) {
5311
- const unerrDir2 = join3(projectRoot, ".unerr");
5312
- mkdirSync(unerrDir2, { recursive: true });
5313
- const dbPath = join3(unerrDir2, FACTS_DB_FILENAME);
5314
- const isNew = !existsSync3(dbPath);
5468
+ const unerrDir2 = join4(projectRoot, ".unerr");
5469
+ mkdirSync2(unerrDir2, { recursive: true });
5470
+ const dbPath = join4(unerrDir2, FACTS_DB_FILENAME);
5471
+ const isNew = !existsSync4(dbPath);
5315
5472
  const cozoModule = await import("cozo-node");
5316
5473
  const CozoDbConstructor = cozoModule.default ? cozoModule.default.CozoDb : cozoModule.CozoDb;
5317
5474
  const db = new CozoDbConstructor("sqlite", dbPath);
@@ -6174,16 +6331,16 @@ var init_temporal_facts = __esm({
6174
6331
  });
6175
6332
 
6176
6333
  // src/intelligence/cochange-index.ts
6177
- import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync } from "fs";
6178
- import { dirname as dirname2, join as join4 } from "path";
6334
+ import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
6335
+ import { dirname as dirname2, join as join5 } from "path";
6179
6336
  function cochangeIndexPath(unerrDir2) {
6180
- return join4(unerrDir2, "state", "cochange-index.json");
6337
+ return join5(unerrDir2, "state", "cochange-index.json");
6181
6338
  }
6182
6339
  function readCoChangeIndex(unerrDir2) {
6183
6340
  const path7 = cochangeIndexPath(unerrDir2);
6184
- if (!existsSync4(path7)) return {};
6341
+ if (!existsSync5(path7)) return {};
6185
6342
  try {
6186
- const raw = readFileSync3(path7, "utf-8");
6343
+ const raw = readFileSync4(path7, "utf-8");
6187
6344
  const parsed = JSON.parse(raw);
6188
6345
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
6189
6346
  return parsed;
@@ -6198,7 +6355,7 @@ function recordCoChangeGroup(unerrDir2, anchors) {
6198
6355
  if (filePaths.length < 2) return;
6199
6356
  const path7 = cochangeIndexPath(unerrDir2);
6200
6357
  try {
6201
- mkdirSync2(dirname2(path7), { recursive: true });
6358
+ mkdirSync3(dirname2(path7), { recursive: true });
6202
6359
  } catch {
6203
6360
  }
6204
6361
  const index = readCoChangeIndex(unerrDir2);
@@ -6213,7 +6370,7 @@ function recordCoChangeGroup(unerrDir2, anchors) {
6213
6370
  index[file] = merged;
6214
6371
  }
6215
6372
  try {
6216
- writeFileSync(path7, JSON.stringify(index), "utf-8");
6373
+ writeFileSync2(path7, JSON.stringify(index), "utf-8");
6217
6374
  } catch {
6218
6375
  }
6219
6376
  }
@@ -6464,7 +6621,7 @@ __export(notes_store_exports, {
6464
6621
  NotesStore: () => NotesStore
6465
6622
  });
6466
6623
  import { createHash } from "crypto";
6467
- import { join as join5 } from "path";
6624
+ import { join as join6 } from "path";
6468
6625
  function rowToStoredNote(row) {
6469
6626
  return {
6470
6627
  note_id: row[0],
@@ -6501,7 +6658,7 @@ var init_notes_store = __esm({
6501
6658
  init_cochange_index();
6502
6659
  init_note_dsl();
6503
6660
  init_topic_shift();
6504
- UNERR_DIR_FOR_COCHANGE = join5(process.cwd(), ".unerr");
6661
+ UNERR_DIR_FOR_COCHANGE = join6(process.cwd(), ".unerr");
6505
6662
  SESSION_SAVE_CAP = 15;
6506
6663
  NotesStore = class {
6507
6664
  constructor(db) {
@@ -6870,8 +7027,8 @@ __export(git_attribution_exports, {
6870
7027
  writeGitNote: () => writeGitNote,
6871
7028
  writeReviewVerdictNote: () => writeReviewVerdictNote
6872
7029
  });
6873
- import { existsSync as existsSync6, readFileSync as readFileSync5 } from "fs";
6874
- import { join as join8 } from "path";
7030
+ import { existsSync as existsSync7, readFileSync as readFileSync6 } from "fs";
7031
+ import { join as join9 } from "path";
6875
7032
  async function writeReviewVerdictNote(cwd, commitSha, note2) {
6876
7033
  await writeNote(
6877
7034
  cwd,
@@ -6929,10 +7086,10 @@ async function writeGitNote(dir, _gitdir, commitSha, payload) {
6929
7086
  await writeNote(dir, "unerr", commitSha, noteContent);
6930
7087
  }
6931
7088
  function readAttributionFromManifest(cwd) {
6932
- const manifestPath = join8(cwd, ".unerr", "manifest.json");
6933
- if (!existsSync6(manifestPath)) return null;
7089
+ const manifestPath = join9(cwd, ".unerr", "manifest.json");
7090
+ if (!existsSync7(manifestPath)) return null;
6934
7091
  try {
6935
- const raw = readFileSync5(manifestPath, "utf-8");
7092
+ const raw = readFileSync6(manifestPath, "utf-8");
6936
7093
  const manifest = JSON.parse(raw);
6937
7094
  if (!manifest.sessionId || !manifest.attributions?.length) return null;
6938
7095
  const allEntryIds = [];
@@ -7485,18 +7642,18 @@ __export(mcp_config_writer_exports, {
7485
7642
  });
7486
7643
  import { execSync } from "child_process";
7487
7644
  import {
7488
- existsSync as existsSync9,
7489
- mkdirSync as mkdirSync5,
7490
- readFileSync as readFileSync8,
7645
+ existsSync as existsSync10,
7646
+ mkdirSync as mkdirSync6,
7647
+ readFileSync as readFileSync9,
7491
7648
  rmdirSync,
7492
7649
  unlinkSync,
7493
- writeFileSync as writeFileSync3
7650
+ writeFileSync as writeFileSync4
7494
7651
  } from "fs";
7495
7652
  import { homedir } from "os";
7496
- import { basename as basename2, dirname as dirname3, join as join11 } from "path";
7653
+ import { basename as basename2, dirname as dirname3, join as join12 } from "path";
7497
7654
  function resolveUnerrCommand() {
7498
7655
  const entryScript = process.argv[1];
7499
- if (entryScript && existsSync9(entryScript)) {
7656
+ if (entryScript && existsSync10(entryScript)) {
7500
7657
  const base = basename2(entryScript);
7501
7658
  if (base === "unerr" || base.startsWith("unerr.")) {
7502
7659
  return entryScript;
@@ -7509,7 +7666,7 @@ function resolveUnerrCommand() {
7509
7666
  timeout: 5e3,
7510
7667
  stdio: ["pipe", "pipe", "pipe"]
7511
7668
  }).trim().split(/\r?\n/)[0];
7512
- if (resolved && existsSync9(resolved)) {
7669
+ if (resolved && existsSync10(resolved)) {
7513
7670
  return resolved;
7514
7671
  }
7515
7672
  } catch {
@@ -7552,10 +7709,10 @@ function writeMcpConfig(cwd, ide) {
7552
7709
  if (!agent) {
7553
7710
  return { path: "", action: "skipped" };
7554
7711
  }
7555
- const configPath2 = agent.configScope === "global" ? join11(homedir(), agent.projectConfigPath) : join11(cwd, agent.projectConfigPath);
7712
+ const configPath2 = agent.configScope === "global" ? join12(homedir(), agent.projectConfigPath) : join12(cwd, agent.projectConfigPath);
7556
7713
  const dir = dirname3(configPath2);
7557
- if (!existsSync9(dir)) {
7558
- mkdirSync5(dir, { recursive: true });
7714
+ if (!existsSync10(dir)) {
7715
+ mkdirSync6(dir, { recursive: true });
7559
7716
  }
7560
7717
  switch (agent.configFormat) {
7561
7718
  case "mcp-json":
@@ -7579,10 +7736,10 @@ function writeAllMcpConfigs(cwd, agents) {
7579
7736
  function removeMcpConfig(cwd, ide) {
7580
7737
  const agent = getAgent(ide);
7581
7738
  if (!agent) return false;
7582
- const configPath2 = agent.configScope === "global" ? join11(homedir(), agent.projectConfigPath) : join11(cwd, agent.projectConfigPath);
7583
- if (!existsSync9(configPath2)) return false;
7739
+ const configPath2 = agent.configScope === "global" ? join12(homedir(), agent.projectConfigPath) : join12(cwd, agent.projectConfigPath);
7740
+ if (!existsSync10(configPath2)) return false;
7584
7741
  try {
7585
- const existing = JSON.parse(readFileSync8(configPath2, "utf-8"));
7742
+ const existing = JSON.parse(readFileSync9(configPath2, "utf-8"));
7586
7743
  if (agent.configFormat === "continue-config") {
7587
7744
  if (!Array.isArray(existing.mcpServers)) return false;
7588
7745
  existing.mcpServers = existing.mcpServers.filter(
@@ -7602,7 +7759,7 @@ function removeMcpConfig(cwd, ide) {
7602
7759
  unlinkSync(configPath2);
7603
7760
  tryRmdir(dirname3(configPath2));
7604
7761
  } else {
7605
- writeFileSync3(configPath2, JSON.stringify(existing, null, 2), "utf-8");
7762
+ writeFileSync4(configPath2, JSON.stringify(existing, null, 2), "utf-8");
7606
7763
  }
7607
7764
  return true;
7608
7765
  } catch {
@@ -7630,10 +7787,10 @@ function tryRmdir(dir) {
7630
7787
  function isConfigured(cwd, ide) {
7631
7788
  const agent = getAgent(ide);
7632
7789
  if (!agent) return false;
7633
- const configPath2 = agent.configScope === "global" ? join11(homedir(), agent.projectConfigPath) : join11(cwd, agent.projectConfigPath);
7634
- if (!existsSync9(configPath2)) return false;
7790
+ const configPath2 = agent.configScope === "global" ? join12(homedir(), agent.projectConfigPath) : join12(cwd, agent.projectConfigPath);
7791
+ if (!existsSync10(configPath2)) return false;
7635
7792
  try {
7636
- const existing = JSON.parse(readFileSync8(configPath2, "utf-8"));
7793
+ const existing = JSON.parse(readFileSync9(configPath2, "utf-8"));
7637
7794
  if (agent.configFormat === "continue-config") {
7638
7795
  return Array.isArray(existing.mcpServers) && existing.mcpServers.some(
7639
7796
  (s) => s.name === UNERR_SERVER_KEY
@@ -7692,10 +7849,10 @@ function getConfigInfo(ide) {
7692
7849
  };
7693
7850
  }
7694
7851
  function writeMcpJsonFormat(configPath2, ide) {
7695
- if (existsSync9(configPath2)) {
7852
+ if (existsSync10(configPath2)) {
7696
7853
  try {
7697
7854
  const existing = JSON.parse(
7698
- readFileSync8(configPath2, "utf-8")
7855
+ readFileSync9(configPath2, "utf-8")
7699
7856
  );
7700
7857
  const current = existing.mcpServers?.[UNERR_SERVER_KEY];
7701
7858
  const desired = createUnerrServerEntry(ide);
@@ -7704,7 +7861,7 @@ function writeMcpJsonFormat(configPath2, ide) {
7704
7861
  }
7705
7862
  existing.mcpServers = existing.mcpServers ?? {};
7706
7863
  existing.mcpServers[UNERR_SERVER_KEY] = desired;
7707
- writeFileSync3(configPath2, JSON.stringify(existing, null, 2), "utf-8");
7864
+ writeFileSync4(configPath2, JSON.stringify(existing, null, 2), "utf-8");
7708
7865
  return { path: configPath2, action: "updated" };
7709
7866
  } catch {
7710
7867
  return { path: configPath2, action: "skipped" };
@@ -7713,13 +7870,13 @@ function writeMcpJsonFormat(configPath2, ide) {
7713
7870
  const config = {
7714
7871
  mcpServers: { [UNERR_SERVER_KEY]: createUnerrServerEntry(ide) }
7715
7872
  };
7716
- writeFileSync3(configPath2, JSON.stringify(config, null, 2), "utf-8");
7873
+ writeFileSync4(configPath2, JSON.stringify(config, null, 2), "utf-8");
7717
7874
  return { path: configPath2, action: "created" };
7718
7875
  }
7719
7876
  function writeSettingsJsonFormat(configPath2, ide) {
7720
- if (existsSync9(configPath2)) {
7877
+ if (existsSync10(configPath2)) {
7721
7878
  try {
7722
- const existing = JSON.parse(readFileSync8(configPath2, "utf-8"));
7879
+ const existing = JSON.parse(readFileSync9(configPath2, "utf-8"));
7723
7880
  const mcp = existing.mcp ?? {};
7724
7881
  const servers = mcp.servers ?? {};
7725
7882
  const current = servers[UNERR_SERVER_KEY];
@@ -7730,7 +7887,7 @@ function writeSettingsJsonFormat(configPath2, ide) {
7730
7887
  servers[UNERR_SERVER_KEY] = desired;
7731
7888
  mcp.servers = servers;
7732
7889
  existing.mcp = mcp;
7733
- writeFileSync3(configPath2, JSON.stringify(existing, null, 2), "utf-8");
7890
+ writeFileSync4(configPath2, JSON.stringify(existing, null, 2), "utf-8");
7734
7891
  return { path: configPath2, action: "updated" };
7735
7892
  } catch {
7736
7893
  return { path: configPath2, action: "skipped" };
@@ -7739,14 +7896,14 @@ function writeSettingsJsonFormat(configPath2, ide) {
7739
7896
  const config = {
7740
7897
  mcp: { servers: { [UNERR_SERVER_KEY]: createUnerrServerEntry(ide) } }
7741
7898
  };
7742
- writeFileSync3(configPath2, JSON.stringify(config, null, 2), "utf-8");
7899
+ writeFileSync4(configPath2, JSON.stringify(config, null, 2), "utf-8");
7743
7900
  return { path: configPath2, action: "created" };
7744
7901
  }
7745
7902
  function writeContinueFormat(configPath2, ide) {
7746
7903
  const entry = { name: UNERR_SERVER_KEY, ...createUnerrServerEntry(ide) };
7747
- if (existsSync9(configPath2)) {
7904
+ if (existsSync10(configPath2)) {
7748
7905
  try {
7749
- const existing = JSON.parse(readFileSync8(configPath2, "utf-8"));
7906
+ const existing = JSON.parse(readFileSync9(configPath2, "utf-8"));
7750
7907
  const servers = existing.mcpServers ?? [];
7751
7908
  const idx = servers.findIndex((s) => s.name === UNERR_SERVER_KEY);
7752
7909
  if (idx >= 0 && entryMatches(servers[idx], entry)) {
@@ -7758,21 +7915,21 @@ function writeContinueFormat(configPath2, ide) {
7758
7915
  servers.push(entry);
7759
7916
  }
7760
7917
  existing.mcpServers = servers;
7761
- writeFileSync3(configPath2, JSON.stringify(existing, null, 2), "utf-8");
7918
+ writeFileSync4(configPath2, JSON.stringify(existing, null, 2), "utf-8");
7762
7919
  return { path: configPath2, action: "updated" };
7763
7920
  } catch {
7764
7921
  return { path: configPath2, action: "skipped" };
7765
7922
  }
7766
7923
  }
7767
7924
  const config = { mcpServers: [entry] };
7768
- writeFileSync3(configPath2, JSON.stringify(config, null, 2), "utf-8");
7925
+ writeFileSync4(configPath2, JSON.stringify(config, null, 2), "utf-8");
7769
7926
  return { path: configPath2, action: "created" };
7770
7927
  }
7771
7928
  function writeCopilotJsonFormat(configPath2, ide) {
7772
- if (existsSync9(configPath2)) {
7929
+ if (existsSync10(configPath2)) {
7773
7930
  try {
7774
7931
  const existing = JSON.parse(
7775
- readFileSync8(configPath2, "utf-8")
7932
+ readFileSync9(configPath2, "utf-8")
7776
7933
  );
7777
7934
  const current = existing.mcpServers?.[UNERR_SERVER_KEY];
7778
7935
  const desired = createCopilotServerEntry(ide);
@@ -7781,7 +7938,7 @@ function writeCopilotJsonFormat(configPath2, ide) {
7781
7938
  }
7782
7939
  existing.mcpServers = existing.mcpServers ?? {};
7783
7940
  existing.mcpServers[UNERR_SERVER_KEY] = desired;
7784
- writeFileSync3(configPath2, JSON.stringify(existing, null, 2), "utf-8");
7941
+ writeFileSync4(configPath2, JSON.stringify(existing, null, 2), "utf-8");
7785
7942
  return { path: configPath2, action: "updated" };
7786
7943
  } catch {
7787
7944
  return { path: configPath2, action: "skipped" };
@@ -7790,7 +7947,7 @@ function writeCopilotJsonFormat(configPath2, ide) {
7790
7947
  const config = {
7791
7948
  mcpServers: { [UNERR_SERVER_KEY]: createCopilotServerEntry(ide) }
7792
7949
  };
7793
- writeFileSync3(configPath2, JSON.stringify(config, null, 2), "utf-8");
7950
+ writeFileSync4(configPath2, JSON.stringify(config, null, 2), "utf-8");
7794
7951
  return { path: configPath2, action: "created" };
7795
7952
  }
7796
7953
  var UNERR_SERVER_KEY, _resolvedCommand;
@@ -7813,8 +7970,8 @@ __export(detect_exports, {
7813
7970
  ideDisplayName: () => ideDisplayName,
7814
7971
  isGitRepo: () => isGitRepo2
7815
7972
  });
7816
- import { existsSync as existsSync10 } from "fs";
7817
- import { join as join12 } from "path";
7973
+ import { existsSync as existsSync11 } from "fs";
7974
+ import { join as join13 } from "path";
7818
7975
  function classifyHost(remote) {
7819
7976
  const lower = remote.toLowerCase();
7820
7977
  if (lower.includes("github.com")) return "github";
@@ -7876,15 +8033,15 @@ async function detectIde(cwd) {
7876
8033
  }
7877
8034
  } catch {
7878
8035
  }
7879
- if (existsSync10(join12(cwd, ".cursor"))) return "cursor";
7880
- if (existsSync10(join12(cwd, ".windsurf"))) return "windsurf";
8036
+ if (existsSync11(join13(cwd, ".cursor"))) return "cursor";
8037
+ if (existsSync11(join13(cwd, ".windsurf"))) return "windsurf";
7881
8038
  if (termProgram === "vscode") return "vscode";
7882
- if (existsSync10(join12(cwd, ".vscode"))) return "vscode";
7883
- if (process.env.ZED_TERM === "true" || existsSync10(join12(cwd, ".zed")))
8039
+ if (existsSync11(join13(cwd, ".vscode"))) return "vscode";
8040
+ if (process.env.ZED_TERM === "true" || existsSync11(join13(cwd, ".zed")))
7884
8041
  return "zed";
7885
8042
  if (process.env.ANTIGRAVITY_PROJECT_DIR || process.env.ANTIGRAVITY_VERSION)
7886
8043
  return "antigravity";
7887
- if (existsSync10(join12(cwd, ".antigravity"))) return "antigravity";
8044
+ if (existsSync11(join13(cwd, ".antigravity"))) return "antigravity";
7888
8045
  return "unknown";
7889
8046
  }
7890
8047
  function detectAgentNameFromEnv() {
@@ -8210,8 +8367,8 @@ var init_config_verify = __esm({
8210
8367
 
8211
8368
  // src/utils/log-paths.ts
8212
8369
  import { randomBytes } from "crypto";
8213
- import { existsSync as existsSync12, readdirSync as readdirSync3, statSync as statSync2, unlinkSync as unlinkSync2 } from "fs";
8214
- import { join as join14 } from "path";
8370
+ import { existsSync as existsSync13, readdirSync as readdirSync4, statSync as statSync3, unlinkSync as unlinkSync2 } from "fs";
8371
+ import { join as join15 } from "path";
8215
8372
  function getOrCreateSid() {
8216
8373
  if (_sid) return _sid;
8217
8374
  const fromEnv = process.env[ENV_VAR];
@@ -8224,10 +8381,10 @@ function getOrCreateSid() {
8224
8381
  return _sid;
8225
8382
  }
8226
8383
  function repoLogsDir(repoRoot) {
8227
- return join14(repoRoot, ".unerr", "logs");
8384
+ return join15(repoRoot, ".unerr", "logs");
8228
8385
  }
8229
8386
  function globalLogsDir(globalRoot) {
8230
- return join14(globalRoot, "logs");
8387
+ return join15(globalRoot, "logs");
8231
8388
  }
8232
8389
  function isLegacyTimestampedSession(name) {
8233
8390
  return /^session-\d{4}-\d{2}-\d{2}-\d{6}\.log(?:\.\d+)?$/.test(name);
@@ -8240,14 +8397,14 @@ function isLegacyName(name) {
8240
8397
  return false;
8241
8398
  }
8242
8399
  function cleanupLegacyLogs(dir) {
8243
- if (!existsSync12(dir)) return 0;
8400
+ if (!existsSync13(dir)) return 0;
8244
8401
  let removed = 0;
8245
8402
  try {
8246
- for (const name of readdirSync3(dir)) {
8403
+ for (const name of readdirSync4(dir)) {
8247
8404
  if (!isLegacyName(name)) continue;
8248
- const full = join14(dir, name);
8405
+ const full = join15(dir, name);
8249
8406
  try {
8250
- if (!statSync2(full).isFile()) continue;
8407
+ if (!statSync3(full).isFile()) continue;
8251
8408
  unlinkSync2(full);
8252
8409
  removed++;
8253
8410
  } catch {
@@ -8265,14 +8422,14 @@ var init_log_paths = __esm({
8265
8422
  SID_RE = /^[a-f0-9]{6}$/;
8266
8423
  _sid = null;
8267
8424
  repoLog = {
8268
- proxy: (repoRoot) => join14(repoLogsDir(repoRoot), "proxy.log"),
8269
- bridge: (repoRoot) => join14(repoLogsDir(repoRoot), "bridge.log"),
8270
- session: (repoRoot) => join14(repoLogsDir(repoRoot), "session.log"),
8271
- events: (repoRoot) => join14(repoLogsDir(repoRoot), "events.jsonl")
8425
+ proxy: (repoRoot) => join15(repoLogsDir(repoRoot), "proxy.log"),
8426
+ bridge: (repoRoot) => join15(repoLogsDir(repoRoot), "bridge.log"),
8427
+ session: (repoRoot) => join15(repoLogsDir(repoRoot), "session.log"),
8428
+ events: (repoRoot) => join15(repoLogsDir(repoRoot), "events.jsonl")
8272
8429
  };
8273
8430
  globalLog = {
8274
- unerrd: (globalRoot) => join14(globalLogsDir(globalRoot), "unerrd.log"),
8275
- events: (globalRoot) => join14(globalLogsDir(globalRoot), "events.jsonl")
8431
+ unerrd: (globalRoot) => join15(globalLogsDir(globalRoot), "unerrd.log"),
8432
+ events: (globalRoot) => join15(globalLogsDir(globalRoot), "events.jsonl")
8276
8433
  };
8277
8434
  LEGACY_PREFIXES = ["mcp-", "child-"];
8278
8435
  LEGACY_EXACT = /* @__PURE__ */ new Set([
@@ -8294,9 +8451,9 @@ __export(startup_log_exports, {
8294
8451
  });
8295
8452
  import {
8296
8453
  appendFileSync as appendFileSync4,
8297
- mkdirSync as mkdirSync7,
8298
- readFileSync as readFileSync10,
8299
- writeFileSync as writeFileSync5
8454
+ mkdirSync as mkdirSync8,
8455
+ readFileSync as readFileSync11,
8456
+ writeFileSync as writeFileSync6
8300
8457
  } from "fs";
8301
8458
  import { dirname as dirname5 } from "path";
8302
8459
  function stripAnsi(s) {
@@ -8307,10 +8464,10 @@ function stripAnsi(s) {
8307
8464
  }
8308
8465
  function rotateIfNeeded(filePath, maxLines, keepLines) {
8309
8466
  try {
8310
- const content = readFileSync10(filePath, "utf-8");
8467
+ const content = readFileSync11(filePath, "utf-8");
8311
8468
  const lines = content.split("\n").filter(Boolean);
8312
8469
  if (lines.length > maxLines) {
8313
- writeFileSync5(filePath, `${lines.slice(-keepLines).join("\n")}
8470
+ writeFileSync6(filePath, `${lines.slice(-keepLines).join("\n")}
8314
8471
  `);
8315
8472
  }
8316
8473
  } catch {
@@ -8318,7 +8475,7 @@ function rotateIfNeeded(filePath, maxLines, keepLines) {
8318
8475
  }
8319
8476
  function initFileLog(cwd) {
8320
8477
  _fileLogPath = repoLog.events(cwd);
8321
- mkdirSync7(dirname5(_fileLogPath), { recursive: true });
8478
+ mkdirSync8(dirname5(_fileLogPath), { recursive: true });
8322
8479
  rotateIfNeeded(_fileLogPath, 2e3, 1e3);
8323
8480
  }
8324
8481
  function writeToFile(level, message, meta) {
@@ -8903,9 +9060,9 @@ __export(settings_exports, {
8903
9060
  resolveEmbeddingEndpoint: () => resolveEmbeddingEndpoint,
8904
9061
  resolveInferenceEndpoint: () => resolveInferenceEndpoint
8905
9062
  });
8906
- import { existsSync as existsSync16, readFileSync as readFileSync14 } from "fs";
9063
+ import { existsSync as existsSync17, readFileSync as readFileSync15 } from "fs";
8907
9064
  import { homedir as homedir5 } from "os";
8908
- import { join as join18 } from "path";
9065
+ import { join as join19 } from "path";
8909
9066
  import { z } from "zod";
8910
9067
  function resolveEmbeddingEndpoint(config) {
8911
9068
  const e = config.embedding;
@@ -8926,18 +9083,18 @@ function resolveInferenceEndpoint(config) {
8926
9083
  };
8927
9084
  }
8928
9085
  function loadJsonFile(filePath) {
8929
- if (!existsSync16(filePath)) return {};
9086
+ if (!existsSync17(filePath)) return {};
8930
9087
  try {
8931
- return JSON.parse(readFileSync14(filePath, "utf-8"));
9088
+ return JSON.parse(readFileSync15(filePath, "utf-8"));
8932
9089
  } catch {
8933
9090
  return {};
8934
9091
  }
8935
9092
  }
8936
9093
  function loadSettings(cwd) {
8937
9094
  const projectDir = cwd ?? process.cwd();
8938
- const userSettings = loadJsonFile(join18(homedir5(), ".unerr", "settings.json"));
9095
+ const userSettings = loadJsonFile(join19(homedir5(), ".unerr", "settings.json"));
8939
9096
  const projectSettings = loadJsonFile(
8940
- join18(projectDir, ".unerr", "settings.json")
9097
+ join19(projectDir, ".unerr", "settings.json")
8941
9098
  );
8942
9099
  const envOverrides = {};
8943
9100
  if (process.env.ANTHROPIC_API_KEY)
@@ -9067,24 +9224,24 @@ __export(persistent_db_exports, {
9067
9224
  hasPersistedGraph: () => hasPersistedGraph,
9068
9225
  openPersistentDb: () => openPersistentDb
9069
9226
  });
9070
- import { existsSync as existsSync17, mkdirSync as mkdirSync9, statSync as statSync4 } from "fs";
9071
- import { join as join19 } from "path";
9227
+ import { existsSync as existsSync18, mkdirSync as mkdirSync10, statSync as statSync5 } from "fs";
9228
+ import { join as join20 } from "path";
9072
9229
  async function openPersistentDb(projectRoot) {
9073
- const unerrDir2 = join19(projectRoot, UNERR_DIR2);
9074
- mkdirSync9(unerrDir2, { recursive: true });
9075
- const dbPath = join19(unerrDir2, GRAPH_DB_FILENAME);
9076
- const isNew = !existsSync17(dbPath);
9230
+ const unerrDir2 = join20(projectRoot, UNERR_DIR2);
9231
+ mkdirSync10(unerrDir2, { recursive: true });
9232
+ const dbPath = join20(unerrDir2, GRAPH_DB_FILENAME);
9233
+ const isNew = !existsSync18(dbPath);
9077
9234
  const db = await createSqliteDb(dbPath);
9078
9235
  return { db, isNew, dbPath };
9079
9236
  }
9080
9237
  function getDbPath(projectRoot) {
9081
- return join19(projectRoot, UNERR_DIR2, GRAPH_DB_FILENAME);
9238
+ return join20(projectRoot, UNERR_DIR2, GRAPH_DB_FILENAME);
9082
9239
  }
9083
9240
  function hasPersistedGraph(projectRoot) {
9084
9241
  const dbPath = getDbPath(projectRoot);
9085
- if (!existsSync17(dbPath)) return false;
9242
+ if (!existsSync18(dbPath)) return false;
9086
9243
  try {
9087
- const stat2 = statSync4(dbPath);
9244
+ const stat2 = statSync5(dbPath);
9088
9245
  return stat2.size > 5e4;
9089
9246
  } catch {
9090
9247
  return false;
@@ -9093,7 +9250,7 @@ function hasPersistedGraph(projectRoot) {
9093
9250
  function getDbMtime(projectRoot) {
9094
9251
  const dbPath = getDbPath(projectRoot);
9095
9252
  try {
9096
- return statSync4(dbPath).mtimeMs;
9253
+ return statSync5(dbPath).mtimeMs;
9097
9254
  } catch {
9098
9255
  return 0;
9099
9256
  }
@@ -9574,8 +9731,8 @@ var init_local_chat_provider = __esm({
9574
9731
  });
9575
9732
 
9576
9733
  // src/proxy/nudge-state.ts
9577
- import { existsSync as existsSync18, mkdirSync as mkdirSync10, readFileSync as readFileSync15, writeFileSync as writeFileSync6 } from "fs";
9578
- import { join as join20 } from "path";
9734
+ import { existsSync as existsSync19, mkdirSync as mkdirSync11, readFileSync as readFileSync16, writeFileSync as writeFileSync7 } from "fs";
9735
+ import { join as join21 } from "path";
9579
9736
  function defaultState() {
9580
9737
  return {
9581
9738
  tier0_emitted: false,
@@ -9600,13 +9757,13 @@ function defaultState() {
9600
9757
  }
9601
9758
  function statePath(cwd) {
9602
9759
  const sessionId = process.env.UNERR_SESSION_ID ?? `pid-${process.pid}`;
9603
- return join20(cwd, ".unerr", "state", `nudge-${sessionId}.flags`);
9760
+ return join21(cwd, ".unerr", "state", `nudge-${sessionId}.flags`);
9604
9761
  }
9605
9762
  function readNudgeState(cwd) {
9606
9763
  try {
9607
9764
  const path7 = statePath(cwd);
9608
- if (!existsSync18(path7)) return defaultState();
9609
- const raw = readFileSync15(path7, "utf8");
9765
+ if (!existsSync19(path7)) return defaultState();
9766
+ const raw = readFileSync16(path7, "utf8");
9610
9767
  const parsed = JSON.parse(raw);
9611
9768
  return {
9612
9769
  tier0_emitted: Boolean(parsed.tier0_emitted),
@@ -9639,8 +9796,8 @@ function writeNudgeState(cwd, state) {
9639
9796
  try {
9640
9797
  const path7 = statePath(cwd);
9641
9798
  const dir = path7.slice(0, path7.lastIndexOf("/"));
9642
- if (!existsSync18(dir)) mkdirSync10(dir, { recursive: true });
9643
- writeFileSync6(path7, JSON.stringify(state), "utf8");
9799
+ if (!existsSync19(dir)) mkdirSync11(dir, { recursive: true });
9800
+ writeFileSync7(path7, JSON.stringify(state), "utf8");
9644
9801
  } catch {
9645
9802
  }
9646
9803
  }
@@ -9664,8 +9821,8 @@ __export(metrics_store_exports, {
9664
9821
  closeMetricsStore: () => closeMetricsStore,
9665
9822
  openMetricsStore: () => openMetricsStore
9666
9823
  });
9667
- import { mkdirSync as mkdirSync11 } from "fs";
9668
- import { join as join21 } from "path";
9824
+ import { mkdirSync as mkdirSync12 } from "fs";
9825
+ import { join as join22 } from "path";
9669
9826
  import Database from "better-sqlite3";
9670
9827
  function reconcileAdditiveColumns(db) {
9671
9828
  for (const { table: table2, column, decl } of ADDITIVE_COLUMNS) {
@@ -9678,8 +9835,8 @@ function reconcileAdditiveColumns(db) {
9678
9835
  function openMetricsStore(unerrDir2) {
9679
9836
  let store = instances.get(unerrDir2);
9680
9837
  if (!store) {
9681
- mkdirSync11(unerrDir2, { recursive: true });
9682
- store = new MetricsStore(join21(unerrDir2, "metrics.db"));
9838
+ mkdirSync12(unerrDir2, { recursive: true });
9839
+ store = new MetricsStore(join22(unerrDir2, "metrics.db"));
9683
9840
  instances.set(unerrDir2, store);
9684
9841
  }
9685
9842
  return store;
@@ -10520,14 +10677,14 @@ __export(shell_compression_log_exports, {
10520
10677
  readRecentCompressionLogs: () => readRecentCompressionLogs,
10521
10678
  readRecentFileReadLogs: () => readRecentFileReadLogs
10522
10679
  });
10523
- import { join as join22 } from "path";
10680
+ import { join as join23 } from "path";
10524
10681
  function parseTs(ts) {
10525
10682
  const n = Date.parse(ts);
10526
10683
  return Number.isNaN(n) ? Date.now() : n;
10527
10684
  }
10528
10685
  function appendCompressionLog(cwd, entry) {
10529
10686
  try {
10530
- const store = openMetricsStore(join22(cwd, ".unerr"));
10687
+ const store = openMetricsStore(join23(cwd, ".unerr"));
10531
10688
  store.insertCompression({
10532
10689
  ts: parseTs(entry.ts),
10533
10690
  ts_iso: entry.ts,
@@ -10545,7 +10702,7 @@ function appendCompressionLog(cwd, entry) {
10545
10702
  }
10546
10703
  function appendFileReadLog(cwd, entry) {
10547
10704
  try {
10548
- const store = openMetricsStore(join22(cwd, ".unerr"));
10705
+ const store = openMetricsStore(join23(cwd, ".unerr"));
10549
10706
  store.insertFileRead({
10550
10707
  ts: parseTs(entry.ts),
10551
10708
  ts_iso: entry.ts,
@@ -10562,7 +10719,7 @@ function appendFileReadLog(cwd, entry) {
10562
10719
  }
10563
10720
  function readRecentFileReadLogs(cwd, limit = 10) {
10564
10721
  try {
10565
- const store = openMetricsStore(join22(cwd, ".unerr"));
10722
+ const store = openMetricsStore(join23(cwd, ".unerr"));
10566
10723
  return store.recentFileReads(limit).map((r) => ({
10567
10724
  ts: r.ts_iso,
10568
10725
  file: r.file,
@@ -10579,7 +10736,7 @@ function readRecentFileReadLogs(cwd, limit = 10) {
10579
10736
  }
10580
10737
  function readRecentCompressionLogs(cwd, limit = 10) {
10581
10738
  try {
10582
- const store = openMetricsStore(join22(cwd, ".unerr"));
10739
+ const store = openMetricsStore(join23(cwd, ".unerr"));
10583
10740
  return store.recentCompression(limit).map((r) => ({
10584
10741
  ts: r.ts_iso,
10585
10742
  command: r.command,
@@ -10609,16 +10766,16 @@ __export(shell_stats_exports, {
10609
10766
  readShellCompressionAggregate: () => readShellCompressionAggregate,
10610
10767
  recordShellCompressionEvent: () => recordShellCompressionEvent
10611
10768
  });
10612
- import { existsSync as existsSync19, mkdirSync as mkdirSync12, readFileSync as readFileSync16, writeFileSync as writeFileSync7 } from "fs";
10613
- import { join as join23 } from "path";
10769
+ import { existsSync as existsSync20, mkdirSync as mkdirSync13, readFileSync as readFileSync17, writeFileSync as writeFileSync8 } from "fs";
10770
+ import { join as join24 } from "path";
10614
10771
  function estimateRoughTokens(s) {
10615
10772
  return Math.max(1, estimateTokenCount(s));
10616
10773
  }
10617
10774
  function recordShellCompressionEvent(cwd, category, original, compressed) {
10618
10775
  try {
10619
- const dir = join23(cwd, ".unerr", "state");
10620
- mkdirSync12(dir, { recursive: true });
10621
- const path7 = join23(dir, "shell_compression_stats.json");
10776
+ const dir = join24(cwd, ".unerr", "state");
10777
+ mkdirSync13(dir, { recursive: true });
10778
+ const path7 = join24(dir, "shell_compression_stats.json");
10622
10779
  const origT = estimateRoughTokens(original);
10623
10780
  const outT = estimateRoughTokens(compressed);
10624
10781
  const saved = Math.max(0, origT - outT);
@@ -10628,11 +10785,11 @@ function recordShellCompressionEvent(cwd, category, original, compressed) {
10628
10785
  byCategory: {},
10629
10786
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
10630
10787
  };
10631
- if (existsSync19(path7)) {
10788
+ if (existsSync20(path7)) {
10632
10789
  agg = {
10633
10790
  ...agg,
10634
10791
  ...JSON.parse(
10635
- readFileSync16(path7, "utf-8")
10792
+ readFileSync17(path7, "utf-8")
10636
10793
  )
10637
10794
  };
10638
10795
  }
@@ -10644,15 +10801,15 @@ function recordShellCompressionEvent(cwd, category, original, compressed) {
10644
10801
  savedApprox: prev.savedApprox + saved
10645
10802
  };
10646
10803
  agg.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
10647
- writeFileSync7(path7, JSON.stringify(agg));
10804
+ writeFileSync8(path7, JSON.stringify(agg));
10648
10805
  } catch {
10649
10806
  }
10650
10807
  }
10651
10808
  function readShellCompressionAggregate(cwd) {
10652
10809
  try {
10653
- const path7 = join23(cwd, ".unerr", "state", "shell_compression_stats.json");
10654
- if (!existsSync19(path7)) return null;
10655
- return JSON.parse(readFileSync16(path7, "utf-8"));
10810
+ const path7 = join24(cwd, ".unerr", "state", "shell_compression_stats.json");
10811
+ if (!existsSync20(path7)) return null;
10812
+ return JSON.parse(readFileSync17(path7, "utf-8"));
10656
10813
  } catch {
10657
10814
  return null;
10658
10815
  }
@@ -10674,14 +10831,14 @@ __export(session_edit_log_exports, {
10674
10831
  });
10675
10832
  import {
10676
10833
  appendFileSync as appendFileSync6,
10677
- existsSync as existsSync22,
10678
- mkdirSync as mkdirSync14,
10679
- readFileSync as readFileSync20,
10834
+ existsSync as existsSync23,
10835
+ mkdirSync as mkdirSync15,
10836
+ readFileSync as readFileSync21,
10680
10837
  rmSync as rmSync2
10681
10838
  } from "fs";
10682
- import { dirname as dirname7, join as join27 } from "path";
10839
+ import { dirname as dirname7, join as join28 } from "path";
10683
10840
  function editLogPath(unerrDir2) {
10684
- return join27(unerrDir2, "state", EDIT_LOG_FILE);
10841
+ return join28(unerrDir2, "state", EDIT_LOG_FILE);
10685
10842
  }
10686
10843
  function cap(content) {
10687
10844
  if (content === null) return null;
@@ -10691,7 +10848,7 @@ function recordEdit(unerrDir2, event) {
10691
10848
  try {
10692
10849
  const path7 = editLogPath(unerrDir2);
10693
10850
  const dir = dirname7(path7);
10694
- if (!existsSync22(dir)) mkdirSync14(dir, { recursive: true });
10851
+ if (!existsSync23(dir)) mkdirSync15(dir, { recursive: true });
10695
10852
  const line = `${JSON.stringify({
10696
10853
  ts: event.ts,
10697
10854
  file_path: event.file_path,
@@ -10708,8 +10865,8 @@ function recordEdit(unerrDir2, event) {
10708
10865
  function readEditLog(unerrDir2) {
10709
10866
  try {
10710
10867
  const path7 = editLogPath(unerrDir2);
10711
- if (!existsSync22(path7)) return [];
10712
- const raw = readFileSync20(path7, "utf-8");
10868
+ if (!existsSync23(path7)) return [];
10869
+ const raw = readFileSync21(path7, "utf-8");
10713
10870
  const events = [];
10714
10871
  for (const line of raw.split("\n")) {
10715
10872
  const trimmed = line.trim();
@@ -10748,11 +10905,11 @@ __export(blast_radius_protocol_exports, {
10748
10905
  handleBlastRadiusRequest: () => handleBlastRadiusRequest,
10749
10906
  recordBlastRadiusTelemetry: () => recordBlastRadiusTelemetry
10750
10907
  });
10751
- import { isAbsolute, relative } from "path";
10908
+ import { isAbsolute, relative as relative2 } from "path";
10752
10909
  async function handleBlastRadiusRequest(graph, params, projectRoot = process.cwd()) {
10753
10910
  const rawPath = params?.file_path;
10754
10911
  if (!rawPath || !graph) return { warnings: [], boundary_violations: [] };
10755
- const filePath = isAbsolute(rawPath) ? relative(projectRoot, rawPath) : rawPath;
10912
+ const filePath = isAbsolute(rawPath) ? relative2(projectRoot, rawPath) : rawPath;
10756
10913
  const warnings = await computeEditImpact(
10757
10914
  graph,
10758
10915
  filePath,
@@ -11029,12 +11186,12 @@ __export(review_protocol_exports, {
11029
11186
  REVIEW_EDIT_METHOD: () => REVIEW_EDIT_METHOD,
11030
11187
  handleReviewEditRequest: () => handleReviewEditRequest
11031
11188
  });
11032
- import { isAbsolute as isAbsolute2, relative as relative2 } from "path";
11189
+ import { isAbsolute as isAbsolute2, relative as relative3 } from "path";
11033
11190
  async function handleReviewEditRequest(graph, params, deps = {}) {
11034
11191
  const rawPath = params?.file_path;
11035
11192
  if (!rawPath || !graph) return EMPTY_RESULT;
11036
11193
  const projectRoot = deps.projectRoot ?? process.cwd();
11037
- const filePath = isAbsolute2(rawPath) ? relative2(projectRoot, rawPath) : rawPath;
11194
+ const filePath = isAbsolute2(rawPath) ? relative3(projectRoot, rawPath) : rawPath;
11038
11195
  const reviewGraph = graph;
11039
11196
  const oldContent = params?.old_content ?? null;
11040
11197
  const newContent = params?.new_content ?? null;
@@ -11110,13 +11267,13 @@ var init_capability = __esm({
11110
11267
  });
11111
11268
 
11112
11269
  // src/tracking/agent-transcript/config-flag.ts
11113
- import { existsSync as existsSync26, readFileSync as readFileSync22 } from "fs";
11114
- import { join as join31 } from "path";
11270
+ import { existsSync as existsSync27, readFileSync as readFileSync23 } from "fs";
11271
+ import { join as join32 } from "path";
11115
11272
  function readAgentTranscriptsFlag(cwd) {
11116
11273
  try {
11117
- const configPath2 = join31(cwd, ".unerr", "config.json");
11118
- if (!existsSync26(configPath2)) return false;
11119
- const raw = JSON.parse(readFileSync22(configPath2, "utf-8"));
11274
+ const configPath2 = join32(cwd, ".unerr", "config.json");
11275
+ if (!existsSync27(configPath2)) return false;
11276
+ const raw = JSON.parse(readFileSync23(configPath2, "utf-8"));
11120
11277
  return raw[READ_AGENT_TRANSCRIPTS_KEY] === true;
11121
11278
  } catch {
11122
11279
  return false;
@@ -11131,17 +11288,17 @@ var init_config_flag = __esm({
11131
11288
  });
11132
11289
 
11133
11290
  // src/tracking/agent-transcript/claude-jsonl.ts
11134
- import { createReadStream, existsSync as existsSync27 } from "fs";
11291
+ import { createReadStream, existsSync as existsSync28 } from "fs";
11135
11292
  import { readdir } from "fs/promises";
11136
11293
  import { homedir as homedir8 } from "os";
11137
- import { join as join32 } from "path";
11294
+ import { join as join33 } from "path";
11138
11295
  import { createInterface as createInterface2 } from "readline";
11139
11296
  function mangleCwd(cwd) {
11140
11297
  const trimmed = cwd.replace(/\/+$/, "");
11141
11298
  return trimmed.replace(/\//g, "-");
11142
11299
  }
11143
11300
  function claudeProjectDir(repoCwd, home = homedir8()) {
11144
- return join32(home, ".claude", "projects", mangleCwd(repoCwd));
11301
+ return join33(home, ".claude", "projects", mangleCwd(repoCwd));
11145
11302
  }
11146
11303
  function num(v) {
11147
11304
  return typeof v === "number" && Number.isFinite(v) && v > 0 ? v : 0;
@@ -11306,14 +11463,14 @@ async function readClaudeTranscript(opts) {
11306
11463
  const projectDir = opts.projectDirOverride ?? claudeProjectDir(opts.repoCwd, opts.home);
11307
11464
  try {
11308
11465
  if (opts.sessionId) {
11309
- const file = join32(projectDir, `${opts.sessionId}.jsonl`);
11310
- if (!existsSync27(file)) return [];
11466
+ const file = join33(projectDir, `${opts.sessionId}.jsonl`);
11467
+ if (!existsSync28(file)) return [];
11311
11468
  const nodes = await parseFile(file);
11312
11469
  return buildTurns(nodes, opts.sessionId);
11313
11470
  }
11314
- if (!existsSync27(projectDir)) return [];
11471
+ if (!existsSync28(projectDir)) return [];
11315
11472
  const entries = await readdir(projectDir, { withFileTypes: true });
11316
- const jsonlFiles = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => join32(projectDir, e.name));
11473
+ const jsonlFiles = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => join33(projectDir, e.name));
11317
11474
  const all = [];
11318
11475
  for (const file of jsonlFiles) {
11319
11476
  const nodes = await parseFile(file);
@@ -11361,27 +11518,27 @@ var init_claude_jsonl = __esm({
11361
11518
  });
11362
11519
 
11363
11520
  // src/tracking/agent-transcript/cursor-sqlite.ts
11364
- import { existsSync as existsSync28, readdirSync as readdirSync6, readFileSync as readFileSync23 } from "fs";
11521
+ import { existsSync as existsSync29, readdirSync as readdirSync7, readFileSync as readFileSync24 } from "fs";
11365
11522
  import { homedir as homedir9, platform as platform2 } from "os";
11366
- import { join as join33, normalize as normalize3 } from "path";
11523
+ import { join as join34, normalize as normalize3 } from "path";
11367
11524
  function cursorTelemetryDbPath(home = homedir9()) {
11368
- return join33(home, ".cursor", "ai-tracking", "ai-code-tracking.db");
11525
+ return join34(home, ".cursor", "ai-tracking", "ai-code-tracking.db");
11369
11526
  }
11370
11527
  function cursorUserDataDir(home = homedir9()) {
11371
11528
  const p = platform2();
11372
11529
  if (p === "darwin")
11373
- return join33(home, "Library", "Application Support", "Cursor", "User");
11530
+ return join34(home, "Library", "Application Support", "Cursor", "User");
11374
11531
  if (p === "win32") {
11375
- const appData = process.env.APPDATA ?? join33(home, "AppData", "Roaming");
11376
- return join33(appData, "Cursor", "User");
11532
+ const appData = process.env.APPDATA ?? join34(home, "AppData", "Roaming");
11533
+ return join34(appData, "Cursor", "User");
11377
11534
  }
11378
- return join33(home, ".config", "Cursor", "User");
11535
+ return join34(home, ".config", "Cursor", "User");
11379
11536
  }
11380
11537
  function cursorGlobalVscdbPath(home = homedir9()) {
11381
- return join33(cursorUserDataDir(home), "globalStorage", "state.vscdb");
11538
+ return join34(cursorUserDataDir(home), "globalStorage", "state.vscdb");
11382
11539
  }
11383
11540
  async function openReadOnly(path7) {
11384
- if (!existsSync28(path7)) return null;
11541
+ if (!existsSync29(path7)) return null;
11385
11542
  try {
11386
11543
  const mod = await import("better-sqlite3");
11387
11544
  const Database2 = mod.default ?? mod;
@@ -11480,18 +11637,18 @@ async function readCursorTranscript(opts) {
11480
11637
  }
11481
11638
  }
11482
11639
  function findWorkspaceHashesForRepo(repoCwd, home = homedir9()) {
11483
- const wsRoot = join33(cursorUserDataDir(home), "workspaceStorage");
11484
- if (!existsSync28(wsRoot)) return [];
11640
+ const wsRoot = join34(cursorUserDataDir(home), "workspaceStorage");
11641
+ if (!existsSync29(wsRoot)) return [];
11485
11642
  const normalizedCwd = normalize3(repoCwd).replace(/\/+$/, "");
11486
11643
  const hashes = [];
11487
11644
  try {
11488
- const entries = readdirSync6(wsRoot, { withFileTypes: true });
11645
+ const entries = readdirSync7(wsRoot, { withFileTypes: true });
11489
11646
  for (const entry of entries) {
11490
11647
  if (!entry.isDirectory()) continue;
11491
- const wsJsonPath = join33(wsRoot, entry.name, "workspace.json");
11492
- if (!existsSync28(wsJsonPath)) continue;
11648
+ const wsJsonPath = join34(wsRoot, entry.name, "workspace.json");
11649
+ if (!existsSync29(wsJsonPath)) continue;
11493
11650
  try {
11494
- const raw = JSON.parse(readFileSync23(wsJsonPath, "utf-8"));
11651
+ const raw = JSON.parse(readFileSync24(wsJsonPath, "utf-8"));
11495
11652
  const uri = raw.folder ?? raw.workspace ?? "";
11496
11653
  const decoded = uri.startsWith("file://") ? decodeURIComponent(uri.slice(7)) : uri;
11497
11654
  if (normalize3(decoded).replace(/\/+$/, "") === normalizedCwd) {
@@ -11601,7 +11758,7 @@ async function readCursorStateVscdb(opts) {
11601
11758
  if (hashes.length === 0) return [];
11602
11759
  composerIds = [];
11603
11760
  for (const hash2 of hashes) {
11604
- const wsDbPath = join33(
11761
+ const wsDbPath = join34(
11605
11762
  cursorUserDataDir(home),
11606
11763
  "workspaceStorage",
11607
11764
  hash2,
@@ -11718,13 +11875,13 @@ var init_transcript_materializer = __esm({
11718
11875
 
11719
11876
  // src/hooks/prompt-capture.ts
11720
11877
  import { createHash as createHash2 } from "crypto";
11721
- import { existsSync as existsSync29, readFileSync as readFileSync24 } from "fs";
11722
- import { join as join34 } from "path";
11878
+ import { existsSync as existsSync30, readFileSync as readFileSync25 } from "fs";
11879
+ import { join as join35 } from "path";
11723
11880
  function readCapturePromptsFlag(cwd) {
11724
11881
  try {
11725
- const configPath2 = join34(cwd, ".unerr", "config.json");
11726
- if (!existsSync29(configPath2)) return false;
11727
- const raw = JSON.parse(readFileSync24(configPath2, "utf-8"));
11882
+ const configPath2 = join35(cwd, ".unerr", "config.json");
11883
+ if (!existsSync30(configPath2)) return false;
11884
+ const raw = JSON.parse(readFileSync25(configPath2, "utf-8"));
11728
11885
  return raw.capture_prompts === true;
11729
11886
  } catch {
11730
11887
  return false;
@@ -11734,8 +11891,8 @@ function readProxySessionId(unerrDir2) {
11734
11891
  const fromEnv = process.env.UNERR_SESSION_ID;
11735
11892
  if (fromEnv && fromEnv.length > 0) return fromEnv;
11736
11893
  try {
11737
- const id = readFileSync24(
11738
- join34(unerrDir2, "state", "session.id"),
11894
+ const id = readFileSync25(
11895
+ join35(unerrDir2, "state", "session.id"),
11739
11896
  "utf-8"
11740
11897
  ).trim();
11741
11898
  return id.length > 0 ? id : null;
@@ -11920,8 +12077,8 @@ __export(session_summary_writer_exports, {
11920
12077
  readLastSession: () => readLastSession,
11921
12078
  writeSessionSummary: () => writeSessionSummary
11922
12079
  });
11923
- import { existsSync as existsSync31, mkdirSync as mkdirSync16, readFileSync as readFileSync26, writeFileSync as writeFileSync10 } from "fs";
11924
- import { join as join36 } from "path";
12080
+ import { existsSync as existsSync32, mkdirSync as mkdirSync17, readFileSync as readFileSync27, writeFileSync as writeFileSync11 } from "fs";
12081
+ import { join as join37 } from "path";
11925
12082
  function writeSessionSummary(unerrDir2, ctx) {
11926
12083
  if (ctx.entries.length === 0) return null;
11927
12084
  try {
@@ -11998,9 +12155,9 @@ function writeSessionSummary(unerrDir2, ctx) {
11998
12155
  }
11999
12156
  function readLastSession(unerrDir2) {
12000
12157
  try {
12001
- const pointerPath = join36(unerrDir2, "state", "last_session.json");
12002
- if (!existsSync31(pointerPath)) return null;
12003
- const content = readFileSync26(pointerPath, "utf-8");
12158
+ const pointerPath = join37(unerrDir2, "state", "last_session.json");
12159
+ if (!existsSync32(pointerPath)) return null;
12160
+ const content = readFileSync27(pointerPath, "utf-8");
12004
12161
  return JSON.parse(content);
12005
12162
  } catch {
12006
12163
  return null;
@@ -12008,12 +12165,12 @@ function readLastSession(unerrDir2) {
12008
12165
  }
12009
12166
  function writeLastSessionPointer(unerrDir2, sessionId, record) {
12010
12167
  try {
12011
- const stateDir = join36(unerrDir2, "state");
12012
- if (!existsSync31(stateDir)) {
12013
- mkdirSync16(stateDir, { recursive: true });
12168
+ const stateDir = join37(unerrDir2, "state");
12169
+ if (!existsSync32(stateDir)) {
12170
+ mkdirSync17(stateDir, { recursive: true });
12014
12171
  }
12015
- const pointerPath = join36(stateDir, "last_session.json");
12016
- writeFileSync10(pointerPath, JSON.stringify(record, null, 2), "utf-8");
12172
+ const pointerPath = join37(stateDir, "last_session.json");
12173
+ writeFileSync11(pointerPath, JSON.stringify(record, null, 2), "utf-8");
12017
12174
  } catch {
12018
12175
  }
12019
12176
  }
@@ -12341,8 +12498,8 @@ var incomplete_work_exports = {};
12341
12498
  __export(incomplete_work_exports, {
12342
12499
  IncompleteWorkDetector: () => IncompleteWorkDetector
12343
12500
  });
12344
- import { existsSync as existsSync32, mkdirSync as mkdirSync17, readFileSync as readFileSync27, writeFileSync as writeFileSync11 } from "fs";
12345
- import { join as join37 } from "path";
12501
+ import { existsSync as existsSync33, mkdirSync as mkdirSync18, readFileSync as readFileSync28, writeFileSync as writeFileSync12 } from "fs";
12502
+ import { join as join38 } from "path";
12346
12503
  function severityRank(severity) {
12347
12504
  switch (severity) {
12348
12505
  case "high":
@@ -12463,10 +12620,10 @@ var init_incomplete_work = __esm({
12463
12620
  persistItems(items) {
12464
12621
  if (!this.unerrDir) return false;
12465
12622
  try {
12466
- const stateDir = join37(this.unerrDir, "state");
12467
- if (!existsSync32(stateDir)) mkdirSync17(stateDir, { recursive: true });
12468
- const filePath = join37(stateDir, PERSISTENCE_FILE);
12469
- writeFileSync11(
12623
+ const stateDir = join38(this.unerrDir, "state");
12624
+ if (!existsSync33(stateDir)) mkdirSync18(stateDir, { recursive: true });
12625
+ const filePath = join38(stateDir, PERSISTENCE_FILE);
12626
+ writeFileSync12(
12470
12627
  filePath,
12471
12628
  JSON.stringify({
12472
12629
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -12485,9 +12642,9 @@ var init_incomplete_work = __esm({
12485
12642
  */
12486
12643
  static readPersistedItems(unerrDir2) {
12487
12644
  try {
12488
- const filePath = join37(unerrDir2, "state", PERSISTENCE_FILE);
12489
- if (!existsSync32(filePath)) return [];
12490
- const data = JSON.parse(readFileSync27(filePath, "utf-8"));
12645
+ const filePath = join38(unerrDir2, "state", PERSISTENCE_FILE);
12646
+ if (!existsSync33(filePath)) return [];
12647
+ const data = JSON.parse(readFileSync28(filePath, "utf-8"));
12491
12648
  return data.items ?? [];
12492
12649
  } catch {
12493
12650
  return [];
@@ -12709,163 +12866,6 @@ var init_session_persistence = __esm({
12709
12866
  }
12710
12867
  });
12711
12868
 
12712
- // src/intelligence/local-snapshot.ts
12713
- var local_snapshot_exports = {};
12714
- __export(local_snapshot_exports, {
12715
- getSnapshotMeta: () => getSnapshotMeta,
12716
- loadLocalSnapshot: () => loadLocalSnapshot,
12717
- persistLocalSnapshot: () => persistLocalSnapshot,
12718
- shouldReindex: () => shouldReindex,
12719
- snapshotPath: () => snapshotPath
12720
- });
12721
- import {
12722
- existsSync as existsSync33,
12723
- mkdirSync as mkdirSync18,
12724
- readFileSync as readFileSync29,
12725
- readdirSync as readdirSync7,
12726
- statSync as statSync6,
12727
- writeFileSync as writeFileSync12
12728
- } from "fs";
12729
- import { join as join39 } from "path";
12730
- function snapshotPath(projectRoot) {
12731
- return join39(projectRoot, ".unerr", "snapshots", SNAPSHOT_FILENAME);
12732
- }
12733
- function getSnapshotMeta(projectRoot) {
12734
- const path7 = snapshotPath(projectRoot);
12735
- return { path: path7, exists: existsSync33(path7) };
12736
- }
12737
- function shouldReindex(projectRoot) {
12738
- const dbPath = join39(projectRoot, ".unerr", "graph.db");
12739
- const snPath = snapshotPath(projectRoot);
12740
- let referenceMtime = null;
12741
- if (existsSync33(dbPath)) {
12742
- try {
12743
- referenceMtime = statSync6(dbPath).mtimeMs;
12744
- } catch {
12745
- }
12746
- }
12747
- if (referenceMtime === null && existsSync33(snPath)) {
12748
- try {
12749
- referenceMtime = statSync6(snPath).mtimeMs;
12750
- } catch {
12751
- }
12752
- }
12753
- if (referenceMtime === null) return true;
12754
- return hasNewerSource(projectRoot, referenceMtime);
12755
- }
12756
- async function persistLocalSnapshot(projectRoot, repoId, entities, edges) {
12757
- const snapshotsDir = join39(projectRoot, ".unerr", "snapshots");
12758
- mkdirSync18(snapshotsDir, { recursive: true });
12759
- const envelope = {
12760
- version: 1,
12761
- repoId,
12762
- orgId: "local",
12763
- entities,
12764
- edges,
12765
- generatedAt: (/* @__PURE__ */ new Date()).toISOString()
12766
- };
12767
- const { pack } = await import("msgpackr");
12768
- const { gzipSync: gzipSync3 } = await import("zlib");
12769
- const packed = pack(envelope);
12770
- const compressed = gzipSync3(packed);
12771
- const path7 = snapshotPath(projectRoot);
12772
- writeFileSync12(path7, compressed);
12773
- return path7;
12774
- }
12775
- async function loadLocalSnapshot(projectRoot, graphStore) {
12776
- const path7 = snapshotPath(projectRoot);
12777
- if (!existsSync33(path7)) return false;
12778
- try {
12779
- const { unpack } = await import("msgpackr");
12780
- const { gunzipSync: gunzipSync3 } = await import("zlib");
12781
- const raw = readFileSync29(path7);
12782
- const buffer = gunzipSync3(raw);
12783
- const envelope = unpack(buffer);
12784
- await graphStore.loadSnapshot(envelope);
12785
- return true;
12786
- } catch {
12787
- return false;
12788
- }
12789
- }
12790
- function hasNewerSource(projectRoot, snapshotMtime) {
12791
- return scanDirForNewer(projectRoot, snapshotMtime);
12792
- }
12793
- function scanDirForNewer(dir, threshold) {
12794
- let entries;
12795
- try {
12796
- entries = readdirSync7(dir);
12797
- } catch {
12798
- return false;
12799
- }
12800
- for (const entry of entries) {
12801
- if (EXCLUDED_DIRS.has(entry)) continue;
12802
- if (entry.startsWith(".") && entry !== ".") continue;
12803
- const fullPath = join39(dir, entry);
12804
- let stat2;
12805
- try {
12806
- stat2 = statSync6(fullPath);
12807
- } catch {
12808
- continue;
12809
- }
12810
- if (stat2.isDirectory()) {
12811
- if (scanDirForNewer(fullPath, threshold)) return true;
12812
- } else if (stat2.isFile()) {
12813
- const ext = fullPath.slice(fullPath.lastIndexOf(".")).toLowerCase();
12814
- if (SOURCE_EXTENSIONS.has(ext) && stat2.mtimeMs > threshold) {
12815
- return true;
12816
- }
12817
- }
12818
- }
12819
- return false;
12820
- }
12821
- var SNAPSHOT_FILENAME, SOURCE_EXTENSIONS, EXCLUDED_DIRS;
12822
- var init_local_snapshot = __esm({
12823
- "src/intelligence/local-snapshot.ts"() {
12824
- "use strict";
12825
- SNAPSHOT_FILENAME = "graph.msgpack.gz";
12826
- SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
12827
- ".ts",
12828
- ".tsx",
12829
- ".js",
12830
- ".jsx",
12831
- ".mjs",
12832
- ".cjs",
12833
- ".py",
12834
- ".go",
12835
- ".java",
12836
- ".rs",
12837
- ".c",
12838
- ".h",
12839
- ".cpp",
12840
- ".cc",
12841
- ".cxx",
12842
- ".hpp"
12843
- ]);
12844
- EXCLUDED_DIRS = /* @__PURE__ */ new Set([
12845
- "node_modules",
12846
- "dist",
12847
- "build",
12848
- "out",
12849
- ".git",
12850
- ".hg",
12851
- ".svn",
12852
- "coverage",
12853
- "__pycache__",
12854
- ".mypy_cache",
12855
- ".pytest_cache",
12856
- "vendor",
12857
- "target",
12858
- ".next",
12859
- ".nuxt",
12860
- ".output",
12861
- ".unerr",
12862
- ".cache",
12863
- ".turbo",
12864
- ".parcel-cache"
12865
- ]);
12866
- }
12867
- });
12868
-
12869
12869
  // src/utils/format-error.ts
12870
12870
  function formatUnknownError(err2) {
12871
12871
  if (err2 instanceof Error) return err2.stack ?? err2.message;
@@ -58513,58 +58513,44 @@ function registerBranchesCommand(program2) {
58513
58513
  init_git_review();
58514
58514
  import {
58515
58515
  appendFileSync as appendFileSync2,
58516
- existsSync as existsSync7,
58517
- mkdirSync as mkdirSync4,
58518
- readFileSync as readFileSync6,
58516
+ existsSync as existsSync8,
58517
+ mkdirSync as mkdirSync5,
58518
+ readFileSync as readFileSync7,
58519
58519
  rmSync,
58520
- writeFileSync as writeFileSync2
58520
+ writeFileSync as writeFileSync3
58521
58521
  } from "fs";
58522
- import { join as join9 } from "path";
58522
+ import { join as join10 } from "path";
58523
58523
  import pc2 from "picocolors";
58524
58524
 
58525
58525
  // src/review/standalone-load.ts
58526
+ init_local_snapshot();
58526
58527
  init_git_review();
58527
- import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
58528
- import { join as join6 } from "path";
58529
- import { gunzipSync } from "zlib";
58528
+ import { existsSync as existsSync6, readFileSync as readFileSync5 } from "fs";
58529
+ import { join as join7 } from "path";
58530
58530
  async function loadStandaloneGraph(cwd) {
58531
- const configPath2 = join6(cwd, ".unerr", "config.json");
58532
- if (!existsSync5(configPath2)) return null;
58533
- let repoId;
58531
+ const configPath2 = join7(cwd, ".unerr", "config.json");
58532
+ if (!existsSync6(configPath2)) return null;
58534
58533
  try {
58535
- const config = JSON.parse(readFileSync4(configPath2, "utf-8"));
58534
+ const config = JSON.parse(readFileSync5(configPath2, "utf-8"));
58536
58535
  if (!config.repoId) return null;
58537
- repoId = config.repoId;
58538
58536
  } catch {
58539
58537
  return null;
58540
58538
  }
58541
- const snapshotsDir = join6(cwd, ".unerr", "snapshots");
58542
- const manifestsDir = join6(cwd, ".unerr", "manifests");
58543
- const manifestPath = join6(manifestsDir, `${repoId}.json`);
58544
- if (!existsSync5(manifestPath)) return null;
58545
- let snapshotPath2 = join6(snapshotsDir, `${repoId}.msgpack.gz`);
58546
- if (!existsSync5(snapshotPath2)) {
58547
- snapshotPath2 = join6(snapshotsDir, `${repoId}.msgpack`);
58548
- }
58549
- if (!existsSync5(snapshotPath2)) return null;
58550
58539
  try {
58551
- const { default: CozoDbConstructor } = await import("cozo-node");
58540
+ const cozoModule = await import("cozo-node");
58552
58541
  const { CozoGraphStore: CozoGraphStore2 } = await Promise.resolve().then(() => (init_local_graph(), local_graph_exports));
58553
- const { unpack } = await import("msgpackr");
58542
+ const CozoDbConstructor = cozoModule.default ? cozoModule.default.CozoDb : cozoModule.CozoDb;
58554
58543
  const db = new CozoDbConstructor();
58555
58544
  const graph = await CozoGraphStore2.create(db);
58556
- const raw = readFileSync4(snapshotPath2);
58557
- const buffer = snapshotPath2.endsWith(".gz") ? gunzipSync(raw) : raw;
58558
- const envelope = unpack(buffer);
58559
- await graph.loadSnapshot(envelope);
58560
- return graph;
58545
+ const loaded = await loadLocalSnapshot(cwd, graph);
58546
+ return loaded ? graph : null;
58561
58547
  } catch {
58562
58548
  return null;
58563
58549
  }
58564
58550
  }
58565
58551
  async function loadStandaloneNotes(cwd, sessionId = "review") {
58566
- const factsDbPath = join6(cwd, ".unerr", "facts.db");
58567
- if (!existsSync5(factsDbPath)) return null;
58552
+ const factsDbPath = join7(cwd, ".unerr", "facts.db");
58553
+ if (!existsSync6(factsDbPath)) return null;
58568
58554
  try {
58569
58555
  const { TemporalFactStore: TemporalFactStore2 } = await Promise.resolve().then(() => (init_temporal_facts(), temporal_facts_exports));
58570
58556
  const { NotesStore: NotesStore2 } = await Promise.resolve().then(() => (init_notes_store(), notes_store_exports));
@@ -58580,8 +58566,8 @@ init_types();
58580
58566
  init_git();
58581
58567
 
58582
58568
  // src/utils/log.ts
58583
- import { appendFileSync, mkdirSync as mkdirSync3 } from "fs";
58584
- import { join as join7 } from "path";
58569
+ import { appendFileSync, mkdirSync as mkdirSync4 } from "fs";
58570
+ import { join as join8 } from "path";
58585
58571
  var logFilePath = null;
58586
58572
  function timestamp() {
58587
58573
  return (/* @__PURE__ */ new Date()).toISOString();
@@ -58642,24 +58628,24 @@ function registerCheckCommitCommand(program2) {
58642
58628
  return;
58643
58629
  }
58644
58630
  let blockingMode = opts.blocking ?? false;
58645
- const settingsPath = join9(cwd, ".unerr", "settings.json");
58646
- if (!blockingMode && existsSync7(settingsPath)) {
58631
+ const settingsPath = join10(cwd, ".unerr", "settings.json");
58632
+ if (!blockingMode && existsSync8(settingsPath)) {
58647
58633
  try {
58648
58634
  const settings = JSON.parse(
58649
- readFileSync6(settingsPath, "utf-8")
58635
+ readFileSync7(settingsPath, "utf-8")
58650
58636
  );
58651
58637
  blockingMode = settings.hooks?.precommit?.blocking ?? false;
58652
58638
  } catch {
58653
58639
  }
58654
58640
  }
58655
58641
  logInfo("check-commit invoked", { blocking: blockingMode });
58656
- const configPath2 = join9(cwd, ".unerr", "config.json");
58657
- if (!existsSync7(configPath2)) {
58642
+ const configPath2 = join10(cwd, ".unerr", "config.json");
58643
+ if (!existsSync8(configPath2)) {
58658
58644
  logInfo("check-commit: no .unerr/config.json, skipping");
58659
58645
  return;
58660
58646
  }
58661
58647
  try {
58662
- const config = JSON.parse(readFileSync6(configPath2, "utf-8"));
58648
+ const config = JSON.parse(readFileSync7(configPath2, "utf-8"));
58663
58649
  if (!config.repoId) {
58664
58650
  logInfo("check-commit: no repoId in config, skipping");
58665
58651
  return;
@@ -58753,7 +58739,7 @@ function renderFinding(f, verbose) {
58753
58739
  detail(` \u2192 ${f.action}`);
58754
58740
  }
58755
58741
  function verdictStatePath(cwd) {
58756
- return join9(cwd, ".unerr", "state", "review-verdict.json");
58742
+ return join10(cwd, ".unerr", "state", "review-verdict.json");
58757
58743
  }
58758
58744
  function persistVerdict(cwd, report, blocking, verdict) {
58759
58745
  const pending = {
@@ -58765,16 +58751,16 @@ function persistVerdict(cwd, report, blocking, verdict) {
58765
58751
  staged_at: (/* @__PURE__ */ new Date()).toISOString()
58766
58752
  };
58767
58753
  try {
58768
- const stateDir = join9(cwd, ".unerr", "state");
58769
- mkdirSync4(stateDir, { recursive: true });
58770
- writeFileSync2(verdictStatePath(cwd), JSON.stringify(pending), "utf-8");
58754
+ const stateDir = join10(cwd, ".unerr", "state");
58755
+ mkdirSync5(stateDir, { recursive: true });
58756
+ writeFileSync3(verdictStatePath(cwd), JSON.stringify(pending), "utf-8");
58771
58757
  } catch {
58772
58758
  }
58773
58759
  try {
58774
- const logsDir = join9(cwd, ".unerr", "logs");
58775
- mkdirSync4(logsDir, { recursive: true });
58760
+ const logsDir = join10(cwd, ".unerr", "logs");
58761
+ mkdirSync5(logsDir, { recursive: true });
58776
58762
  appendFileSync2(
58777
- join9(logsDir, "review-verdicts.jsonl"),
58763
+ join10(logsDir, "review-verdicts.jsonl"),
58778
58764
  `${JSON.stringify(pending)}
58779
58765
  `,
58780
58766
  "utf-8"
@@ -58784,10 +58770,10 @@ function persistVerdict(cwd, report, blocking, verdict) {
58784
58770
  }
58785
58771
  async function recordPendingVerdict(cwd) {
58786
58772
  const statePath2 = verdictStatePath(cwd);
58787
- if (!existsSync7(statePath2)) return;
58773
+ if (!existsSync8(statePath2)) return;
58788
58774
  let pending;
58789
58775
  try {
58790
- pending = JSON.parse(readFileSync6(statePath2, "utf-8"));
58776
+ pending = JSON.parse(readFileSync7(statePath2, "utf-8"));
58791
58777
  } catch {
58792
58778
  try {
58793
58779
  rmSync(statePath2, { force: true });
@@ -58823,19 +58809,19 @@ async function recordPendingVerdict(cwd) {
58823
58809
 
58824
58810
  // src/commands/compress-output.ts
58825
58811
  init_output_compressor();
58826
- import { existsSync as existsSync8, readFileSync as readFileSync7 } from "fs";
58827
- import { join as join10 } from "path";
58812
+ import { existsSync as existsSync9, readFileSync as readFileSync8 } from "fs";
58813
+ import { join as join11 } from "path";
58828
58814
  function loadEntityRiskMap(cwd) {
58829
58815
  const riskMap = /* @__PURE__ */ new Map();
58830
58816
  try {
58831
- const unerrDir2 = join10(cwd, ".unerr");
58832
- const configPath2 = join10(unerrDir2, "config.json");
58833
- if (!existsSync8(configPath2)) return riskMap;
58834
- const config = JSON.parse(readFileSync7(configPath2, "utf-8"));
58817
+ const unerrDir2 = join11(cwd, ".unerr");
58818
+ const configPath2 = join11(unerrDir2, "config.json");
58819
+ if (!existsSync9(configPath2)) return riskMap;
58820
+ const config = JSON.parse(readFileSync8(configPath2, "utf-8"));
58835
58821
  if (!config.repoId) return riskMap;
58836
- const riskCachePath = join10(unerrDir2, "state", "entity_risk_cache.json");
58837
- if (!existsSync8(riskCachePath)) return riskMap;
58838
- const data = JSON.parse(readFileSync7(riskCachePath, "utf-8"));
58822
+ const riskCachePath = join11(unerrDir2, "state", "entity_risk_cache.json");
58823
+ if (!existsSync9(riskCachePath)) return riskMap;
58824
+ const data = JSON.parse(readFileSync8(riskCachePath, "utf-8"));
58839
58825
  for (const [key, info2] of Object.entries(data)) {
58840
58826
  riskMap.set(key, info2);
58841
58827
  }
@@ -58872,13 +58858,13 @@ init_config_verify();
58872
58858
  init_exec();
58873
58859
  init_git();
58874
58860
  init_startup_log();
58875
- import { existsSync as existsSync13, readFileSync as readFileSync11 } from "fs";
58876
- import { join as join15 } from "path";
58861
+ import { existsSync as existsSync14, readFileSync as readFileSync12 } from "fs";
58862
+ import { join as join16 } from "path";
58877
58863
  function readServerJson(cwd) {
58878
- const p = join15(cwd, ".unerr", "state", "server.json");
58879
- if (!existsSync13(p)) return null;
58864
+ const p = join16(cwd, ".unerr", "state", "server.json");
58865
+ if (!existsSync14(p)) return null;
58880
58866
  try {
58881
- const raw = readFileSync11(p, "utf-8");
58867
+ const raw = readFileSync12(p, "utf-8");
58882
58868
  return JSON.parse(raw);
58883
58869
  } catch {
58884
58870
  return null;
@@ -58917,10 +58903,10 @@ function registerDashboardCommand(program2) {
58917
58903
 
58918
58904
  // src/commands/debug.ts
58919
58905
  init_git();
58920
- import { existsSync as existsSync14, readFileSync as readFileSync12, readdirSync as readdirSync4, statSync as statSync3 } from "fs";
58906
+ import { existsSync as existsSync15, readFileSync as readFileSync13, readdirSync as readdirSync5, statSync as statSync4 } from "fs";
58921
58907
  import { arch, homedir as homedir3, platform, release } from "os";
58922
- import { join as join16 } from "path";
58923
- var UNERR_DIR = join16(homedir3(), ".unerr");
58908
+ import { join as join17 } from "path";
58909
+ var UNERR_DIR = join17(homedir3(), ".unerr");
58924
58910
  function registerDebugCommand(program2) {
58925
58911
  program2.command("debug").description("Diagnostics dump for support").action(async () => {
58926
58912
  const sections = [];
@@ -58931,11 +58917,11 @@ function registerDebugCommand(program2) {
58931
58917
  sections.push(" CLI: 0.1.0");
58932
58918
  sections.push("");
58933
58919
  sections.push("## Settings");
58934
- const settingsPath = join16(UNERR_DIR, "settings.json");
58935
- if (existsSync14(settingsPath)) {
58920
+ const settingsPath = join17(UNERR_DIR, "settings.json");
58921
+ if (existsSync15(settingsPath)) {
58936
58922
  try {
58937
58923
  const settings = JSON.parse(
58938
- readFileSync12(settingsPath, "utf-8")
58924
+ readFileSync13(settingsPath, "utf-8")
58939
58925
  );
58940
58926
  for (const [key, value] of Object.entries(settings)) {
58941
58927
  if (key === "anthropicApiKey" && typeof value === "string") {
@@ -58959,11 +58945,11 @@ function registerDebugCommand(program2) {
58959
58945
  sections.push(` Branch: ${branch ?? "(detached)"}`);
58960
58946
  sections.push("");
58961
58947
  sections.push("## Project Config (.unerr/config.json)");
58962
- const configPath2 = join16(process.cwd(), ".unerr", "config.json");
58963
- if (existsSync14(configPath2)) {
58948
+ const configPath2 = join17(process.cwd(), ".unerr", "config.json");
58949
+ if (existsSync15(configPath2)) {
58964
58950
  try {
58965
58951
  const config = JSON.parse(
58966
- readFileSync12(configPath2, "utf-8")
58952
+ readFileSync13(configPath2, "utf-8")
58967
58953
  );
58968
58954
  for (const [key, value] of Object.entries(config)) {
58969
58955
  sections.push(` ${key}: ${String(value)}`);
@@ -58976,11 +58962,11 @@ function registerDebugCommand(program2) {
58976
58962
  }
58977
58963
  sections.push("");
58978
58964
  sections.push("## Proxy Status");
58979
- const pidPath2 = join16(process.cwd(), ".unerr", "state", "proxy.pid");
58980
- if (existsSync14(pidPath2)) {
58965
+ const pidPath2 = join17(process.cwd(), ".unerr", "state", "proxy.pid");
58966
+ if (existsSync15(pidPath2)) {
58981
58967
  try {
58982
58968
  const pid = Number.parseInt(
58983
- readFileSync12(pidPath2, "utf-8").trim(),
58969
+ readFileSync13(pidPath2, "utf-8").trim(),
58984
58970
  10
58985
58971
  );
58986
58972
  let alive = false;
@@ -58998,23 +58984,23 @@ function registerDebugCommand(program2) {
58998
58984
  }
58999
58985
  sections.push("");
59000
58986
  sections.push("## .unerr/ Directory (repo-local)");
59001
- const localUnerrDir = join16(process.cwd(), ".unerr");
59002
- if (existsSync14(localUnerrDir)) {
58987
+ const localUnerrDir = join17(process.cwd(), ".unerr");
58988
+ if (existsSync15(localUnerrDir)) {
59003
58989
  listDir(localUnerrDir, " ", sections, 0, 2);
59004
58990
  } else {
59005
58991
  sections.push(" (not found)");
59006
58992
  }
59007
58993
  sections.push("");
59008
58994
  sections.push("## Snapshots");
59009
- const snapshotsDir = join16(localUnerrDir, "snapshots");
59010
- if (existsSync14(snapshotsDir)) {
59011
- const files = readdirSync4(snapshotsDir);
58995
+ const snapshotsDir = join17(localUnerrDir, "snapshots");
58996
+ if (existsSync15(snapshotsDir)) {
58997
+ const files = readdirSync5(snapshotsDir);
59012
58998
  if (files.length === 0) {
59013
58999
  sections.push(" (empty)");
59014
59000
  }
59015
59001
  for (const file of files) {
59016
- const filePath = join16(snapshotsDir, file);
59017
- const stat2 = statSync3(filePath);
59002
+ const filePath = join17(snapshotsDir, file);
59003
+ const stat2 = statSync4(filePath);
59018
59004
  sections.push(` ${file}: ${formatBytes(stat2.size)}`);
59019
59005
  }
59020
59006
  } else {
@@ -59023,10 +59009,10 @@ function registerDebugCommand(program2) {
59023
59009
  sections.push("");
59024
59010
  sections.push("## MCP Config Locations");
59025
59011
  const mcpLocations = [
59026
- join16(process.cwd(), ".cursor", "mcp.json"),
59027
- join16(process.cwd(), ".vscode", "mcp.json"),
59028
- join16(homedir3(), ".claude", "claude_desktop_config.json"),
59029
- join16(
59012
+ join17(process.cwd(), ".cursor", "mcp.json"),
59013
+ join17(process.cwd(), ".vscode", "mcp.json"),
59014
+ join17(homedir3(), ".claude", "claude_desktop_config.json"),
59015
+ join17(
59030
59016
  homedir3(),
59031
59017
  "Library",
59032
59018
  "Application Support",
@@ -59038,20 +59024,20 @@ function registerDebugCommand(program2) {
59038
59024
  )
59039
59025
  ];
59040
59026
  for (const loc of mcpLocations) {
59041
- const exists = existsSync14(loc);
59027
+ const exists = existsSync15(loc);
59042
59028
  sections.push(
59043
59029
  ` ${exists ? "[x]" : "[ ]"} ${loc.replace(homedir3(), "~")}`
59044
59030
  );
59045
59031
  }
59046
59032
  sections.push("");
59047
59033
  sections.push("## Recent Log (last 20 lines)");
59048
- const logsDir = join16(process.cwd(), ".unerr", "logs");
59049
- if (existsSync14(logsDir)) {
59050
- const logFiles = readdirSync4(logsDir).filter((f) => f.endsWith(".log")).sort().reverse();
59034
+ const logsDir = join17(process.cwd(), ".unerr", "logs");
59035
+ if (existsSync15(logsDir)) {
59036
+ const logFiles = readdirSync5(logsDir).filter((f) => f.endsWith(".log")).sort().reverse();
59051
59037
  if (logFiles.length > 0 && logFiles[0]) {
59052
- const logPath = join16(logsDir, logFiles[0]);
59038
+ const logPath = join17(logsDir, logFiles[0]);
59053
59039
  try {
59054
- const content = readFileSync12(logPath, "utf-8");
59040
+ const content = readFileSync13(logPath, "utf-8");
59055
59041
  const lines = content.split("\n").filter(Boolean);
59056
59042
  const last20 = lines.slice(-20);
59057
59043
  for (const line of last20) {
@@ -59077,19 +59063,19 @@ function formatBytes(bytes) {
59077
59063
  function listDir(dirPath, indent, out, depth, maxDepth) {
59078
59064
  if (depth > maxDepth) return;
59079
59065
  try {
59080
- const entries = readdirSync4(dirPath, { withFileTypes: true });
59066
+ const entries = readdirSync5(dirPath, { withFileTypes: true });
59081
59067
  for (const entry of entries) {
59082
59068
  if (entry.isDirectory()) {
59083
59069
  out.push(`${indent}${entry.name}/`);
59084
59070
  listDir(
59085
- join16(dirPath, entry.name),
59071
+ join17(dirPath, entry.name),
59086
59072
  `${indent} `,
59087
59073
  out,
59088
59074
  depth + 1,
59089
59075
  maxDepth
59090
59076
  );
59091
59077
  } else {
59092
- const size = formatBytes(statSync3(join16(dirPath, entry.name)).size);
59078
+ const size = formatBytes(statSync4(join17(dirPath, entry.name)).size);
59093
59079
  out.push(`${indent}${entry.name} (${size})`);
59094
59080
  }
59095
59081
  }
@@ -59104,14 +59090,14 @@ import { execSync as execSync2 } from "child_process";
59104
59090
  import {
59105
59091
  accessSync,
59106
59092
  appendFileSync as appendFileSync5,
59107
- existsSync as existsSync15,
59093
+ existsSync as existsSync16,
59108
59094
  constants as fsConstants,
59109
- mkdirSync as mkdirSync8,
59110
- readFileSync as readFileSync13
59095
+ mkdirSync as mkdirSync9,
59096
+ readFileSync as readFileSync14
59111
59097
  } from "fs";
59112
59098
  import { createServer } from "net";
59113
59099
  import { homedir as homedir4 } from "os";
59114
- import { dirname as dirname6, join as join17, normalize } from "path";
59100
+ import { dirname as dirname6, join as join18, normalize } from "path";
59115
59101
  import { createInterface } from "readline";
59116
59102
  var hasTTY = !!process.stderr.isTTY;
59117
59103
  var W = hasTTY ? "\x1B[33m" : "";
@@ -59145,7 +59131,7 @@ function getGlobalBin() {
59145
59131
  timeout: 5e3,
59146
59132
  stdio: ["pipe", "pipe", "pipe"]
59147
59133
  }).trim();
59148
- return isWin ? prefix : join17(prefix, "bin");
59134
+ return isWin ? prefix : join18(prefix, "bin");
59149
59135
  } catch {
59150
59136
  return "";
59151
59137
  }
@@ -59163,30 +59149,30 @@ function getRcPath(shell) {
59163
59149
  const home = homedir4();
59164
59150
  switch (shell) {
59165
59151
  case "zsh":
59166
- return join17(home, ".zshrc");
59152
+ return join18(home, ".zshrc");
59167
59153
  case "fish":
59168
- return join17(home, ".config", "fish", "config.fish");
59154
+ return join18(home, ".config", "fish", "config.fish");
59169
59155
  case "bash":
59170
- return join17(home, ".bashrc");
59156
+ return join18(home, ".bashrc");
59171
59157
  case "powershell": {
59172
- const docs = process.env.USERPROFILE ? join17(process.env.USERPROFILE, "Documents") : join17(home, "Documents");
59173
- const ps7Profile = join17(
59158
+ const docs = process.env.USERPROFILE ? join18(process.env.USERPROFILE, "Documents") : join18(home, "Documents");
59159
+ const ps7Profile = join18(
59174
59160
  docs,
59175
59161
  "PowerShell",
59176
59162
  "Microsoft.PowerShell_profile.ps1"
59177
59163
  );
59178
- const ps5Profile = join17(
59164
+ const ps5Profile = join18(
59179
59165
  docs,
59180
59166
  "WindowsPowerShell",
59181
59167
  "Microsoft.PowerShell_profile.ps1"
59182
59168
  );
59183
- if (existsSync15(dirname6(ps7Profile))) return ps7Profile;
59169
+ if (existsSync16(dirname6(ps7Profile))) return ps7Profile;
59184
59170
  return ps5Profile;
59185
59171
  }
59186
59172
  case "cmd":
59187
- return join17(home, ".unerr-path.cmd");
59173
+ return join18(home, ".unerr-path.cmd");
59188
59174
  default:
59189
- return join17(home, ".bashrc");
59175
+ return join18(home, ".bashrc");
59190
59176
  }
59191
59177
  }
59192
59178
  function getRcDisplayName(shell) {
@@ -59300,8 +59286,8 @@ function getFixPayload(shell, globalBin) {
59300
59286
  };
59301
59287
  }
59302
59288
  function isAlreadyInRc(rcPath, fix) {
59303
- if (!existsSync15(rcPath)) return false;
59304
- const content = readFileSync13(rcPath, "utf-8");
59289
+ if (!existsSync16(rcPath)) return false;
59290
+ const content = readFileSync14(rcPath, "utf-8");
59305
59291
  const meaningful = fix.lines.filter(
59306
59292
  (l) => l.trim() && !l.trim().startsWith("#") && !l.trim().startsWith("::")
59307
59293
  );
@@ -59345,8 +59331,8 @@ function applyFix(shell, rcPath, rcName, fix, globalBin) {
59345
59331
  );
59346
59332
  } else {
59347
59333
  const dir = dirname6(rcPath);
59348
- if (!existsSync15(dir)) {
59349
- mkdirSync8(dir, { recursive: true });
59334
+ if (!existsSync16(dir)) {
59335
+ mkdirSync9(dir, { recursive: true });
59350
59336
  }
59351
59337
  appendFileSync5(rcPath, `${fix.lines.join("\n")}
59352
59338
  `, "utf-8");
@@ -59672,9 +59658,9 @@ Recommended: open a shell using your default node, then \`npm i -g @unerr-ai/une
59672
59658
  };
59673
59659
  }
59674
59660
  function checkUnerrDirAccess() {
59675
- const dir = join17(homedir4(), ".unerr");
59661
+ const dir = join18(homedir4(), ".unerr");
59676
59662
  try {
59677
- mkdirSync8(dir, { recursive: true });
59663
+ mkdirSync9(dir, { recursive: true });
59678
59664
  } catch (err2) {
59679
59665
  const msg = err2 instanceof Error ? err2.message : String(err2);
59680
59666
  return {
@@ -60120,7 +60106,7 @@ init_nudge_state();
60120
60106
  // src/proxy/shell-compressor.ts
60121
60107
  init_token_flow();
60122
60108
  init_detect();
60123
- import { readFileSync as readFileSync18 } from "fs";
60109
+ import { readFileSync as readFileSync19 } from "fs";
60124
60110
 
60125
60111
  // src/proxy/shell-classifier.ts
60126
60112
  var COMMAND_HINTS = {
@@ -61496,10 +61482,10 @@ async function tryLoadGraphForShellBoost(cwd) {
61496
61482
  }
61497
61483
  let buffer;
61498
61484
  try {
61499
- const { gunzipSync: gunzipSync3 } = await import("zlib");
61485
+ const { gunzipSync: gunzipSync2 } = await import("zlib");
61500
61486
  const raw = readFileSync89(snapshotPath2);
61501
61487
  try {
61502
- buffer = gunzipSync3(raw);
61488
+ buffer = gunzipSync2(raw);
61503
61489
  } catch {
61504
61490
  buffer = raw;
61505
61491
  }
@@ -62562,15 +62548,15 @@ function compressErrorDiagnostic(raw, command) {
62562
62548
  }
62563
62549
 
62564
62550
  // src/proxy/shell-strategies/filter-dsl.ts
62565
- import { existsSync as existsSync20, readFileSync as readFileSync17 } from "fs";
62551
+ import { existsSync as existsSync21, readFileSync as readFileSync18 } from "fs";
62566
62552
  import { homedir as homedir6 } from "os";
62567
- import { join as join24 } from "path";
62553
+ import { join as join25 } from "path";
62568
62554
  var cachedFilters = null;
62569
62555
  var cacheKey = "";
62570
62556
  function readFile(path7) {
62571
62557
  try {
62572
- if (!existsSync20(path7)) return null;
62573
- return readFileSync17(path7, "utf8");
62558
+ if (!existsSync21(path7)) return null;
62559
+ return readFileSync18(path7, "utf8");
62574
62560
  } catch {
62575
62561
  return null;
62576
62562
  }
@@ -62750,8 +62736,8 @@ function compileOne(name, raw) {
62750
62736
  };
62751
62737
  }
62752
62738
  function loadFilters(cwd) {
62753
- const repoPath = join24(cwd, ".unerr", "filters.toml");
62754
- const userPath = join24(homedir6(), ".config", "unerr", "filters.toml");
62739
+ const repoPath = join25(cwd, ".unerr", "filters.toml");
62740
+ const userPath = join25(homedir6(), ".config", "unerr", "filters.toml");
62755
62741
  const key = `${repoPath}|${userPath}`;
62756
62742
  if (cachedFilters && cacheKey === key) return cachedFilters;
62757
62743
  const sources = [readFile(repoPath), readFile(userPath)].filter(
@@ -64848,13 +64834,13 @@ ${clipped}`;
64848
64834
 
64849
64835
  // src/proxy/shell-tee.ts
64850
64836
  import {
64851
- mkdirSync as mkdirSync13,
64852
- readdirSync as readdirSync5,
64853
- statSync as statSync5,
64837
+ mkdirSync as mkdirSync14,
64838
+ readdirSync as readdirSync6,
64839
+ statSync as statSync6,
64854
64840
  unlinkSync as unlinkSync3,
64855
- writeFileSync as writeFileSync8
64841
+ writeFileSync as writeFileSync9
64856
64842
  } from "fs";
64857
- import { join as join25 } from "path";
64843
+ import { join as join26 } from "path";
64858
64844
  var MAX_TEE_FILES = 50;
64859
64845
  var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
64860
64846
  function commandSlug(cmd) {
@@ -64863,15 +64849,15 @@ function commandSlug(cmd) {
64863
64849
  function teeShellOutput(cwd, command, raw, compressed) {
64864
64850
  const ratio2 = 1 - compressed.length / raw.length;
64865
64851
  if (ratio2 < 0.3 || raw.length < 1024) return null;
64866
- const teeDir = join25(cwd, ".unerr", "tee");
64852
+ const teeDir = join26(cwd, ".unerr", "tee");
64867
64853
  try {
64868
- mkdirSync13(teeDir, { recursive: true });
64854
+ mkdirSync14(teeDir, { recursive: true });
64869
64855
  } catch {
64870
64856
  }
64871
64857
  const slug = commandSlug(command);
64872
64858
  const ts = Date.now();
64873
64859
  const filename = `${ts}-${slug}.txt`;
64874
- const filePath = join25(teeDir, filename);
64860
+ const filePath = join26(teeDir, filename);
64875
64861
  const header = [
64876
64862
  "# unerr tee \u2014 full shell output",
64877
64863
  `# command: ${command}`,
@@ -64882,7 +64868,7 @@ function teeShellOutput(cwd, command, raw, compressed) {
64882
64868
  ].join("\n");
64883
64869
  const content = header + raw;
64884
64870
  try {
64885
- writeFileSync8(filePath, content, "utf8");
64871
+ writeFileSync9(filePath, content, "utf8");
64886
64872
  } catch {
64887
64873
  return null;
64888
64874
  }
@@ -64893,10 +64879,10 @@ function cleanupOldTees(teeDir, maxAgeMs = MAX_AGE_MS) {
64893
64879
  let deleted = 0;
64894
64880
  let entries = [];
64895
64881
  try {
64896
- entries = readdirSync5(teeDir).filter((f) => f.endsWith(".txt")).map((name) => {
64897
- const p = join25(teeDir, name);
64882
+ entries = readdirSync6(teeDir).filter((f) => f.endsWith(".txt")).map((name) => {
64883
+ const p = join26(teeDir, name);
64898
64884
  try {
64899
- const { mtimeMs } = statSync5(p);
64885
+ const { mtimeMs } = statSync6(p);
64900
64886
  return { name, mtime: mtimeMs, path: p };
64901
64887
  } catch {
64902
64888
  return { name, mtime: 0, path: p };
@@ -65289,7 +65275,7 @@ function recordShellTokenFlow(cwd, command, category, raw, compressed, strategy)
65289
65275
  const unerrDir2 = `${cwd}/.unerr`;
65290
65276
  if (!sessionId) {
65291
65277
  try {
65292
- sessionId = readFileSync18(
65278
+ sessionId = readFileSync19(
65293
65279
  `${unerrDir2}/state/session.id`,
65294
65280
  "utf-8"
65295
65281
  ).trim();
@@ -65497,8 +65483,8 @@ function registerExecCommand(program2) {
65497
65483
  }
65498
65484
 
65499
65485
  // src/commands/gain.ts
65500
- import { existsSync as existsSync21, readFileSync as readFileSync19 } from "fs";
65501
- import { join as join26 } from "path";
65486
+ import { existsSync as existsSync22, readFileSync as readFileSync20 } from "fs";
65487
+ import { join as join27 } from "path";
65502
65488
  var PALETTE = {
65503
65489
  reset: "\x1B[0m",
65504
65490
  violet: "\x1B[38;2;139;92;246m",
@@ -65510,9 +65496,9 @@ var PALETTE = {
65510
65496
  bold: "\x1B[1m"
65511
65497
  };
65512
65498
  function loadFlow(cwd) {
65513
- const path7 = join26(cwd, ".unerr", "token-flow.jsonl");
65514
- if (!existsSync21(path7)) return [];
65515
- const raw = readFileSync19(path7, "utf8");
65499
+ const path7 = join27(cwd, ".unerr", "token-flow.jsonl");
65500
+ if (!existsSync22(path7)) return [];
65501
+ const raw = readFileSync20(path7, "utf8");
65516
65502
  const events = [];
65517
65503
  for (const line of raw.split("\n")) {
65518
65504
  if (!line.trim()) continue;
@@ -65636,11 +65622,11 @@ function registerDiscoverCommand(program2) {
65636
65622
  }
65637
65623
 
65638
65624
  // src/commands/hook.ts
65639
- import { readFileSync as readFileSync28 } from "fs";
65625
+ import { readFileSync as readFileSync29 } from "fs";
65640
65626
 
65641
65627
  // src/hooks/navigation-hooks.ts
65642
65628
  init_cochange_index();
65643
- import { join as join30 } from "path";
65629
+ import { join as join31 } from "path";
65644
65630
 
65645
65631
  // src/review/format.ts
65646
65632
  init_types();
@@ -65671,17 +65657,17 @@ init_session_edit_log();
65671
65657
 
65672
65658
  // src/hooks/blast-radius-client.ts
65673
65659
  init_blast_radius_protocol();
65674
- import { existsSync as existsSync23 } from "fs";
65660
+ import { existsSync as existsSync24 } from "fs";
65675
65661
  import { connect } from "net";
65676
- import { join as join28 } from "path";
65662
+ import { join as join29 } from "path";
65677
65663
  var DEFAULT_BLAST_RADIUS_TIMEOUT_MS = 300;
65678
65664
  function defaultProxySockPath(cwd = process.cwd()) {
65679
- return join28(cwd, ".unerr", "state", "proxy.sock");
65665
+ return join29(cwd, ".unerr", "state", "proxy.sock");
65680
65666
  }
65681
65667
  function queryBlastRadius(params, options = {}) {
65682
65668
  const sockPath2 = options.sockPath ?? defaultProxySockPath();
65683
65669
  const timeoutMs = options.timeoutMs ?? DEFAULT_BLAST_RADIUS_TIMEOUT_MS;
65684
- if (!existsSync23(sockPath2)) return Promise.resolve(null);
65670
+ if (!existsSync24(sockPath2)) return Promise.resolve(null);
65685
65671
  return new Promise((resolve8) => {
65686
65672
  let settled = false;
65687
65673
  let buffer = "";
@@ -65735,15 +65721,15 @@ function queryBlastRadius(params, options = {}) {
65735
65721
  }
65736
65722
 
65737
65723
  // src/hooks/hook-dedup.ts
65738
- import { existsSync as existsSync24, mkdirSync as mkdirSync15, readFileSync as readFileSync21, writeFileSync as writeFileSync9 } from "fs";
65739
- import { dirname as dirname8, join as join29 } from "path";
65740
- var STATE_FILE = join29(".unerr", "state", "hook-recent.json");
65724
+ import { existsSync as existsSync25, mkdirSync as mkdirSync16, readFileSync as readFileSync22, writeFileSync as writeFileSync10 } from "fs";
65725
+ import { dirname as dirname8, join as join30 } from "path";
65726
+ var STATE_FILE = join30(".unerr", "state", "hook-recent.json");
65741
65727
  var DEFAULT_TTL_MS = 3e4;
65742
65728
  var PRUNE_FACTOR = 10;
65743
65729
  function readMap(file) {
65744
65730
  try {
65745
- if (!existsSync24(file)) return {};
65746
- const raw = readFileSync21(file, "utf8");
65731
+ if (!existsSync25(file)) return {};
65732
+ const raw = readFileSync22(file, "utf8");
65747
65733
  const obj = JSON.parse(raw);
65748
65734
  if (obj && typeof obj === "object") return obj;
65749
65735
  } catch {
@@ -65753,8 +65739,8 @@ function readMap(file) {
65753
65739
  function writeMap(file, map) {
65754
65740
  try {
65755
65741
  const dir = dirname8(file);
65756
- if (!existsSync24(dir)) mkdirSync15(dir, { recursive: true });
65757
- writeFileSync9(file, JSON.stringify(map));
65742
+ if (!existsSync25(dir)) mkdirSync16(dir, { recursive: true });
65743
+ writeFileSync10(file, JSON.stringify(map));
65758
65744
  } catch {
65759
65745
  }
65760
65746
  }
@@ -65816,7 +65802,8 @@ var claudeCodeAdapter = {
65816
65802
  hookSpecificOutput: {
65817
65803
  hookEventName: "PreToolUse",
65818
65804
  permissionDecision: "allow",
65819
- systemMessage: result.message
65805
+ systemMessage: result.message,
65806
+ additionalContext: result.message
65820
65807
  }
65821
65808
  });
65822
65809
  }
@@ -66163,13 +66150,13 @@ ${existing}` : prefix
66163
66150
 
66164
66151
  // src/hooks/review-client.ts
66165
66152
  init_review_protocol();
66166
- import { existsSync as existsSync25 } from "fs";
66153
+ import { existsSync as existsSync26 } from "fs";
66167
66154
  import { connect as connect2 } from "net";
66168
66155
  var DEFAULT_REVIEW_TIMEOUT_MS = 500;
66169
66156
  function queryReviewEdit(params, options = {}) {
66170
66157
  const sockPath2 = options.sockPath ?? defaultProxySockPath();
66171
66158
  const timeoutMs = options.timeoutMs ?? DEFAULT_REVIEW_TIMEOUT_MS;
66172
- if (!existsSync25(sockPath2)) return Promise.resolve(null);
66159
+ if (!existsSync26(sockPath2)) return Promise.resolve(null);
66173
66160
  return new Promise((resolve8) => {
66174
66161
  let settled = false;
66175
66162
  let buffer = "";
@@ -66228,7 +66215,7 @@ function queryReviewEdit(params, options = {}) {
66228
66215
  var DENY_ONCE_TTL_MS = 5 * 60 * 1e3;
66229
66216
  function appendCoChangeClause(base, filePath) {
66230
66217
  try {
66231
- const unerrDir2 = join30(process.cwd(), ".unerr");
66218
+ const unerrDir2 = join31(process.cwd(), ".unerr");
66232
66219
  const partners = lookupCoChangePartners(unerrDir2, filePath, 3);
66233
66220
  if (partners.length === 0) return base;
66234
66221
  return `${base}; commonly co-changed with: ${partners.join(", ")}`;
@@ -66346,7 +66333,7 @@ function formatCascadeNudge(warnings, filePath, readPrereq) {
66346
66333
  const head = readPrereq.trimEnd();
66347
66334
  if (head) lines.push(head);
66348
66335
  lines.push(
66349
- `Editing "${filePath}" changes ${warnings.length} signature(s) with callers that must be updated in the same change:`
66336
+ `\u26A1 unerr \xB7 cascade guard: editing "${filePath}" changes ${warnings.length} signature(s) with callers that must be updated in the same change:`
66350
66337
  );
66351
66338
  for (const w of warnings) {
66352
66339
  const direct = w.blast_radius.direct_callers.length;
@@ -66455,7 +66442,7 @@ var postEditHandlerAsync = async (normalized) => {
66455
66442
  if (!filePath || !isCodeFile(filePath)) return passthrough();
66456
66443
  const oldContent = input.old_string ?? null;
66457
66444
  const newContent = input.new_string ?? null;
66458
- recordEdit(join30(process.cwd(), ".unerr"), {
66445
+ recordEdit(join31(process.cwd(), ".unerr"), {
66459
66446
  ts: (/* @__PURE__ */ new Date()).toISOString(),
66460
66447
  file_path: filePath,
66461
66448
  old_content: oldContent,
@@ -66512,8 +66499,8 @@ function runPostEditHookAsync(stdinJson) {
66512
66499
  // src/hooks/prompt-hooks.ts
66513
66500
  init_topic_shift();
66514
66501
  init_nudge_state();
66515
- import { existsSync as existsSync30, readFileSync as readFileSync25 } from "fs";
66516
- import { join as join35 } from "path";
66502
+ import { existsSync as existsSync31, readFileSync as readFileSync26 } from "fs";
66503
+ import { join as join36 } from "path";
66517
66504
  init_prompt_capture();
66518
66505
  var VERB_CLUSTERS = [
66519
66506
  {
@@ -66739,9 +66726,9 @@ function buildSkillCatalog() {
66739
66726
  }
66740
66727
  function readShadowLedgerSync(cwd) {
66741
66728
  try {
66742
- const path7 = join35(cwd, ".unerr", "ledger", "shadow.jsonl");
66743
- if (!existsSync30(path7)) return [];
66744
- const raw = readFileSync25(path7, "utf8");
66729
+ const path7 = join36(cwd, ".unerr", "ledger", "shadow.jsonl");
66730
+ if (!existsSync31(path7)) return [];
66731
+ const raw = readFileSync26(path7, "utf8");
66745
66732
  const out = [];
66746
66733
  for (const line of raw.split("\n")) {
66747
66734
  const trimmed = line.trim();
@@ -66828,10 +66815,10 @@ var promptSubmitHandler = (normalized) => {
66828
66815
  if (message.length < 10) return passthrough();
66829
66816
  try {
66830
66817
  const cwd = process.cwd();
66831
- const sessionId = readProxySessionId(join35(cwd, ".unerr")) ?? raw.session_id ?? "unknown";
66818
+ const sessionId = readProxySessionId(join36(cwd, ".unerr")) ?? raw.session_id ?? "unknown";
66832
66819
  const cluster = classifyVerbCluster(message);
66833
66820
  recordUserPromptReceived({
66834
- unerrDir: join35(cwd, ".unerr"),
66821
+ unerrDir: join36(cwd, ".unerr"),
66835
66822
  cwd,
66836
66823
  sessionId,
66837
66824
  message,
@@ -66917,13 +66904,13 @@ function runUserPromptSubmitHook(stdinJson) {
66917
66904
 
66918
66905
  // src/hooks/session-hooks.ts
66919
66906
  init_session_persistence();
66920
- import { join as join38 } from "path";
66907
+ import { join as join39 } from "path";
66921
66908
  var sessionStartHandler = (_normalized) => {
66922
66909
  return passthrough();
66923
66910
  };
66924
66911
  async function runSessionStartHookAsync(stdinJson) {
66925
66912
  try {
66926
- const unerrDir2 = join38(process.cwd(), ".unerr");
66913
+ const unerrDir2 = join39(process.cwd(), ".unerr");
66927
66914
  const payload = await generateSessionResumePayload(unerrDir2);
66928
66915
  if (!payload) return runSessionStartHook(stdinJson, sessionStartHandler);
66929
66916
  const block = formatSessionResumeBlock(payload);
@@ -66989,7 +66976,7 @@ function runPreWebFetchHook(stdinJson) {
66989
66976
  function safeHookAction(handler) {
66990
66977
  return () => {
66991
66978
  try {
66992
- const stdin = readFileSync28(0, "utf-8");
66979
+ const stdin = readFileSync29(0, "utf-8");
66993
66980
  process.stdout.write(handler(stdin));
66994
66981
  } catch (e) {
66995
66982
  process.stderr.write(`[unerr] hook error: ${e}
@@ -67001,7 +66988,7 @@ function safeHookAction(handler) {
67001
66988
  function safeAsyncHookAction(handler) {
67002
66989
  return async () => {
67003
66990
  try {
67004
- const stdin = readFileSync28(0, "utf-8");
66991
+ const stdin = readFileSync29(0, "utf-8");
67005
66992
  process.stdout.write(await handler(stdin));
67006
66993
  } catch (e) {
67007
66994
  process.stderr.write(`[unerr] hook error: ${e}
@@ -68453,7 +68440,7 @@ function ensureGitignore(cwd) {
68453
68440
  init_correction_detector();
68454
68441
  import { existsSync as existsSync48 } from "fs";
68455
68442
  import { join as join55 } from "path";
68456
- import { gunzipSync as gunzipSync2 } from "zlib";
68443
+ import { gunzipSync } from "zlib";
68457
68444
  import pc3 from "picocolors";
68458
68445
  function registerLearnCommand(program2) {
68459
68446
  program2.command("learn").description(
@@ -68551,7 +68538,7 @@ async function persistPatterns(patterns, _unerrDir) {
68551
68538
  const store = await CozoGraphStore2.create(db);
68552
68539
  const { unpack } = await import("msgpackr");
68553
68540
  const raw = readFileSync89(snapshotPath2);
68554
- const buffer = gunzipSync2(raw);
68541
+ const buffer = gunzipSync(raw);
68555
68542
  const envelope = unpack(buffer);
68556
68543
  await store.loadSnapshot(envelope);
68557
68544
  store.persistCorrections(patterns);
@@ -70704,27 +70691,6 @@ function registerStatusCommand(program2) {
70704
70691
  }
70705
70692
  }
70706
70693
  let graphInfo = "No local graph";
70707
- const manifestsDir = join73(localDataDir, "manifests");
70708
- if (repoId && existsSync66(join73(manifestsDir, `${repoId}.json`))) {
70709
- try {
70710
- const manifest = JSON.parse(
70711
- readFileSync57(join73(manifestsDir, `${repoId}.json`), "utf-8")
70712
- );
70713
- const entityCount = manifest.entityCount ?? 0;
70714
- const edgeCount = manifest.edgeCount ?? 0;
70715
- const pulledAt = manifest.pulledAt;
70716
- let ageStr = "";
70717
- if (pulledAt) {
70718
- const ageMs = Date.now() - new Date(pulledAt).getTime();
70719
- const ageHours = Math.floor(ageMs / 36e5);
70720
- if (ageHours < 1) ageStr = "indexed <1h ago";
70721
- else if (ageHours < 24) ageStr = `indexed ${ageHours}h ago`;
70722
- else ageStr = `indexed ${Math.floor(ageHours / 24)}d ago`;
70723
- }
70724
- graphInfo = `${entityCount.toLocaleString()} entities, ${edgeCount.toLocaleString()} edges${ageStr ? ` (${ageStr})` : ""}`;
70725
- } catch {
70726
- }
70727
- }
70728
70694
  let drift;
70729
70695
  const driftSummaryPath = join73(unerrDir2, "drift", "drift_summary.json");
70730
70696
  if (existsSync66(driftSummaryPath)) {
@@ -70760,14 +70726,15 @@ function registerStatusCommand(program2) {
70760
70726
  snapshotPath2 = join73(snapshotsDir, "graph.msgpack");
70761
70727
  }
70762
70728
  if (existsSync66(snapshotPath2)) {
70763
- const { gunzipSync: gunzipSync3 } = await import("zlib");
70729
+ const { gunzipSync: gunzipSync2 } = await import("zlib");
70764
70730
  const { unpack } = await import("msgpackr");
70765
- const { default: CozoDbConstructor } = await import("cozo-node");
70731
+ const cozoModule = await import("cozo-node");
70766
70732
  const { CozoGraphStore: CozoGraphStore2 } = await Promise.resolve().then(() => (init_local_graph(), local_graph_exports));
70733
+ const CozoDbConstructor = cozoModule.default ? cozoModule.default.CozoDb : cozoModule.CozoDb;
70767
70734
  const raw = readFileSync57(snapshotPath2);
70768
70735
  let buffer;
70769
70736
  try {
70770
- buffer = gunzipSync3(raw);
70737
+ buffer = gunzipSync2(raw);
70771
70738
  } catch {
70772
70739
  buffer = raw;
70773
70740
  }
@@ -70776,6 +70743,17 @@ function registerStatusCommand(program2) {
70776
70743
  const envelope = unpack(buffer);
70777
70744
  await graph.loadSnapshot(envelope);
70778
70745
  ruleHealth = await graph.getRuleHealthSummary();
70746
+ const entityCount = envelope?.entities?.length ?? 0;
70747
+ const edgeCount = envelope?.edges?.length ?? 0;
70748
+ let ageStr = "";
70749
+ if (typeof envelope?.generatedAt === "string") {
70750
+ const ageMs = Date.now() - new Date(envelope.generatedAt).getTime();
70751
+ const ageHours = Math.floor(ageMs / 36e5);
70752
+ if (ageHours < 1) ageStr = "indexed <1h ago";
70753
+ else if (ageHours < 24) ageStr = `indexed ${ageHours}h ago`;
70754
+ else ageStr = `indexed ${Math.floor(ageHours / 24)}d ago`;
70755
+ }
70756
+ graphInfo = `${entityCount.toLocaleString()} entities, ${edgeCount.toLocaleString()} edges${ageStr ? ` (${ageStr})` : ""}`;
70779
70757
  }
70780
70758
  } catch {
70781
70759
  }