@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.
- package/README.md +31 -46
- package/dist/cli.js +528 -550
- 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
|
|
3054
|
-
import { join as
|
|
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 =
|
|
3067
|
-
WRITE_TIMEOUT_MS =
|
|
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 =
|
|
3127
|
-
if (
|
|
3283
|
+
const pidPath2 = join3(projectRoot, ".unerr", "state", "proxy.pid");
|
|
3284
|
+
if (existsSync3(pidPath2)) {
|
|
3128
3285
|
try {
|
|
3129
|
-
const raw =
|
|
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
|
|
5309
|
-
import { join as
|
|
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 =
|
|
5312
|
-
|
|
5313
|
-
const dbPath =
|
|
5314
|
-
const isNew = !
|
|
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
|
|
6178
|
-
import { dirname as dirname2, join as
|
|
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
|
|
6337
|
+
return join5(unerrDir2, "state", "cochange-index.json");
|
|
6181
6338
|
}
|
|
6182
6339
|
function readCoChangeIndex(unerrDir2) {
|
|
6183
6340
|
const path7 = cochangeIndexPath(unerrDir2);
|
|
6184
|
-
if (!
|
|
6341
|
+
if (!existsSync5(path7)) return {};
|
|
6185
6342
|
try {
|
|
6186
|
-
const raw =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
|
6874
|
-
import { join as
|
|
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 =
|
|
6933
|
-
if (!
|
|
7089
|
+
const manifestPath = join9(cwd, ".unerr", "manifest.json");
|
|
7090
|
+
if (!existsSync7(manifestPath)) return null;
|
|
6934
7091
|
try {
|
|
6935
|
-
const raw =
|
|
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
|
|
7489
|
-
mkdirSync as
|
|
7490
|
-
readFileSync as
|
|
7645
|
+
existsSync as existsSync10,
|
|
7646
|
+
mkdirSync as mkdirSync6,
|
|
7647
|
+
readFileSync as readFileSync9,
|
|
7491
7648
|
rmdirSync,
|
|
7492
7649
|
unlinkSync,
|
|
7493
|
-
writeFileSync as
|
|
7650
|
+
writeFileSync as writeFileSync4
|
|
7494
7651
|
} from "fs";
|
|
7495
7652
|
import { homedir } from "os";
|
|
7496
|
-
import { basename as basename2, dirname as dirname3, join as
|
|
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 &&
|
|
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 &&
|
|
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" ?
|
|
7712
|
+
const configPath2 = agent.configScope === "global" ? join12(homedir(), agent.projectConfigPath) : join12(cwd, agent.projectConfigPath);
|
|
7556
7713
|
const dir = dirname3(configPath2);
|
|
7557
|
-
if (!
|
|
7558
|
-
|
|
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" ?
|
|
7583
|
-
if (!
|
|
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(
|
|
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
|
-
|
|
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" ?
|
|
7634
|
-
if (!
|
|
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(
|
|
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 (
|
|
7852
|
+
if (existsSync10(configPath2)) {
|
|
7696
7853
|
try {
|
|
7697
7854
|
const existing = JSON.parse(
|
|
7698
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
7877
|
+
if (existsSync10(configPath2)) {
|
|
7721
7878
|
try {
|
|
7722
|
-
const existing = JSON.parse(
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
7904
|
+
if (existsSync10(configPath2)) {
|
|
7748
7905
|
try {
|
|
7749
|
-
const existing = JSON.parse(
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
7929
|
+
if (existsSync10(configPath2)) {
|
|
7773
7930
|
try {
|
|
7774
7931
|
const existing = JSON.parse(
|
|
7775
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
7817
|
-
import { join as
|
|
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 (
|
|
7880
|
-
if (
|
|
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 (
|
|
7883
|
-
if (process.env.ZED_TERM === "true" ||
|
|
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 (
|
|
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
|
|
8214
|
-
import { join as
|
|
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
|
|
8384
|
+
return join15(repoRoot, ".unerr", "logs");
|
|
8228
8385
|
}
|
|
8229
8386
|
function globalLogsDir(globalRoot) {
|
|
8230
|
-
return
|
|
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 (!
|
|
8400
|
+
if (!existsSync13(dir)) return 0;
|
|
8244
8401
|
let removed = 0;
|
|
8245
8402
|
try {
|
|
8246
|
-
for (const name of
|
|
8403
|
+
for (const name of readdirSync4(dir)) {
|
|
8247
8404
|
if (!isLegacyName(name)) continue;
|
|
8248
|
-
const full =
|
|
8405
|
+
const full = join15(dir, name);
|
|
8249
8406
|
try {
|
|
8250
|
-
if (!
|
|
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) =>
|
|
8269
|
-
bridge: (repoRoot) =>
|
|
8270
|
-
session: (repoRoot) =>
|
|
8271
|
-
events: (repoRoot) =>
|
|
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) =>
|
|
8275
|
-
events: (globalRoot) =>
|
|
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
|
|
8298
|
-
readFileSync as
|
|
8299
|
-
writeFileSync as
|
|
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 =
|
|
8467
|
+
const content = readFileSync11(filePath, "utf-8");
|
|
8311
8468
|
const lines = content.split("\n").filter(Boolean);
|
|
8312
8469
|
if (lines.length > maxLines) {
|
|
8313
|
-
|
|
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
|
-
|
|
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
|
|
9063
|
+
import { existsSync as existsSync17, readFileSync as readFileSync15 } from "fs";
|
|
8907
9064
|
import { homedir as homedir5 } from "os";
|
|
8908
|
-
import { join as
|
|
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 (!
|
|
9086
|
+
if (!existsSync17(filePath)) return {};
|
|
8930
9087
|
try {
|
|
8931
|
-
return JSON.parse(
|
|
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(
|
|
9095
|
+
const userSettings = loadJsonFile(join19(homedir5(), ".unerr", "settings.json"));
|
|
8939
9096
|
const projectSettings = loadJsonFile(
|
|
8940
|
-
|
|
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
|
|
9071
|
-
import { join as
|
|
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 =
|
|
9074
|
-
|
|
9075
|
-
const dbPath =
|
|
9076
|
-
const isNew = !
|
|
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
|
|
9238
|
+
return join20(projectRoot, UNERR_DIR2, GRAPH_DB_FILENAME);
|
|
9082
9239
|
}
|
|
9083
9240
|
function hasPersistedGraph(projectRoot) {
|
|
9084
9241
|
const dbPath = getDbPath(projectRoot);
|
|
9085
|
-
if (!
|
|
9242
|
+
if (!existsSync18(dbPath)) return false;
|
|
9086
9243
|
try {
|
|
9087
|
-
const stat2 =
|
|
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
|
|
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
|
|
9578
|
-
import { join as
|
|
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
|
|
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 (!
|
|
9609
|
-
const raw =
|
|
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 (!
|
|
9643
|
-
|
|
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
|
|
9668
|
-
import { join as
|
|
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
|
-
|
|
9682
|
-
store = new MetricsStore(
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
10613
|
-
import { join as
|
|
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 =
|
|
10620
|
-
|
|
10621
|
-
const path7 =
|
|
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 (
|
|
10788
|
+
if (existsSync20(path7)) {
|
|
10632
10789
|
agg = {
|
|
10633
10790
|
...agg,
|
|
10634
10791
|
...JSON.parse(
|
|
10635
|
-
|
|
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
|
-
|
|
10804
|
+
writeFileSync8(path7, JSON.stringify(agg));
|
|
10648
10805
|
} catch {
|
|
10649
10806
|
}
|
|
10650
10807
|
}
|
|
10651
10808
|
function readShellCompressionAggregate(cwd) {
|
|
10652
10809
|
try {
|
|
10653
|
-
const path7 =
|
|
10654
|
-
if (!
|
|
10655
|
-
return JSON.parse(
|
|
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
|
|
10678
|
-
mkdirSync as
|
|
10679
|
-
readFileSync as
|
|
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
|
|
10839
|
+
import { dirname as dirname7, join as join28 } from "path";
|
|
10683
10840
|
function editLogPath(unerrDir2) {
|
|
10684
|
-
return
|
|
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 (!
|
|
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 (!
|
|
10712
|
-
const raw =
|
|
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) ?
|
|
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
|
|
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) ?
|
|
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
|
|
11114
|
-
import { join as
|
|
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 =
|
|
11118
|
-
if (!
|
|
11119
|
-
const raw = JSON.parse(
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
11310
|
-
if (!
|
|
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 (!
|
|
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) =>
|
|
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
|
|
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
|
|
11523
|
+
import { join as join34, normalize as normalize3 } from "path";
|
|
11367
11524
|
function cursorTelemetryDbPath(home = homedir9()) {
|
|
11368
|
-
return
|
|
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
|
|
11530
|
+
return join34(home, "Library", "Application Support", "Cursor", "User");
|
|
11374
11531
|
if (p === "win32") {
|
|
11375
|
-
const appData = process.env.APPDATA ??
|
|
11376
|
-
return
|
|
11532
|
+
const appData = process.env.APPDATA ?? join34(home, "AppData", "Roaming");
|
|
11533
|
+
return join34(appData, "Cursor", "User");
|
|
11377
11534
|
}
|
|
11378
|
-
return
|
|
11535
|
+
return join34(home, ".config", "Cursor", "User");
|
|
11379
11536
|
}
|
|
11380
11537
|
function cursorGlobalVscdbPath(home = homedir9()) {
|
|
11381
|
-
return
|
|
11538
|
+
return join34(cursorUserDataDir(home), "globalStorage", "state.vscdb");
|
|
11382
11539
|
}
|
|
11383
11540
|
async function openReadOnly(path7) {
|
|
11384
|
-
if (!
|
|
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 =
|
|
11484
|
-
if (!
|
|
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 =
|
|
11645
|
+
const entries = readdirSync7(wsRoot, { withFileTypes: true });
|
|
11489
11646
|
for (const entry of entries) {
|
|
11490
11647
|
if (!entry.isDirectory()) continue;
|
|
11491
|
-
const wsJsonPath =
|
|
11492
|
-
if (!
|
|
11648
|
+
const wsJsonPath = join34(wsRoot, entry.name, "workspace.json");
|
|
11649
|
+
if (!existsSync29(wsJsonPath)) continue;
|
|
11493
11650
|
try {
|
|
11494
|
-
const raw = JSON.parse(
|
|
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 =
|
|
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
|
|
11722
|
-
import { join as
|
|
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 =
|
|
11726
|
-
if (!
|
|
11727
|
-
const raw = JSON.parse(
|
|
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 =
|
|
11738
|
-
|
|
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
|
|
11924
|
-
import { join as
|
|
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 =
|
|
12002
|
-
if (!
|
|
12003
|
-
const content =
|
|
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 =
|
|
12012
|
-
if (!
|
|
12013
|
-
|
|
12168
|
+
const stateDir = join37(unerrDir2, "state");
|
|
12169
|
+
if (!existsSync32(stateDir)) {
|
|
12170
|
+
mkdirSync17(stateDir, { recursive: true });
|
|
12014
12171
|
}
|
|
12015
|
-
const pointerPath =
|
|
12016
|
-
|
|
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
|
|
12345
|
-
import { join as
|
|
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 =
|
|
12467
|
-
if (!
|
|
12468
|
-
const filePath =
|
|
12469
|
-
|
|
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 =
|
|
12489
|
-
if (!
|
|
12490
|
-
const data = JSON.parse(
|
|
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
|
|
58517
|
-
mkdirSync as
|
|
58518
|
-
readFileSync as
|
|
58516
|
+
existsSync as existsSync8,
|
|
58517
|
+
mkdirSync as mkdirSync5,
|
|
58518
|
+
readFileSync as readFileSync7,
|
|
58519
58519
|
rmSync,
|
|
58520
|
-
writeFileSync as
|
|
58520
|
+
writeFileSync as writeFileSync3
|
|
58521
58521
|
} from "fs";
|
|
58522
|
-
import { join as
|
|
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
|
|
58528
|
-
import { join as
|
|
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 =
|
|
58532
|
-
if (!
|
|
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(
|
|
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
|
|
58540
|
+
const cozoModule = await import("cozo-node");
|
|
58552
58541
|
const { CozoGraphStore: CozoGraphStore2 } = await Promise.resolve().then(() => (init_local_graph(), local_graph_exports));
|
|
58553
|
-
const
|
|
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
|
|
58557
|
-
|
|
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 =
|
|
58567
|
-
if (!
|
|
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
|
|
58584
|
-
import { join as
|
|
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 =
|
|
58646
|
-
if (!blockingMode &&
|
|
58631
|
+
const settingsPath = join10(cwd, ".unerr", "settings.json");
|
|
58632
|
+
if (!blockingMode && existsSync8(settingsPath)) {
|
|
58647
58633
|
try {
|
|
58648
58634
|
const settings = JSON.parse(
|
|
58649
|
-
|
|
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 =
|
|
58657
|
-
if (!
|
|
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(
|
|
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
|
|
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 =
|
|
58769
|
-
|
|
58770
|
-
|
|
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 =
|
|
58775
|
-
|
|
58760
|
+
const logsDir = join10(cwd, ".unerr", "logs");
|
|
58761
|
+
mkdirSync5(logsDir, { recursive: true });
|
|
58776
58762
|
appendFileSync2(
|
|
58777
|
-
|
|
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 (!
|
|
58773
|
+
if (!existsSync8(statePath2)) return;
|
|
58788
58774
|
let pending;
|
|
58789
58775
|
try {
|
|
58790
|
-
pending = JSON.parse(
|
|
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
|
|
58827
|
-
import { join as
|
|
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 =
|
|
58832
|
-
const configPath2 =
|
|
58833
|
-
if (!
|
|
58834
|
-
const config = JSON.parse(
|
|
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 =
|
|
58837
|
-
if (!
|
|
58838
|
-
const data = JSON.parse(
|
|
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
|
|
58876
|
-
import { join as
|
|
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 =
|
|
58879
|
-
if (!
|
|
58864
|
+
const p = join16(cwd, ".unerr", "state", "server.json");
|
|
58865
|
+
if (!existsSync14(p)) return null;
|
|
58880
58866
|
try {
|
|
58881
|
-
const raw =
|
|
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
|
|
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
|
|
58923
|
-
var UNERR_DIR =
|
|
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 =
|
|
58935
|
-
if (
|
|
58920
|
+
const settingsPath = join17(UNERR_DIR, "settings.json");
|
|
58921
|
+
if (existsSync15(settingsPath)) {
|
|
58936
58922
|
try {
|
|
58937
58923
|
const settings = JSON.parse(
|
|
58938
|
-
|
|
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 =
|
|
58963
|
-
if (
|
|
58948
|
+
const configPath2 = join17(process.cwd(), ".unerr", "config.json");
|
|
58949
|
+
if (existsSync15(configPath2)) {
|
|
58964
58950
|
try {
|
|
58965
58951
|
const config = JSON.parse(
|
|
58966
|
-
|
|
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 =
|
|
58980
|
-
if (
|
|
58965
|
+
const pidPath2 = join17(process.cwd(), ".unerr", "state", "proxy.pid");
|
|
58966
|
+
if (existsSync15(pidPath2)) {
|
|
58981
58967
|
try {
|
|
58982
58968
|
const pid = Number.parseInt(
|
|
58983
|
-
|
|
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 =
|
|
59002
|
-
if (
|
|
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 =
|
|
59010
|
-
if (
|
|
59011
|
-
const files =
|
|
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 =
|
|
59017
|
-
const stat2 =
|
|
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
|
-
|
|
59027
|
-
|
|
59028
|
-
|
|
59029
|
-
|
|
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 =
|
|
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 =
|
|
59049
|
-
if (
|
|
59050
|
-
const logFiles =
|
|
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 =
|
|
59038
|
+
const logPath = join17(logsDir, logFiles[0]);
|
|
59053
59039
|
try {
|
|
59054
|
-
const content =
|
|
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 =
|
|
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
|
-
|
|
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(
|
|
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
|
|
59093
|
+
existsSync as existsSync16,
|
|
59108
59094
|
constants as fsConstants,
|
|
59109
|
-
mkdirSync as
|
|
59110
|
-
readFileSync as
|
|
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
|
|
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 :
|
|
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
|
|
59152
|
+
return join18(home, ".zshrc");
|
|
59167
59153
|
case "fish":
|
|
59168
|
-
return
|
|
59154
|
+
return join18(home, ".config", "fish", "config.fish");
|
|
59169
59155
|
case "bash":
|
|
59170
|
-
return
|
|
59156
|
+
return join18(home, ".bashrc");
|
|
59171
59157
|
case "powershell": {
|
|
59172
|
-
const docs = process.env.USERPROFILE ?
|
|
59173
|
-
const ps7Profile =
|
|
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 =
|
|
59164
|
+
const ps5Profile = join18(
|
|
59179
59165
|
docs,
|
|
59180
59166
|
"WindowsPowerShell",
|
|
59181
59167
|
"Microsoft.PowerShell_profile.ps1"
|
|
59182
59168
|
);
|
|
59183
|
-
if (
|
|
59169
|
+
if (existsSync16(dirname6(ps7Profile))) return ps7Profile;
|
|
59184
59170
|
return ps5Profile;
|
|
59185
59171
|
}
|
|
59186
59172
|
case "cmd":
|
|
59187
|
-
return
|
|
59173
|
+
return join18(home, ".unerr-path.cmd");
|
|
59188
59174
|
default:
|
|
59189
|
-
return
|
|
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 (!
|
|
59304
|
-
const content =
|
|
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 (!
|
|
59349
|
-
|
|
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 =
|
|
59661
|
+
const dir = join18(homedir4(), ".unerr");
|
|
59676
59662
|
try {
|
|
59677
|
-
|
|
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
|
|
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:
|
|
61485
|
+
const { gunzipSync: gunzipSync2 } = await import("zlib");
|
|
61500
61486
|
const raw = readFileSync89(snapshotPath2);
|
|
61501
61487
|
try {
|
|
61502
|
-
buffer =
|
|
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
|
|
62551
|
+
import { existsSync as existsSync21, readFileSync as readFileSync18 } from "fs";
|
|
62566
62552
|
import { homedir as homedir6 } from "os";
|
|
62567
|
-
import { join as
|
|
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 (!
|
|
62573
|
-
return
|
|
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 =
|
|
62754
|
-
const userPath =
|
|
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
|
|
64852
|
-
readdirSync as
|
|
64853
|
-
statSync as
|
|
64837
|
+
mkdirSync as mkdirSync14,
|
|
64838
|
+
readdirSync as readdirSync6,
|
|
64839
|
+
statSync as statSync6,
|
|
64854
64840
|
unlinkSync as unlinkSync3,
|
|
64855
|
-
writeFileSync as
|
|
64841
|
+
writeFileSync as writeFileSync9
|
|
64856
64842
|
} from "fs";
|
|
64857
|
-
import { join as
|
|
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 =
|
|
64852
|
+
const teeDir = join26(cwd, ".unerr", "tee");
|
|
64867
64853
|
try {
|
|
64868
|
-
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
64897
|
-
const p =
|
|
64882
|
+
entries = readdirSync6(teeDir).filter((f) => f.endsWith(".txt")).map((name) => {
|
|
64883
|
+
const p = join26(teeDir, name);
|
|
64898
64884
|
try {
|
|
64899
|
-
const { mtimeMs } =
|
|
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 =
|
|
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
|
|
65501
|
-
import { join as
|
|
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 =
|
|
65514
|
-
if (!
|
|
65515
|
-
const raw =
|
|
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
|
|
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
|
|
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
|
|
65660
|
+
import { existsSync as existsSync24 } from "fs";
|
|
65675
65661
|
import { connect } from "net";
|
|
65676
|
-
import { join as
|
|
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
|
|
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 (!
|
|
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
|
|
65739
|
-
import { dirname as dirname8, join as
|
|
65740
|
-
var STATE_FILE =
|
|
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 (!
|
|
65746
|
-
const raw =
|
|
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 (!
|
|
65757
|
-
|
|
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
|
|
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 (!
|
|
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 =
|
|
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
|
-
|
|
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(
|
|
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
|
|
66516
|
-
import { join as
|
|
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 =
|
|
66743
|
-
if (!
|
|
66744
|
-
const raw =
|
|
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(
|
|
66818
|
+
const sessionId = readProxySessionId(join36(cwd, ".unerr")) ?? raw.session_id ?? "unknown";
|
|
66832
66819
|
const cluster = classifyVerbCluster(message);
|
|
66833
66820
|
recordUserPromptReceived({
|
|
66834
|
-
unerrDir:
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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:
|
|
70729
|
+
const { gunzipSync: gunzipSync2 } = await import("zlib");
|
|
70764
70730
|
const { unpack } = await import("msgpackr");
|
|
70765
|
-
const
|
|
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 =
|
|
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
|
}
|