@inerrata-corporation/errata 2.0.23-dev.4900 → 2.0.23-dev.4938
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/THIRD-PARTY-NOTICES.md +27 -0
- package/consolidate-worker.mjs +36 -5
- package/errata.mjs +1165 -696
- package/generalize-worker.mjs +14 -0
- package/package.json +1 -1
- package/pass-worker.mjs +32 -0
- package/resources/context-plugin/.codex-plugin/plugin.json +1 -1
- package/resources/context-plugin/SHA256SUMS +1 -1
- package/resources/models/potion-base-8M.q8.bin +0 -0
package/errata.mjs
CHANGED
|
@@ -19589,7 +19589,7 @@ var init_lineage_integrity = __esm({
|
|
|
19589
19589
|
});
|
|
19590
19590
|
|
|
19591
19591
|
// ../../packages/math/src/constants.ts
|
|
19592
|
-
var SURPRISE_MOMENTUM, SURPRISE_LEARNING_RATE, SURPRISE_LEARNING_RATE_SCALING, TIER_HALFLIFE_MULTIPLIER, HIT_RATE_SCALING_ALPHA, BASE_HALF_LIFE_SEQ, MOMENTUM_GATE_FLOOR, EVIDENCE_HALFLIFE_SEQ, EVIDENCE_ACCEPTED_HALFLIFE_MULT, EVIDENCE_DECAY_FLOOR, CORROBORATION_WEIGHT, SURPRISE_RECENCY_LAMBDA_SEQ, NEMORI_SOFT_WRITE_MIN_COSINE, NEMORI_SOFT_WRITE_MAX_COSINE, NEMORI_DEDUP_COSINE, NEMORI_SOFT_ALPHA_MIN, NEMORI_SOFT_ALPHA_MAX, NEMORI_HIGH_SURPRISE_THRESHOLD,
|
|
19592
|
+
var SURPRISE_MOMENTUM, SURPRISE_LEARNING_RATE, SURPRISE_LEARNING_RATE_SCALING, TIER_HALFLIFE_MULTIPLIER, HIT_RATE_SCALING_ALPHA, BASE_HALF_LIFE_SEQ, MOMENTUM_GATE_FLOOR, EVIDENCE_HALFLIFE_SEQ, EVIDENCE_ACCEPTED_HALFLIFE_MULT, EVIDENCE_DECAY_FLOOR, CORROBORATION_WEIGHT, SURPRISE_RECENCY_LAMBDA_SEQ, NEMORI_SOFT_WRITE_MIN_COSINE, NEMORI_SOFT_WRITE_MAX_COSINE, NEMORI_DEDUP_COSINE, NEMORI_SOFT_ALPHA_MIN, NEMORI_SOFT_ALPHA_MAX, NEMORI_HIGH_SURPRISE_THRESHOLD, REVIEW_SURPRISE_THRESHOLD, REVIEW_HITS_THRESHOLD;
|
|
19593
19593
|
var init_constants = __esm({
|
|
19594
19594
|
"../../packages/math/src/constants.ts"() {
|
|
19595
19595
|
"use strict";
|
|
@@ -19615,7 +19615,6 @@ var init_constants = __esm({
|
|
|
19615
19615
|
NEMORI_SOFT_ALPHA_MIN = 0.6;
|
|
19616
19616
|
NEMORI_SOFT_ALPHA_MAX = 1;
|
|
19617
19617
|
NEMORI_HIGH_SURPRISE_THRESHOLD = 0.2;
|
|
19618
|
-
NEMORI_PREDICTION_FLOOR = 0.5;
|
|
19619
19618
|
REVIEW_SURPRISE_THRESHOLD = 3;
|
|
19620
19619
|
REVIEW_HITS_THRESHOLD = 5;
|
|
19621
19620
|
}
|
|
@@ -23839,49 +23838,231 @@ var init_problem_package_link = __esm({
|
|
|
23839
23838
|
}
|
|
23840
23839
|
});
|
|
23841
23840
|
|
|
23841
|
+
// ../../packages/embedding/src/static.ts
|
|
23842
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3 } from "node:fs";
|
|
23843
|
+
import { dirname as dirname4, join as join3 } from "node:path";
|
|
23844
|
+
import { fileURLToPath } from "node:url";
|
|
23845
|
+
function decodeStaticAsset(bytes) {
|
|
23846
|
+
const buf = Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
23847
|
+
if (buf.toString("ascii", 0, 8) !== ASSET_MAGIC) throw new Error("static model: bad magic");
|
|
23848
|
+
const headerLength = buf.readUInt32LE(8);
|
|
23849
|
+
const header = JSON.parse(buf.toString("utf8", 12, 12 + headerLength));
|
|
23850
|
+
if (header.format !== 1) throw new Error(`static model: unsupported format ${String(header.format)}`);
|
|
23851
|
+
const lead2 = 12 + headerLength;
|
|
23852
|
+
const scalesAt = lead2 + (4 - lead2 % 4) % 4;
|
|
23853
|
+
const scales = new Float32Array(buf.buffer.slice(buf.byteOffset + scalesAt, buf.byteOffset + scalesAt + 4 * header.rows));
|
|
23854
|
+
const weightsAt = scalesAt + 4 * header.rows;
|
|
23855
|
+
const weights = new Int8Array(buf.buffer.slice(buf.byteOffset + weightsAt, buf.byteOffset + weightsAt + header.rows * header.dim));
|
|
23856
|
+
if (weights.length !== header.rows * header.dim) throw new Error("static model: truncated weights");
|
|
23857
|
+
return staticModel(header, scales, weights);
|
|
23858
|
+
}
|
|
23859
|
+
function staticModel(header, scales, weights) {
|
|
23860
|
+
const vocab = /* @__PURE__ */ new Map();
|
|
23861
|
+
header.vocab.forEach((token, id) => vocab.set(token, id));
|
|
23862
|
+
const unkId = vocab.get(header.unkToken);
|
|
23863
|
+
const { dim, rows, prefix, maxCharsPerWord } = header;
|
|
23864
|
+
function wordpiece(word) {
|
|
23865
|
+
const chars = Array.from(word);
|
|
23866
|
+
if (chars.length > maxCharsPerWord) return unkId === void 0 ? [] : [unkId];
|
|
23867
|
+
const ids = [];
|
|
23868
|
+
let start2 = 0;
|
|
23869
|
+
while (start2 < chars.length) {
|
|
23870
|
+
let end = chars.length;
|
|
23871
|
+
let found;
|
|
23872
|
+
while (start2 < end) {
|
|
23873
|
+
const piece = (start2 > 0 ? prefix : "") + chars.slice(start2, end).join("");
|
|
23874
|
+
found = vocab.get(piece);
|
|
23875
|
+
if (found !== void 0) break;
|
|
23876
|
+
end--;
|
|
23877
|
+
}
|
|
23878
|
+
if (found === void 0) return unkId === void 0 ? [] : [unkId];
|
|
23879
|
+
ids.push(found);
|
|
23880
|
+
start2 = end;
|
|
23881
|
+
}
|
|
23882
|
+
return ids;
|
|
23883
|
+
}
|
|
23884
|
+
function tokenize4(text) {
|
|
23885
|
+
return preTokenize(normalize2(text)).flatMap(wordpiece);
|
|
23886
|
+
}
|
|
23887
|
+
function embed2(text) {
|
|
23888
|
+
const sum = new Float64Array(dim);
|
|
23889
|
+
let used = 0;
|
|
23890
|
+
for (const id of tokenize4(text)) {
|
|
23891
|
+
if (id === unkId || id >= rows) continue;
|
|
23892
|
+
if (used++ >= MAX_TOKENS) break;
|
|
23893
|
+
const scale = scales[id];
|
|
23894
|
+
const offset = id * dim;
|
|
23895
|
+
for (let i2 = 0; i2 < dim; i2++) sum[i2] += weights[offset + i2] * scale;
|
|
23896
|
+
}
|
|
23897
|
+
let norm = 0;
|
|
23898
|
+
for (let i2 = 0; i2 < dim; i2++) norm += sum[i2] * sum[i2];
|
|
23899
|
+
norm = Math.sqrt(norm);
|
|
23900
|
+
const out2 = new Array(dim);
|
|
23901
|
+
for (let i2 = 0; i2 < dim; i2++) out2[i2] = norm > 0 ? sum[i2] / norm : 0;
|
|
23902
|
+
return out2;
|
|
23903
|
+
}
|
|
23904
|
+
return { version: header.version, dim, tokenize: tokenize4, embed: embed2 };
|
|
23905
|
+
}
|
|
23906
|
+
function isBertPunctuation(ch) {
|
|
23907
|
+
const c = ch.codePointAt(0);
|
|
23908
|
+
if (c >= 33 && c <= 47 || c >= 58 && c <= 64 || c >= 91 && c <= 96 || c >= 123 && c <= 126) return true;
|
|
23909
|
+
return new RegExp("\\p{P}", "u").test(ch);
|
|
23910
|
+
}
|
|
23911
|
+
function isCjk(c) {
|
|
23912
|
+
return c >= 19968 && c <= 40959 || c >= 13312 && c <= 19903 || c >= 131072 && c <= 173791 || c >= 173824 && c <= 177983 || c >= 177984 && c <= 178207 || c >= 178208 && c <= 183983 || c >= 63744 && c <= 64255 || c >= 194560 && c <= 195103;
|
|
23913
|
+
}
|
|
23914
|
+
function normalize2(text) {
|
|
23915
|
+
let out2 = "";
|
|
23916
|
+
for (const ch of text) {
|
|
23917
|
+
const c = ch.codePointAt(0);
|
|
23918
|
+
if (c === 0 || c === 65533) continue;
|
|
23919
|
+
if (/\s/u.test(ch)) {
|
|
23920
|
+
out2 += " ";
|
|
23921
|
+
continue;
|
|
23922
|
+
}
|
|
23923
|
+
if (new RegExp("\\p{C}", "u").test(ch)) continue;
|
|
23924
|
+
out2 += isCjk(c) ? ` ${ch} ` : ch;
|
|
23925
|
+
}
|
|
23926
|
+
return out2.toLowerCase().normalize("NFD").replace(new RegExp("\\p{Mn}", "gu"), "");
|
|
23927
|
+
}
|
|
23928
|
+
function preTokenize(text) {
|
|
23929
|
+
const words = [];
|
|
23930
|
+
for (const chunk of text.split(" ")) {
|
|
23931
|
+
let current = "";
|
|
23932
|
+
for (const ch of chunk) {
|
|
23933
|
+
if (isBertPunctuation(ch)) {
|
|
23934
|
+
if (current) words.push(current);
|
|
23935
|
+
words.push(ch);
|
|
23936
|
+
current = "";
|
|
23937
|
+
} else {
|
|
23938
|
+
current += ch;
|
|
23939
|
+
}
|
|
23940
|
+
}
|
|
23941
|
+
if (current) words.push(current);
|
|
23942
|
+
}
|
|
23943
|
+
return words;
|
|
23944
|
+
}
|
|
23945
|
+
function staticModelCandidates(moduleUrl = import.meta.url) {
|
|
23946
|
+
const here = dirname4(fileURLToPath(moduleUrl));
|
|
23947
|
+
const explicit = process.env["ERRATA_STATIC_MODEL"];
|
|
23948
|
+
return [
|
|
23949
|
+
...explicit ? [explicit] : [],
|
|
23950
|
+
join3(here, "resources", "models", STATIC_MODEL_FILE),
|
|
23951
|
+
join3(here, "..", "assets", STATIC_MODEL_FILE)
|
|
23952
|
+
];
|
|
23953
|
+
}
|
|
23954
|
+
function loadStaticModel() {
|
|
23955
|
+
if (loaded !== void 0) return loaded;
|
|
23956
|
+
const path3 = staticModelCandidates().find((p) => existsSync4(p));
|
|
23957
|
+
if (!path3) {
|
|
23958
|
+
loadError = new Error(`no static model asset (looked in: ${staticModelCandidates().join(", ")})`);
|
|
23959
|
+
loaded = null;
|
|
23960
|
+
return loaded;
|
|
23961
|
+
}
|
|
23962
|
+
try {
|
|
23963
|
+
loaded = decodeStaticAsset(readFileSync3(path3));
|
|
23964
|
+
} catch (err2) {
|
|
23965
|
+
loadError = err2 instanceof Error ? err2 : new Error(String(err2));
|
|
23966
|
+
loaded = null;
|
|
23967
|
+
}
|
|
23968
|
+
return loaded;
|
|
23969
|
+
}
|
|
23970
|
+
function getStaticModelLoadError() {
|
|
23971
|
+
return loadError;
|
|
23972
|
+
}
|
|
23973
|
+
var STATIC_MODEL_FILE, ASSET_MAGIC, MAX_TOKENS, loaded, loadError;
|
|
23974
|
+
var init_static = __esm({
|
|
23975
|
+
"../../packages/embedding/src/static.ts"() {
|
|
23976
|
+
"use strict";
|
|
23977
|
+
STATIC_MODEL_FILE = "potion-base-8M.q8.bin";
|
|
23978
|
+
ASSET_MAGIC = "ERRSTAT1";
|
|
23979
|
+
MAX_TOKENS = 512;
|
|
23980
|
+
loadError = null;
|
|
23981
|
+
}
|
|
23982
|
+
});
|
|
23983
|
+
|
|
23984
|
+
// ../../packages/embedding/src/bands.ts
|
|
23985
|
+
function cosineBandsFor(version3) {
|
|
23986
|
+
return (version3 ? BANDS[version3] : void 0) ?? UNKNOWN;
|
|
23987
|
+
}
|
|
23988
|
+
var DESIGNED_FOR_MINILM, BANDS, UNKNOWN;
|
|
23989
|
+
var init_bands = __esm({
|
|
23990
|
+
"../../packages/embedding/src/bands.ts"() {
|
|
23991
|
+
"use strict";
|
|
23992
|
+
DESIGNED_FOR_MINILM = {
|
|
23993
|
+
dedup: 0.88,
|
|
23994
|
+
softWriteMin: 0.8,
|
|
23995
|
+
bindMin: 0.78,
|
|
23996
|
+
nearMiss: 0.72,
|
|
23997
|
+
judgeMin: 0.5,
|
|
23998
|
+
predictionFloor: 0.5,
|
|
23999
|
+
relevanceFloor: 0.25,
|
|
24000
|
+
relatedWeak: 0.35,
|
|
24001
|
+
relatedStrong: 0.45
|
|
24002
|
+
};
|
|
24003
|
+
BANDS = {
|
|
24004
|
+
"hash-v1": DESIGNED_FOR_MINILM,
|
|
24005
|
+
"minilm-l6-v2": DESIGNED_FOR_MINILM,
|
|
24006
|
+
"potion-8m-q8": {
|
|
24007
|
+
dedup: 0.895,
|
|
24008
|
+
softWriteMin: 0.835,
|
|
24009
|
+
bindMin: 0.83,
|
|
24010
|
+
nearMiss: 0.775,
|
|
24011
|
+
judgeMin: 0.335,
|
|
24012
|
+
predictionFloor: 0.335,
|
|
24013
|
+
relevanceFloor: 0.35,
|
|
24014
|
+
relatedWeak: 0.49,
|
|
24015
|
+
relatedStrong: 0.53
|
|
24016
|
+
}
|
|
24017
|
+
};
|
|
24018
|
+
UNKNOWN = { ...DESIGNED_FOR_MINILM, relevanceFloor: 0.5 };
|
|
24019
|
+
}
|
|
24020
|
+
});
|
|
24021
|
+
|
|
23842
24022
|
// ../../packages/embedding/src/model.ts
|
|
23843
|
-
import { mkdirSync as mkdirSync3, existsSync as
|
|
24023
|
+
import { mkdirSync as mkdirSync3, existsSync as existsSync5 } from "node:fs";
|
|
23844
24024
|
import { homedir } from "node:os";
|
|
23845
|
-
import { dirname as
|
|
24025
|
+
import { dirname as dirname5, join as join4 } from "node:path";
|
|
23846
24026
|
import { createRequire } from "node:module";
|
|
23847
24027
|
function semanticFloorFor(version3) {
|
|
23848
|
-
|
|
23849
|
-
return 0.5;
|
|
24028
|
+
return cosineBandsFor(version3).relevanceFloor;
|
|
23850
24029
|
}
|
|
23851
24030
|
function noteHashFallback() {
|
|
23852
24031
|
if (warnedHashFallback) return;
|
|
23853
24032
|
if (process.env["ERRATA_EMBED_HASH_ONLY"] === "1") return;
|
|
23854
24033
|
warnedHashFallback = true;
|
|
23855
24034
|
console.warn(
|
|
23856
|
-
`[errata] embedding model unavailable (${
|
|
24035
|
+
`[errata] embedding model unavailable (static: ${getStaticModelLoadError()?.message ?? "unknown"}; transformers: ${lastError?.message ?? "not attempted"}) \u2014 falling back to ${EMBEDDING_VERSION} hash vectors; semantic ranking runs at reduced fidelity`
|
|
23857
24036
|
);
|
|
23858
24037
|
}
|
|
23859
24038
|
function getCacheDir() {
|
|
23860
|
-
return process.env["ERRATA_MODEL_CACHE"] ??
|
|
24039
|
+
return process.env["ERRATA_MODEL_CACHE"] ?? join4(homedir(), ".errata", "models");
|
|
23861
24040
|
}
|
|
23862
24041
|
async function loadTransformers() {
|
|
24042
|
+
let importError;
|
|
23863
24043
|
try {
|
|
23864
24044
|
return await import("@huggingface/transformers");
|
|
23865
24045
|
} catch (err2) {
|
|
23866
|
-
|
|
24046
|
+
importError = err2;
|
|
23867
24047
|
}
|
|
23868
24048
|
try {
|
|
23869
|
-
const seaResourceBase =
|
|
24049
|
+
const seaResourceBase = join4(
|
|
23870
24050
|
// execPath dir is where errata.exe lives; resources/ rides alongside.
|
|
23871
|
-
|
|
24051
|
+
dirname5(process.execPath),
|
|
23872
24052
|
"resources",
|
|
23873
24053
|
"_resolve.js"
|
|
23874
24054
|
);
|
|
23875
24055
|
const resourceRequire = createRequire(seaResourceBase);
|
|
23876
24056
|
return resourceRequire("@huggingface/transformers");
|
|
23877
24057
|
} catch (err2) {
|
|
23878
|
-
|
|
24058
|
+
const message2 = (e) => (e instanceof Error ? e.message : String(e)).split("\n")[0];
|
|
24059
|
+
lastError = new Error(`${message2(importError)} (SEA resources fallback: ${message2(err2)})`);
|
|
23879
24060
|
return null;
|
|
23880
24061
|
}
|
|
23881
24062
|
}
|
|
23882
24063
|
async function loadPipeline() {
|
|
23883
24064
|
const cacheDir = getCacheDir();
|
|
23884
|
-
if (!
|
|
24065
|
+
if (!existsSync5(cacheDir)) mkdirSync3(cacheDir, { recursive: true });
|
|
23885
24066
|
try {
|
|
23886
24067
|
const tx = await loadTransformers();
|
|
23887
24068
|
if (!tx) {
|
|
@@ -23920,6 +24101,14 @@ async function embedTextWithModel(text) {
|
|
|
23920
24101
|
const out2 = await pipe2(text, { pooling: "mean", normalize: true });
|
|
23921
24102
|
return Array.from(out2.data);
|
|
23922
24103
|
}
|
|
24104
|
+
function embedTextSync(text) {
|
|
24105
|
+
if (process.env["ERRATA_EMBED_HASH_ONLY"] !== "1") {
|
|
24106
|
+
const staticModel2 = loadStaticModel();
|
|
24107
|
+
if (staticModel2) return { vector: staticModel2.embed(text), version: staticModel2.version, dim: staticModel2.dim };
|
|
24108
|
+
}
|
|
24109
|
+
const v = embed(text);
|
|
24110
|
+
return { vector: v, version: EMBEDDING_VERSION, dim: v.length };
|
|
24111
|
+
}
|
|
23923
24112
|
async function embedBatchWithModelOrHash(texts) {
|
|
23924
24113
|
if (texts.length === 0) return [];
|
|
23925
24114
|
if (process.env["ERRATA_EMBED_HASH_ONLY"] === "1") {
|
|
@@ -23928,6 +24117,10 @@ async function embedBatchWithModelOrHash(texts) {
|
|
|
23928
24117
|
return { vector: v, version: EMBEDDING_VERSION, dim: v.length };
|
|
23929
24118
|
});
|
|
23930
24119
|
}
|
|
24120
|
+
const staticModel2 = loadStaticModel();
|
|
24121
|
+
if (staticModel2) {
|
|
24122
|
+
return texts.map((t) => ({ vector: staticModel2.embed(t), version: staticModel2.version, dim: staticModel2.dim }));
|
|
24123
|
+
}
|
|
23931
24124
|
try {
|
|
23932
24125
|
const pipe2 = await ensureModelLoaded();
|
|
23933
24126
|
if (pipe2) {
|
|
@@ -23957,6 +24150,10 @@ async function embedTextWithModelOrHash(text) {
|
|
|
23957
24150
|
const v = embed(text);
|
|
23958
24151
|
return { vector: v, version: EMBEDDING_VERSION, dim: v.length };
|
|
23959
24152
|
}
|
|
24153
|
+
const staticModel2 = loadStaticModel();
|
|
24154
|
+
if (staticModel2) {
|
|
24155
|
+
return { vector: staticModel2.embed(text), version: staticModel2.version, dim: staticModel2.dim };
|
|
24156
|
+
}
|
|
23960
24157
|
try {
|
|
23961
24158
|
const v = await embedTextWithModel(text);
|
|
23962
24159
|
return { vector: v, version: MODEL_EMBEDDING_VERSION, dim: v.length };
|
|
@@ -23971,6 +24168,8 @@ var init_model = __esm({
|
|
|
23971
24168
|
"../../packages/embedding/src/model.ts"() {
|
|
23972
24169
|
"use strict";
|
|
23973
24170
|
init_src4();
|
|
24171
|
+
init_static();
|
|
24172
|
+
init_bands();
|
|
23974
24173
|
MODEL_NAME = "Xenova/all-MiniLM-L6-v2";
|
|
23975
24174
|
MODEL_EMBEDDING_DIM = 384;
|
|
23976
24175
|
MODEL_EMBEDDING_VERSION = "minilm-l6-v2";
|
|
@@ -24035,6 +24234,8 @@ var init_src4 = __esm({
|
|
|
24035
24234
|
"../../packages/embedding/src/index.ts"() {
|
|
24036
24235
|
"use strict";
|
|
24037
24236
|
init_model();
|
|
24237
|
+
init_bands();
|
|
24238
|
+
init_static();
|
|
24038
24239
|
EMBEDDING_DIM = 256;
|
|
24039
24240
|
EMBEDDING_VERSION = "hash-v1";
|
|
24040
24241
|
}
|
|
@@ -24520,9 +24721,8 @@ function mintPatternNode(store, name2, ts) {
|
|
|
24520
24721
|
const emb = embed(display);
|
|
24521
24722
|
let best = null;
|
|
24522
24723
|
let bestCos = 0;
|
|
24523
|
-
for (const p of store.selectNodes({ labels: ["Pattern"]
|
|
24524
|
-
const e = p.
|
|
24525
|
-
if (!e || e.length !== EMBEDDING_DIM) continue;
|
|
24724
|
+
for (const p of store.selectNodes({ labels: ["Pattern"] })) {
|
|
24725
|
+
const e = embed(canonicalizePatternText(p.description));
|
|
24526
24726
|
let d = 0;
|
|
24527
24727
|
for (let i2 = 0; i2 < EMBEDDING_DIM; i2++) d += e[i2] * emb[i2];
|
|
24528
24728
|
if (d > bestCos) {
|
|
@@ -24532,13 +24732,7 @@ function mintPatternNode(store, name2, ts) {
|
|
|
24532
24732
|
}
|
|
24533
24733
|
const bestNode = best && bestCos >= PATTERN_DEDUP_COSINE ? store.getNode(best) : null;
|
|
24534
24734
|
if (bestNode) return reinforce(bestNode, display);
|
|
24535
|
-
store.mergeNode({
|
|
24536
|
-
...buildNode(store, id, "Pattern", display, ts, { source: "convo", provisional: true, observedCount: 1 }),
|
|
24537
|
-
// Embedded inline (sync hash) so the node participates in the gate
|
|
24538
|
-
// immediately — buildNode's empty embedding would leave every new pattern
|
|
24539
|
-
// invisible to dedup until the nightly embed pass.
|
|
24540
|
-
embedding: emb
|
|
24541
|
-
});
|
|
24735
|
+
store.mergeNode(buildNode(store, id, "Pattern", display, ts, { source: "convo", provisional: true, observedCount: 1 }));
|
|
24542
24736
|
return id;
|
|
24543
24737
|
}
|
|
24544
24738
|
function titleCaseDomain(name2) {
|
|
@@ -24899,8 +25093,8 @@ function anchorNodeToDiff(store, nodeId, expectLabel, changedPaths, workspaceId2
|
|
|
24899
25093
|
const n0 = store.getNode(nodeId);
|
|
24900
25094
|
if (!n0 || n0.label !== expectLabel) return 0;
|
|
24901
25095
|
const code = changedPaths.filter((f) => isAnchorableCodePath(f));
|
|
24902
|
-
const
|
|
24903
|
-
if (code.length === 0 || code.length >
|
|
25096
|
+
const cap2 = opts.maxFiles ?? MAX_ANCHOR_FILES;
|
|
25097
|
+
if (code.length === 0 || code.length > cap2) return 0;
|
|
24904
25098
|
const already = new Set(store.outEdges(nodeId, ["ANCHORED_AT"]).map((e) => e.to));
|
|
24905
25099
|
let n = 0;
|
|
24906
25100
|
for (const path3 of code) {
|
|
@@ -27283,14 +27477,15 @@ async function resolveFoldCandidates(store, opts) {
|
|
|
27283
27477
|
if (fresh.embedding.length > 0 && fresh.embedding.length === target.embedding.length && (fresh.attrs["embeddingVersion"] ?? "") === (target.attrs["embeddingVersion"] ?? "")) {
|
|
27284
27478
|
cos = cosine(fresh.embedding, target.embedding);
|
|
27285
27479
|
}
|
|
27286
|
-
|
|
27480
|
+
const bands = cosineBandsFor(fresh.attrs["embeddingVersion"]);
|
|
27481
|
+
if (cos !== null && cos >= bands.dedup) {
|
|
27287
27482
|
if (unseenMark(target)) neverExamined--;
|
|
27288
27483
|
foldPair(store, fresh, target, opts.ts);
|
|
27289
27484
|
report.folded++;
|
|
27290
27485
|
report.foldedEmbedding++;
|
|
27291
27486
|
continue;
|
|
27292
27487
|
}
|
|
27293
|
-
if (cos !== null && cos <
|
|
27488
|
+
if (cos !== null && cos < bands.judgeMin) {
|
|
27294
27489
|
clearCandidate(store, fresh, opts.ts, target.id);
|
|
27295
27490
|
report.rejected++;
|
|
27296
27491
|
continue;
|
|
@@ -27742,6 +27937,24 @@ var init_mechanism_liveness = __esm({
|
|
|
27742
27937
|
effectCounter: "structureLinksMinted",
|
|
27743
27938
|
note: "the answer is the agent's; nothing is inferred"
|
|
27744
27939
|
},
|
|
27940
|
+
{
|
|
27941
|
+
id: "held-ask",
|
|
27942
|
+
what: "asks a session whether a prior it leaned on held; the agent's confirm/refute answers it",
|
|
27943
|
+
pass: "capture",
|
|
27944
|
+
// Opened only by a lean-on cite of a prior the session did not mint —
|
|
27945
|
+
// written-at-all bar. The answers feed confirmedAt/refutedAt locally and
|
|
27946
|
+
// the cloud's corroborate/contradict channels (§5.4 α/β) — the contrastive
|
|
27947
|
+
// verdicts the FEP core needs (docs/reference/plans/fep-core.md §5.7).
|
|
27948
|
+
fed: {
|
|
27949
|
+
labels: ["Problem", "Solution", "RootCause", "Pattern"],
|
|
27950
|
+
attr: "heldAskedAt",
|
|
27951
|
+
minFraction: 0
|
|
27952
|
+
},
|
|
27953
|
+
// Counts only answers to questions a render actually SHOWED — a verdict the
|
|
27954
|
+
// agent would have given unasked does not prove the ask did anything.
|
|
27955
|
+
effectCounter: "heldAnswered",
|
|
27956
|
+
note: "asked, never inferred; the lean is provisional while asked and replaced by the answer; Network-only priors are asked by id"
|
|
27957
|
+
},
|
|
27745
27958
|
{
|
|
27746
27959
|
id: "regression-recognize",
|
|
27747
27960
|
what: "marks a resolved problem as resolutionSuspect when it recurs at the door",
|
|
@@ -28736,6 +28949,18 @@ function renderSnapshot(s) {
|
|
|
28736
28949
|
}
|
|
28737
28950
|
lines.push("");
|
|
28738
28951
|
}
|
|
28952
|
+
if (s.heldAsks?.length) {
|
|
28953
|
+
lines.push("### \u{1F9EA} Did it hold?");
|
|
28954
|
+
lines.push(
|
|
28955
|
+
"_You leaned on these priors this session. Once you know whether each one held up in your work, say so \u2014 a prior nobody judges ranks the same whether it worked or not:_"
|
|
28956
|
+
);
|
|
28957
|
+
for (const p of s.heldAsks) {
|
|
28958
|
+
const what = p.description ? `**${p.description}** \u2014 \`${p.id}\`` : `\`${p.id}\``;
|
|
28959
|
+
lines.push(`- ${what}${p.lifecycle ? ` _(${p.lifecycle})_` : ""}`);
|
|
28960
|
+
lines.push(` - it held \u2192 ${TAG_VERDICT_TOKENS.confirm(p.id)} \xB7 it didn't \u2192 ${TAG_VERDICT_TOKENS.refute(p.id)}`);
|
|
28961
|
+
}
|
|
28962
|
+
lines.push("");
|
|
28963
|
+
}
|
|
28739
28964
|
lines.push("### Recently observed problems in this workspace");
|
|
28740
28965
|
if (s.recentProblems.length === 0 && s.recentResolved.length === 0 && s.recentConstraints.length === 0 && s.regressions.length === 0) {
|
|
28741
28966
|
lines.push("- _none yet \u2014 errata is still building its model_");
|
|
@@ -29039,6 +29264,7 @@ function isolateSnapshot(s) {
|
|
|
29039
29264
|
statedIntent: _statedIntent,
|
|
29040
29265
|
selfCiteSkips: _selfCiteSkips,
|
|
29041
29266
|
supersessionAsks: _supersessionAsks,
|
|
29267
|
+
heldAsks: _heldAsks,
|
|
29042
29268
|
pendingUpdate: _pendingUpdate,
|
|
29043
29269
|
daemonDistress: _daemonDistress,
|
|
29044
29270
|
reviewItems: _reviewItems,
|
|
@@ -29239,8 +29465,8 @@ var init_bleed_memory = __esm({
|
|
|
29239
29465
|
});
|
|
29240
29466
|
|
|
29241
29467
|
// ../../packages/context-writer/src/bleed-rules.ts
|
|
29242
|
-
import { existsSync as
|
|
29243
|
-
import { join as
|
|
29468
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync4, readdirSync, readFileSync as readFileSync4, rmSync, writeFileSync as writeFileSync4 } from "node:fs";
|
|
29469
|
+
import { join as join5 } from "node:path";
|
|
29244
29470
|
function formatRuleFile(item2) {
|
|
29245
29471
|
const frontmatter = item2.paths && item2.paths.length > 0 ? `---
|
|
29246
29472
|
paths:
|
|
@@ -29253,21 +29479,21 @@ ${item2.body.trim()}
|
|
|
29253
29479
|
`;
|
|
29254
29480
|
}
|
|
29255
29481
|
function bleedRules(rulesDir, items) {
|
|
29256
|
-
if (!
|
|
29482
|
+
if (!existsSync6(rulesDir)) mkdirSync4(rulesDir, { recursive: true });
|
|
29257
29483
|
const wanted = new Map(items.map((i2) => [fileFor(i2.slug), i2]));
|
|
29258
29484
|
let written = 0;
|
|
29259
29485
|
let created = 0;
|
|
29260
29486
|
for (const [file2, item2] of wanted) {
|
|
29261
|
-
const path3 =
|
|
29262
|
-
if (!
|
|
29487
|
+
const path3 = join5(rulesDir, file2);
|
|
29488
|
+
if (!existsSync6(path3)) created++;
|
|
29263
29489
|
writeFileSync4(path3, formatRuleFile(item2), "utf8");
|
|
29264
29490
|
written++;
|
|
29265
29491
|
}
|
|
29266
29492
|
let pruned = 0;
|
|
29267
29493
|
for (const f of readdirSync(rulesDir)) {
|
|
29268
29494
|
if (!f.startsWith(PREFIX) || !f.endsWith(".md") || wanted.has(f)) continue;
|
|
29269
|
-
if (
|
|
29270
|
-
rmSync(
|
|
29495
|
+
if (readFileSync4(join5(rulesDir, f), "utf8").includes(MARKER)) {
|
|
29496
|
+
rmSync(join5(rulesDir, f));
|
|
29271
29497
|
pruned++;
|
|
29272
29498
|
}
|
|
29273
29499
|
}
|
|
@@ -30650,9 +30876,9 @@ var init_src7 = __esm({
|
|
|
30650
30876
|
// src/owner-only-file.ts
|
|
30651
30877
|
import { chmodSync, statSync } from "node:fs";
|
|
30652
30878
|
import { execFileSync } from "node:child_process";
|
|
30653
|
-
import { join as
|
|
30879
|
+
import { join as join6 } from "node:path";
|
|
30654
30880
|
function system32(exe) {
|
|
30655
|
-
return
|
|
30881
|
+
return join6(process.env["SystemRoot"] ?? "C:\\Windows", "System32", exe);
|
|
30656
30882
|
}
|
|
30657
30883
|
function parseWhoamiSid(output) {
|
|
30658
30884
|
const match2 = /"(S-1-\d+(?:-\d+)+)"/.exec(output);
|
|
@@ -30797,33 +31023,33 @@ __export(paths_exports, {
|
|
|
30797
31023
|
});
|
|
30798
31024
|
import { execFile } from "node:child_process";
|
|
30799
31025
|
import { mkdirSync as mkdirSync5 } from "node:fs";
|
|
30800
|
-
import { dirname as
|
|
31026
|
+
import { dirname as dirname6, join as join7 } from "node:path";
|
|
30801
31027
|
function globalDir() {
|
|
30802
31028
|
const p = envPaths("errata", { suffix: "" });
|
|
30803
31029
|
return p.config;
|
|
30804
31030
|
}
|
|
30805
31031
|
function globalConfigPath() {
|
|
30806
|
-
return process.env["ERRATA_CONFIG_PATH"] ??
|
|
31032
|
+
return process.env["ERRATA_CONFIG_PATH"] ?? join7(globalDir(), "config.json");
|
|
30807
31033
|
}
|
|
30808
31034
|
function daemonLogPath() {
|
|
30809
31035
|
mkdirSync5(globalDir(), { recursive: true });
|
|
30810
|
-
return
|
|
31036
|
+
return join7(globalDir(), "daemon.log");
|
|
30811
31037
|
}
|
|
30812
31038
|
function globalDaemonLock() {
|
|
30813
|
-
return process.env["ERRATA_DAEMON_LOCK"] ??
|
|
31039
|
+
return process.env["ERRATA_DAEMON_LOCK"] ?? join7(globalDir(), "daemon.lock");
|
|
30814
31040
|
}
|
|
30815
31041
|
function sharedStorePath() {
|
|
30816
|
-
return process.env["ERRATA_SHARED_DB"] ??
|
|
31042
|
+
return process.env["ERRATA_SHARED_DB"] ?? join7(globalDir(), "shared", "graph.db");
|
|
30817
31043
|
}
|
|
30818
31044
|
function workspaceDir(workspaceRoot) {
|
|
30819
|
-
return
|
|
31045
|
+
return join7(workspaceRoot, ".errata");
|
|
30820
31046
|
}
|
|
30821
31047
|
function ensureDir(p) {
|
|
30822
31048
|
mkdirSync5(p, { recursive: true });
|
|
30823
31049
|
return p;
|
|
30824
31050
|
}
|
|
30825
31051
|
function ensureParent(p) {
|
|
30826
|
-
mkdirSync5(
|
|
31052
|
+
mkdirSync5(dirname6(p), { recursive: true });
|
|
30827
31053
|
return p;
|
|
30828
31054
|
}
|
|
30829
31055
|
function attribHasNotIndexed(attribOutput, path3) {
|
|
@@ -30834,7 +31060,7 @@ function excludeFromIndexing(dir, run3 = execFile) {
|
|
|
30834
31060
|
if (process.platform !== "win32") return;
|
|
30835
31061
|
run3("attrib", [dir], { windowsHide: true }, (err2, stdout) => {
|
|
30836
31062
|
if (err2 || attribHasNotIndexed(String(stdout), dir)) return;
|
|
30837
|
-
run3("attrib", ["+I",
|
|
31063
|
+
run3("attrib", ["+I", join7(dir, "*"), "/S", "/D"], { windowsHide: true }, () => {
|
|
30838
31064
|
run3("attrib", ["+I", dir], { windowsHide: true }, () => {
|
|
30839
31065
|
});
|
|
30840
31066
|
});
|
|
@@ -30845,15 +31071,15 @@ function workspacePaths(root) {
|
|
|
30845
31071
|
return {
|
|
30846
31072
|
root,
|
|
30847
31073
|
configDir: dir,
|
|
30848
|
-
workspaceJson:
|
|
30849
|
-
eventLog:
|
|
30850
|
-
castalia:
|
|
30851
|
-
reviewQueue:
|
|
30852
|
-
outbox:
|
|
30853
|
-
daemonLock:
|
|
30854
|
-
identityAudit:
|
|
30855
|
-
skillsDir:
|
|
30856
|
-
skillsManifest:
|
|
31074
|
+
workspaceJson: join7(dir, "workspace.json"),
|
|
31075
|
+
eventLog: join7(dir, "eventlog.sqlite"),
|
|
31076
|
+
castalia: join7(dir, "castalia.db"),
|
|
31077
|
+
reviewQueue: join7(dir, "review-queue.json"),
|
|
31078
|
+
outbox: join7(dir, "outbox"),
|
|
31079
|
+
daemonLock: join7(dir, "daemon.lock"),
|
|
31080
|
+
identityAudit: join7(dir, "identity-audit.log"),
|
|
31081
|
+
skillsDir: join7(dir, "skills"),
|
|
31082
|
+
skillsManifest: join7(dir, "skills.json")
|
|
30857
31083
|
};
|
|
30858
31084
|
}
|
|
30859
31085
|
var init_paths = __esm({
|
|
@@ -30864,7 +31090,7 @@ var init_paths = __esm({
|
|
|
30864
31090
|
});
|
|
30865
31091
|
|
|
30866
31092
|
// src/config.ts
|
|
30867
|
-
import { existsSync as
|
|
31093
|
+
import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "node:fs";
|
|
30868
31094
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
30869
31095
|
function mcpUrlFor(cloudUrl) {
|
|
30870
31096
|
return `${cloudUrl.replace(/\/+$/, "")}/mcp`;
|
|
@@ -30896,13 +31122,13 @@ function defaultConfig() {
|
|
|
30896
31122
|
}
|
|
30897
31123
|
function loadConfig() {
|
|
30898
31124
|
const p = globalConfigPath();
|
|
30899
|
-
if (!
|
|
31125
|
+
if (!existsSync7(p)) {
|
|
30900
31126
|
ensureDir(globalDir());
|
|
30901
31127
|
const cfg = defaultConfig();
|
|
30902
31128
|
saveConfig({ ...cfg, cloudUrl: DEFAULT_CLOUD_URL });
|
|
30903
31129
|
return cfg;
|
|
30904
31130
|
}
|
|
30905
|
-
const raw2 =
|
|
31131
|
+
const raw2 = readFileSync5(p, "utf8").replace(/^\uFEFF/, "");
|
|
30906
31132
|
const parsed = JSON.parse(raw2);
|
|
30907
31133
|
const base = defaultConfig();
|
|
30908
31134
|
const envCloudUrl = process.env["ERRATA_CLOUD_URL"];
|
|
@@ -33817,13 +34043,16 @@ var init_review_detector = __esm({
|
|
|
33817
34043
|
|
|
33818
34044
|
// ../../packages/generalizer/src/nemori-gate.ts
|
|
33819
34045
|
function nemoriDecide(input) {
|
|
33820
|
-
|
|
34046
|
+
const dedup = input.bands?.dedup ?? NEMORI_DEDUP_COSINE;
|
|
34047
|
+
const softWriteMin = input.bands?.softWriteMin ?? NEMORI_SOFT_WRITE_MIN_COSINE;
|
|
34048
|
+
const softWriteMax = input.bands ? dedup : NEMORI_SOFT_WRITE_MAX_COSINE;
|
|
34049
|
+
if (input.topCosine >= dedup && input.topId) {
|
|
33821
34050
|
return { kind: "REINFORCE", existingId: input.topId };
|
|
33822
34051
|
}
|
|
33823
34052
|
if (input.surprise >= NEMORI_HIGH_SURPRISE_THRESHOLD) {
|
|
33824
34053
|
return { kind: "WRITE_FULL", reason: "high-surprise" };
|
|
33825
34054
|
}
|
|
33826
|
-
const inSoftBand = input.topCosine >=
|
|
34055
|
+
const inSoftBand = input.topCosine >= softWriteMin && input.topCosine < softWriteMax;
|
|
33827
34056
|
if (input.isPredicted || inSoftBand) {
|
|
33828
34057
|
const s = Math.max(0, Math.min(1, input.surprise));
|
|
33829
34058
|
const alpha = NEMORI_SOFT_ALPHA_MIN + (NEMORI_SOFT_ALPHA_MAX - NEMORI_SOFT_ALPHA_MIN) * s;
|
|
@@ -33926,7 +34155,7 @@ var init_diagnostic_matcher = __esm({
|
|
|
33926
34155
|
});
|
|
33927
34156
|
|
|
33928
34157
|
// ../../packages/generalizer/src/generalizer.ts
|
|
33929
|
-
import { isAbsolute, join as
|
|
34158
|
+
import { isAbsolute, join as join8, relative } from "node:path";
|
|
33930
34159
|
async function runGeneralizer(opts) {
|
|
33931
34160
|
const report = {
|
|
33932
34161
|
eventsProcessed: 0,
|
|
@@ -34034,7 +34263,7 @@ function extractDiagnostics(ev) {
|
|
|
34034
34263
|
function diagRelPath(file2, cwd, workspaceRoot) {
|
|
34035
34264
|
const norm = (p) => p.replace(/\\/g, "/");
|
|
34036
34265
|
if (!workspaceRoot) return norm(file2);
|
|
34037
|
-
const abs = isAbsolute(file2) ? file2 :
|
|
34266
|
+
const abs = isAbsolute(file2) ? file2 : join8(cwd ?? workspaceRoot, file2);
|
|
34038
34267
|
return norm(relative(workspaceRoot, abs));
|
|
34039
34268
|
}
|
|
34040
34269
|
function extractErrorSignature(ev) {
|
|
@@ -34066,7 +34295,10 @@ function rankOpenProblemNeighbors(store, embedding, limit = 5) {
|
|
|
34066
34295
|
where: [{ embedding: embedding.vector.length > 0 ? "present" : "absent" }],
|
|
34067
34296
|
withEmbedding: true
|
|
34068
34297
|
}).filter(
|
|
34069
|
-
(p) => p.embedding.length === embedding.vector.length &&
|
|
34298
|
+
(p) => p.embedding.length === embedding.vector.length && // Unversioned vectors predate the model embedders: they are hash-v1. The
|
|
34299
|
+
// old "unversioned matches anything" leaned on hash-v1 (256-d) never
|
|
34300
|
+
// sharing a length with the model; potion-8m-q8 is 256-d too.
|
|
34301
|
+
String(p.attrs["embeddingVersion"] ?? EMBEDDING_VERSION) === embedding.version
|
|
34070
34302
|
).map((p) => ({ id: p.id, score: cosine(embedding.vector, p.embedding) })).sort((a, b) => b.score - a.score).slice(0, limit).map(({ id, score: score2 }) => {
|
|
34071
34303
|
const p = store.getNode(id);
|
|
34072
34304
|
return {
|
|
@@ -34079,8 +34311,6 @@ function rankOpenProblemNeighbors(store, embedding, limit = 5) {
|
|
|
34079
34311
|
});
|
|
34080
34312
|
}
|
|
34081
34313
|
function mergeProblemsByEmbedding(store, opts) {
|
|
34082
|
-
const minCosine = opts.minCosine ?? NEMORI_DEDUP_COSINE;
|
|
34083
|
-
const NEAR_MISS_FLOOR = 0.72;
|
|
34084
34314
|
const report = { clusters: 0, merged: 0, nearMissMarked: 0 };
|
|
34085
34315
|
if (opts.freshSince !== void 0 && store.countNodes({ labels: ["Problem"], where: [...OPEN_UNMERGED, HAS_VECTOR, { column: "created_at", gt: opts.freshSince }] }) === 0) {
|
|
34086
34316
|
return report;
|
|
@@ -34105,10 +34335,11 @@ function mergeProblemsByEmbedding(store, opts) {
|
|
|
34105
34335
|
if ((a.attrs["embeddingVersion"] ?? "") !== (b.attrs["embeddingVersion"] ?? "")) continue;
|
|
34106
34336
|
if (isConstraintProblem(a) !== isConstraintProblem(b)) continue;
|
|
34107
34337
|
const cos = cosine(a.embedding, b.embedding);
|
|
34108
|
-
|
|
34338
|
+
const bands = bandsOf(a);
|
|
34339
|
+
if (cos >= (opts.minCosine ?? bands.dedup)) {
|
|
34109
34340
|
cluster.push(b);
|
|
34110
34341
|
consumed.add(b.id);
|
|
34111
|
-
} else if (cos >=
|
|
34342
|
+
} else if (cos >= bands.nearMiss) {
|
|
34112
34343
|
const [younger, elder] = a.createdAt >= b.createdAt ? [a, b] : [b, a];
|
|
34113
34344
|
actions.push({ kind: "mark", younger: younger.id, elder: elder.id, cos });
|
|
34114
34345
|
}
|
|
@@ -34142,7 +34373,6 @@ function mergeProblemsByEmbedding(store, opts) {
|
|
|
34142
34373
|
return report;
|
|
34143
34374
|
}
|
|
34144
34375
|
function bindResolvedRegressions(store, opts) {
|
|
34145
|
-
const minCosine = opts.minCosine ?? NEMORI_DEDUP_COSINE;
|
|
34146
34376
|
const watermarkRaw = store.getMeta?.("regression_sweep_at") ?? null;
|
|
34147
34377
|
const full = watermarkRaw === null;
|
|
34148
34378
|
const since = full ? 0 : Number(watermarkRaw) || 0;
|
|
@@ -34172,7 +34402,7 @@ function bindResolvedRegressions(store, opts) {
|
|
|
34172
34402
|
if ((r.attrs["embeddingVersion"] ?? "") !== (f.attrs["embeddingVersion"] ?? "")) continue;
|
|
34173
34403
|
if (isConstraintProblem(f) !== isConstraintProblem(r)) continue;
|
|
34174
34404
|
const s = cosine(f.embedding, r.embedding);
|
|
34175
|
-
if (s >= minCosine && (!best || s > best.s)) best = { node: r, s };
|
|
34405
|
+
if (s >= (opts.minCosine ?? bandsOf(f).dedup) && (!best || s > best.s)) best = { node: r, s };
|
|
34176
34406
|
}
|
|
34177
34407
|
if (!best) continue;
|
|
34178
34408
|
if (store.outEdges(f.id, ["REGRESSION_OF"]).some((e) => e.to === best.node.id)) continue;
|
|
@@ -34221,13 +34451,14 @@ function bindCanonicalNeighbors(store, opts) {
|
|
|
34221
34451
|
store.outEdges(p.id, ["MATCHES", "INSTANCE_OF", "RELATES_TO"]).map((e) => e.to)
|
|
34222
34452
|
);
|
|
34223
34453
|
if (existing.size >= k) continue;
|
|
34454
|
+
const bands = bandsOf(p);
|
|
34224
34455
|
const ranked2 = pool.filter(
|
|
34225
34456
|
(c) => c.id !== p.id && !existing.has(c.id) && c.embedding.length === p.embedding.length && (c.attrs["embeddingVersion"] ?? "") === (p.attrs["embeddingVersion"] ?? "")
|
|
34226
|
-
).map((c) => ({ c, s: cosine(p.embedding, c.embedding) })).filter((x) => x.s >=
|
|
34457
|
+
).map((c) => ({ c, s: cosine(p.embedding, c.embedding) })).filter((x) => x.s >= bands.bindMin && x.s < bands.dedup).sort((a, b) => b.s - a.s);
|
|
34227
34458
|
const picked = [];
|
|
34228
34459
|
for (const cand of ranked2) {
|
|
34229
34460
|
if (picked.length + existing.size >= k) break;
|
|
34230
|
-
if (picked.some((q) => cosine(q.c.embedding, cand.c.embedding) >=
|
|
34461
|
+
if (picked.some((q) => cosine(q.c.embedding, cand.c.embedding) >= bands.dedup)) continue;
|
|
34231
34462
|
picked.push(cand);
|
|
34232
34463
|
}
|
|
34233
34464
|
for (const { c, s } of picked) {
|
|
@@ -34279,6 +34510,7 @@ async function ingestErrorSignature(opts, sig, commandSig) {
|
|
|
34279
34510
|
topCosine = 1;
|
|
34280
34511
|
topId = openMatch.id;
|
|
34281
34512
|
}
|
|
34513
|
+
const bands = cosineBandsFor(candidateEmbedding.version);
|
|
34282
34514
|
const titans = titansSurpriseFromNeighbors(neighbors);
|
|
34283
34515
|
const decision = nemoriDecide({
|
|
34284
34516
|
surprise: titans.surprise,
|
|
@@ -34287,7 +34519,8 @@ async function ingestErrorSignature(opts, sig, commandSig) {
|
|
|
34287
34519
|
// The prior (the neighbor search above) anticipated this if it surfaced a
|
|
34288
34520
|
// real neighbor — not just embedding noise. Below the soft band, so a
|
|
34289
34521
|
// low-surprise predicted observation dampens instead of writing full.
|
|
34290
|
-
isPredicted: topId !== null && topCosine >=
|
|
34522
|
+
isPredicted: topId !== null && topCosine >= bands.predictionFloor,
|
|
34523
|
+
bands
|
|
34291
34524
|
});
|
|
34292
34525
|
let node2;
|
|
34293
34526
|
const prevTier = openMatch?.memoryTier;
|
|
@@ -34952,7 +35185,7 @@ function reconcileDiagnostics(store, workspaceId2, relPath, diags, t, command) {
|
|
|
34952
35185
|
}
|
|
34953
35186
|
return { opened, resolved };
|
|
34954
35187
|
}
|
|
34955
|
-
var GENERALIZER_CURSOR, GENERALIZER_KINDS, GENERALIZER_BATCH, OPEN_UNMERGED, HAS_VECTOR,
|
|
35188
|
+
var bandsOf, GENERALIZER_CURSOR, GENERALIZER_KINDS, GENERALIZER_BATCH, OPEN_UNMERGED, HAS_VECTOR, ANCHOR_LABELS2, DIAG_SEVERITY_ERROR;
|
|
34956
35189
|
var init_generalizer = __esm({
|
|
34957
35190
|
"../../packages/generalizer/src/generalizer.ts"() {
|
|
34958
35191
|
"use strict";
|
|
@@ -34965,6 +35198,7 @@ var init_generalizer = __esm({
|
|
|
34965
35198
|
init_review_detector();
|
|
34966
35199
|
init_nemori_gate();
|
|
34967
35200
|
init_diagnostic_matcher();
|
|
35201
|
+
bandsOf = (n) => cosineBandsFor(n.attrs["embeddingVersion"]);
|
|
34968
35202
|
GENERALIZER_CURSOR = "generalizer";
|
|
34969
35203
|
GENERALIZER_KINDS = [
|
|
34970
35204
|
"shell.command",
|
|
@@ -34977,7 +35211,6 @@ var init_generalizer = __esm({
|
|
|
34977
35211
|
{ attr: "mergedInto", absent: true }
|
|
34978
35212
|
];
|
|
34979
35213
|
HAS_VECTOR = { embedding: "present" };
|
|
34980
|
-
CANONICAL_BIND_MIN = 0.78;
|
|
34981
35214
|
ANCHOR_LABELS2 = ["Function", "Method", "Class"];
|
|
34982
35215
|
DIAG_SEVERITY_ERROR = 1;
|
|
34983
35216
|
}
|
|
@@ -35215,13 +35448,13 @@ function runGraphRescore(store, opts = {}) {
|
|
|
35215
35448
|
function tryIncrementalRescore(store, lastRescoreAt, started2) {
|
|
35216
35449
|
const allowedTypes = new Set(pagerankEdgeTypes());
|
|
35217
35450
|
const liveN = store.nodeCount();
|
|
35218
|
-
const
|
|
35451
|
+
const cap2 = Math.max(1e3, Math.floor(liveN * INCREMENTAL_REGION_MAX_FRACTION));
|
|
35219
35452
|
const region = new Set(store.dirtyNodeIdsSince(lastRescoreAt));
|
|
35220
35453
|
for (const e of store.edgeEndpointsTouchedSince(lastRescoreAt)) {
|
|
35221
35454
|
region.add(e.from);
|
|
35222
35455
|
region.add(e.to);
|
|
35223
35456
|
}
|
|
35224
|
-
if (region.size >
|
|
35457
|
+
if (region.size > cap2) return null;
|
|
35225
35458
|
let frontier = [...region];
|
|
35226
35459
|
for (let hop = 0; hop < INCREMENTAL_HOPS && frontier.length > 0; hop++) {
|
|
35227
35460
|
const next = [];
|
|
@@ -35232,7 +35465,7 @@ function tryIncrementalRescore(store, lastRescoreAt, started2) {
|
|
|
35232
35465
|
next.push(e.to);
|
|
35233
35466
|
}
|
|
35234
35467
|
}
|
|
35235
|
-
if (region.size >
|
|
35468
|
+
if (region.size > cap2) return null;
|
|
35236
35469
|
frontier = next;
|
|
35237
35470
|
}
|
|
35238
35471
|
const rank0 = store.ranksForMany([...region]);
|
|
@@ -35269,7 +35502,7 @@ function tryIncrementalRescore(store, lastRescoreAt, started2) {
|
|
|
35269
35502
|
}
|
|
35270
35503
|
const boundaryEdges = store.inEdgesForMany(regionIds).filter((e) => allowedTypes.has(e.type) && !inRegion.has(e.from) && (EDGE_WEIGHT[e.type] ?? 1) > 0);
|
|
35271
35504
|
const boundarySources = [...new Set(boundaryEdges.map((e) => e.from))];
|
|
35272
|
-
if (boundarySources.length >
|
|
35505
|
+
if (boundarySources.length > cap2) return null;
|
|
35273
35506
|
const boundaryRanks = store.ranksForMany(boundarySources);
|
|
35274
35507
|
const boundaryOutSum = /* @__PURE__ */ new Map();
|
|
35275
35508
|
for (const e of store.outEdgesForMany(boundarySources)) {
|
|
@@ -35508,8 +35741,7 @@ async function ensureNodeEmbedded(store, nodeId, opts = {}) {
|
|
|
35508
35741
|
let result;
|
|
35509
35742
|
try {
|
|
35510
35743
|
if (opts.mode === "hash") {
|
|
35511
|
-
|
|
35512
|
-
result = { vector: v, version: EMBEDDING_VERSION, dim: v.length };
|
|
35744
|
+
result = embedTextSync(text);
|
|
35513
35745
|
} else {
|
|
35514
35746
|
const r = (await embedBatchWithModelOrHash([text]))[0];
|
|
35515
35747
|
if (!r) return false;
|
|
@@ -35605,11 +35837,11 @@ async function embedNodesByLabels(store, labels, opts = {}) {
|
|
|
35605
35837
|
}
|
|
35606
35838
|
}
|
|
35607
35839
|
if (candidates.length === 0) {
|
|
35608
|
-
complete(held?.version ?? (hashOnly ?
|
|
35840
|
+
complete(held?.version ?? (hashOnly ? embedTextSync("").version : null));
|
|
35609
35841
|
report.durationMs = Date.now() - started2;
|
|
35610
35842
|
return report;
|
|
35611
35843
|
}
|
|
35612
|
-
const currentVersion = hashOnly ?
|
|
35844
|
+
const currentVersion = hashOnly ? embedTextSync("probe").version : (await embedBatchWithModelOrHash(["probe"]))[0]?.version ?? "unknown";
|
|
35613
35845
|
if (changedIds !== null && held?.version && held.version !== currentVersion) {
|
|
35614
35846
|
const { incrementalKey: _incremental, ...fullOpts } = opts;
|
|
35615
35847
|
return embedNodesByLabels(store, labels, fullOpts).then((full) => {
|
|
@@ -35632,10 +35864,7 @@ async function embedNodesByLabels(store, labels, opts = {}) {
|
|
|
35632
35864
|
const batch = todo.slice(i2, i2 + BATCH_SIZE);
|
|
35633
35865
|
let results;
|
|
35634
35866
|
try {
|
|
35635
|
-
results = hashOnly ? batch.map((b) =>
|
|
35636
|
-
const v = embed(b.text);
|
|
35637
|
-
return { vector: v, version: EMBEDDING_VERSION, dim: v.length };
|
|
35638
|
-
}) : await embedBatchWithModelOrHash(batch.map((b) => b.text));
|
|
35867
|
+
results = hashOnly ? batch.map((b) => embedTextSync(b.text)) : await embedBatchWithModelOrHash(batch.map((b) => b.text));
|
|
35639
35868
|
} catch {
|
|
35640
35869
|
report.failed += batch.length;
|
|
35641
35870
|
continue;
|
|
@@ -35711,7 +35940,7 @@ function nodeFreshness(node2, currentIngestSeq) {
|
|
|
35711
35940
|
});
|
|
35712
35941
|
}
|
|
35713
35942
|
function scoreCandidate(candidate, ctx = {}, weights) {
|
|
35714
|
-
const sameVersion =
|
|
35943
|
+
const sameVersion = String(candidate.attrs["embeddingVersion"] ?? EMBEDDING_VERSION) === String(ctx.seedEmbeddingVersion ?? EMBEDDING_VERSION);
|
|
35715
35944
|
const comparable = ctx.seedEmbedding != null && candidate.embedding.length === ctx.seedEmbedding.length && sameVersion;
|
|
35716
35945
|
const semantic = comparable ? cosine(ctx.seedEmbedding, candidate.embedding) : void 0;
|
|
35717
35946
|
const semanticUnknown = ctx.seedEmbedding != null && !comparable;
|
|
@@ -36353,8 +36582,8 @@ var init_recall_card = __esm({
|
|
|
36353
36582
|
});
|
|
36354
36583
|
|
|
36355
36584
|
// src/recall-signal.ts
|
|
36356
|
-
import { existsSync as
|
|
36357
|
-
import { join as
|
|
36585
|
+
import { existsSync as existsSync8, readFileSync as readFileSync6, writeFileSync as writeFileSync6 } from "node:fs";
|
|
36586
|
+
import { join as join9 } from "node:path";
|
|
36358
36587
|
function live(n) {
|
|
36359
36588
|
return n != null && n.validTo == null && historyReadPolicy(n, { mode: "passive" }).allow;
|
|
36360
36589
|
}
|
|
@@ -36423,17 +36652,17 @@ function contextCard(store, snapshot) {
|
|
|
36423
36652
|
return deliveredCard(store, intent ? `${count2} for \u201C${clipIntent(intent)}\u201D` : `${count2} in context`, delivered);
|
|
36424
36653
|
}
|
|
36425
36654
|
function writeContextCard(root, hash2, card) {
|
|
36426
|
-
writeFileSync6(
|
|
36655
|
+
writeFileSync6(join9(root, ".errata", CONTEXT_CARD_FILE), JSON.stringify({
|
|
36427
36656
|
hash: hash2,
|
|
36428
36657
|
card,
|
|
36429
36658
|
line: card && recallCardEnabled() ? renderRecallLine(card) : null
|
|
36430
36659
|
}));
|
|
36431
36660
|
}
|
|
36432
36661
|
function readContextCard(root, hash2) {
|
|
36433
|
-
const path3 =
|
|
36434
|
-
if (!
|
|
36662
|
+
const path3 = join9(root, ".errata", CONTEXT_CARD_FILE);
|
|
36663
|
+
if (!existsSync8(path3)) return null;
|
|
36435
36664
|
try {
|
|
36436
|
-
const saved = JSON.parse(
|
|
36665
|
+
const saved = JSON.parse(readFileSync6(path3, "utf8"));
|
|
36437
36666
|
return saved.hash === hash2 ? saved.card ?? null : null;
|
|
36438
36667
|
} catch {
|
|
36439
36668
|
return null;
|
|
@@ -36501,9 +36730,9 @@ var init_recall_signal = __esm({
|
|
|
36501
36730
|
});
|
|
36502
36731
|
|
|
36503
36732
|
// src/session-registry.ts
|
|
36504
|
-
import { existsSync as
|
|
36733
|
+
import { existsSync as existsSync9, readFileSync as readFileSync7, realpathSync, writeFileSync as writeFileSync7 } from "node:fs";
|
|
36505
36734
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
36506
|
-
import { basename as basename2, dirname as
|
|
36735
|
+
import { basename as basename2, dirname as dirname7, resolve } from "node:path";
|
|
36507
36736
|
function shipsFromWorkspace(root, env2 = process.env) {
|
|
36508
36737
|
return Boolean(env2["VITEST"]) || !isScratchWorkspace(root);
|
|
36509
36738
|
}
|
|
@@ -36511,8 +36740,8 @@ function isScratchWorkspace(root, tmp = tmpdir2()) {
|
|
|
36511
36740
|
const norm = (p) => {
|
|
36512
36741
|
let cursor = resolve(p);
|
|
36513
36742
|
const suffix = [];
|
|
36514
|
-
while (!
|
|
36515
|
-
const parent =
|
|
36743
|
+
while (!existsSync9(cursor)) {
|
|
36744
|
+
const parent = dirname7(cursor);
|
|
36516
36745
|
if (parent === cursor) break;
|
|
36517
36746
|
suffix.unshift(basename2(cursor));
|
|
36518
36747
|
cursor = parent;
|
|
@@ -36595,9 +36824,9 @@ function createSessionRegistry(opts = {}) {
|
|
|
36595
36824
|
return registry2;
|
|
36596
36825
|
}
|
|
36597
36826
|
function loadOrigins(path3) {
|
|
36598
|
-
if (!path3 || !
|
|
36827
|
+
if (!path3 || !existsSync9(path3)) return [];
|
|
36599
36828
|
try {
|
|
36600
|
-
const raw2 = JSON.parse(
|
|
36829
|
+
const raw2 = JSON.parse(readFileSync7(path3, "utf8"));
|
|
36601
36830
|
return Object.entries(raw2).flatMap(([k, v]) => typeof v === "string" ? [[k, v]] : []);
|
|
36602
36831
|
} catch {
|
|
36603
36832
|
return [];
|
|
@@ -36632,11 +36861,11 @@ var init_session_registry = __esm({
|
|
|
36632
36861
|
});
|
|
36633
36862
|
|
|
36634
36863
|
// src/review.ts
|
|
36635
|
-
import { existsSync as
|
|
36864
|
+
import { existsSync as existsSync10, readFileSync as readFileSync8, writeFileSync as writeFileSync8 } from "node:fs";
|
|
36636
36865
|
function loadReviewQueue(paths) {
|
|
36637
|
-
if (!
|
|
36866
|
+
if (!existsSync10(paths.reviewQueue)) return [];
|
|
36638
36867
|
try {
|
|
36639
|
-
return JSON.parse(
|
|
36868
|
+
return JSON.parse(readFileSync8(paths.reviewQueue, "utf8"));
|
|
36640
36869
|
} catch {
|
|
36641
36870
|
return [];
|
|
36642
36871
|
}
|
|
@@ -36713,14 +36942,14 @@ var init_consent = __esm({
|
|
|
36713
36942
|
|
|
36714
36943
|
// src/git-remote.ts
|
|
36715
36944
|
import { spawnSync } from "node:child_process";
|
|
36716
|
-
import { existsSync as
|
|
36717
|
-
import { isAbsolute as isAbsolute2, join as
|
|
36945
|
+
import { existsSync as existsSync11, readFileSync as readFileSync9, statSync as statSync3 } from "node:fs";
|
|
36946
|
+
import { isAbsolute as isAbsolute2, join as join10, resolve as resolve2 } from "node:path";
|
|
36718
36947
|
function resolveGitDir(root) {
|
|
36719
|
-
const dotGit =
|
|
36948
|
+
const dotGit = join10(root, ".git");
|
|
36720
36949
|
try {
|
|
36721
36950
|
const st = statSync3(dotGit);
|
|
36722
36951
|
if (st.isDirectory()) return dotGit;
|
|
36723
|
-
const m = /^gitdir:\s*(.+?)\s*$/m.exec(
|
|
36952
|
+
const m = /^gitdir:\s*(.+?)\s*$/m.exec(readFileSync9(dotGit, "utf8"));
|
|
36724
36953
|
if (!m) return null;
|
|
36725
36954
|
const dir = m[1];
|
|
36726
36955
|
return isAbsolute2(dir) ? dir : resolve2(root, dir);
|
|
@@ -36729,22 +36958,22 @@ function resolveGitDir(root) {
|
|
|
36729
36958
|
}
|
|
36730
36959
|
}
|
|
36731
36960
|
function gitConfigPath(gitDir) {
|
|
36732
|
-
const commondirFile =
|
|
36733
|
-
if (
|
|
36734
|
-
const common =
|
|
36961
|
+
const commondirFile = join10(gitDir, "commondir");
|
|
36962
|
+
if (existsSync11(commondirFile)) {
|
|
36963
|
+
const common = readFileSync9(commondirFile, "utf8").trim();
|
|
36735
36964
|
const commonDir = isAbsolute2(common) ? common : resolve2(gitDir, common);
|
|
36736
|
-
return
|
|
36965
|
+
return join10(commonDir, "config");
|
|
36737
36966
|
}
|
|
36738
|
-
return
|
|
36967
|
+
return join10(gitDir, "config");
|
|
36739
36968
|
}
|
|
36740
36969
|
function readRemotes(root) {
|
|
36741
36970
|
const gitDir = resolveGitDir(root);
|
|
36742
36971
|
if (!gitDir) return [];
|
|
36743
36972
|
const cfgPath = gitConfigPath(gitDir);
|
|
36744
|
-
if (!
|
|
36973
|
+
if (!existsSync11(cfgPath)) return [];
|
|
36745
36974
|
let txt;
|
|
36746
36975
|
try {
|
|
36747
|
-
txt =
|
|
36976
|
+
txt = readFileSync9(cfgPath, "utf8");
|
|
36748
36977
|
} catch {
|
|
36749
36978
|
return [];
|
|
36750
36979
|
}
|
|
@@ -36799,9 +37028,9 @@ var init_git_remote = __esm({
|
|
|
36799
37028
|
});
|
|
36800
37029
|
|
|
36801
37030
|
// src/profile.ts
|
|
36802
|
-
import { existsSync as
|
|
37031
|
+
import { existsSync as existsSync12, readFileSync as readFileSync10, writeFileSync as writeFileSync9 } from "node:fs";
|
|
36803
37032
|
import { createHash as createHash5 } from "node:crypto";
|
|
36804
|
-
import { join as
|
|
37033
|
+
import { join as join11 } from "node:path";
|
|
36805
37034
|
function workspaceId(root) {
|
|
36806
37035
|
return "wp_" + createHash5("sha256").update(root).digest("hex").slice(0, 12);
|
|
36807
37036
|
}
|
|
@@ -36824,8 +37053,8 @@ function refreshRepoLocator(root, profile) {
|
|
|
36824
37053
|
}
|
|
36825
37054
|
function loadProfile(root) {
|
|
36826
37055
|
const p = workspacePaths(root);
|
|
36827
|
-
if (!
|
|
36828
|
-
return JSON.parse(
|
|
37056
|
+
if (!existsSync12(p.workspaceJson)) return null;
|
|
37057
|
+
return JSON.parse(readFileSync10(p.workspaceJson, "utf8"));
|
|
36829
37058
|
}
|
|
36830
37059
|
function saveProfile(root, profile) {
|
|
36831
37060
|
const p = workspacePaths(root);
|
|
@@ -36838,13 +37067,13 @@ function autodetectProfile(root) {
|
|
|
36838
37067
|
const p = emptyProfile(id, name2);
|
|
36839
37068
|
const locator = detectRepoLocator(root);
|
|
36840
37069
|
if (locator) p.repoLocator = locator;
|
|
36841
|
-
const pkgPath =
|
|
36842
|
-
if (
|
|
37070
|
+
const pkgPath = join11(root, "package.json");
|
|
37071
|
+
if (existsSync12(pkgPath)) {
|
|
36843
37072
|
try {
|
|
36844
|
-
const pkg = JSON.parse(
|
|
37073
|
+
const pkg = JSON.parse(readFileSync10(pkgPath, "utf8"));
|
|
36845
37074
|
const deps = { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
|
|
36846
37075
|
p.languages.push("javascript");
|
|
36847
|
-
if (
|
|
37076
|
+
if (existsSync12(join11(root, "tsconfig.json")) || deps["typescript"]) {
|
|
36848
37077
|
p.languages.push("typescript");
|
|
36849
37078
|
}
|
|
36850
37079
|
const nodeVer = pkg.engines?.node?.trim();
|
|
@@ -36865,10 +37094,10 @@ function autodetectProfile(root) {
|
|
|
36865
37094
|
} catch {
|
|
36866
37095
|
}
|
|
36867
37096
|
}
|
|
36868
|
-
const pyproject =
|
|
36869
|
-
if (
|
|
37097
|
+
const pyproject = join11(root, "pyproject.toml");
|
|
37098
|
+
if (existsSync12(pyproject)) {
|
|
36870
37099
|
try {
|
|
36871
|
-
const txt =
|
|
37100
|
+
const txt = readFileSync10(pyproject, "utf8");
|
|
36872
37101
|
const py = /python\s*=\s*"([^"]+)"/.exec(txt)?.[1];
|
|
36873
37102
|
p.languages.push("python");
|
|
36874
37103
|
p.stack.push(`python@${py ?? "3"}`);
|
|
@@ -36879,16 +37108,16 @@ function autodetectProfile(root) {
|
|
|
36879
37108
|
} catch {
|
|
36880
37109
|
}
|
|
36881
37110
|
}
|
|
36882
|
-
const reqs =
|
|
36883
|
-
if (
|
|
37111
|
+
const reqs = join11(root, "requirements.txt");
|
|
37112
|
+
if (existsSync12(reqs)) {
|
|
36884
37113
|
if (!p.languages.includes("python")) p.languages.push("python");
|
|
36885
37114
|
if (!p.stack.includes("python@3")) p.stack.push("python@3");
|
|
36886
37115
|
}
|
|
36887
|
-
if (
|
|
37116
|
+
if (existsSync12(join11(root, "go.mod"))) {
|
|
36888
37117
|
p.languages.push("go");
|
|
36889
37118
|
p.stack.push("go");
|
|
36890
37119
|
}
|
|
36891
|
-
if (
|
|
37120
|
+
if (existsSync12(join11(root, "Cargo.toml"))) {
|
|
36892
37121
|
p.languages.push("rust");
|
|
36893
37122
|
p.stack.push("rust");
|
|
36894
37123
|
}
|
|
@@ -36993,32 +37222,32 @@ var init_identity2 = __esm({
|
|
|
36993
37222
|
});
|
|
36994
37223
|
|
|
36995
37224
|
// src/checkout-root.ts
|
|
36996
|
-
import { existsSync as
|
|
36997
|
-
import { basename as basename3, dirname as
|
|
37225
|
+
import { existsSync as existsSync13, readFileSync as readFileSync11 } from "node:fs";
|
|
37226
|
+
import { basename as basename3, dirname as dirname8, isAbsolute as isAbsolute3, join as join12, resolve as resolve3 } from "node:path";
|
|
36998
37227
|
function nearestGitRoot(dir) {
|
|
36999
37228
|
let cur = resolve3(dir);
|
|
37000
37229
|
for (; ; ) {
|
|
37001
|
-
if (
|
|
37002
|
-
const parent =
|
|
37230
|
+
if (existsSync13(join12(cur, ".git"))) return cur;
|
|
37231
|
+
const parent = dirname8(cur);
|
|
37003
37232
|
if (parent === cur) return null;
|
|
37004
37233
|
cur = parent;
|
|
37005
37234
|
}
|
|
37006
37235
|
}
|
|
37007
37236
|
function mainCheckoutOfWorktree(root) {
|
|
37008
37237
|
const gitDir = resolveGitDir(root);
|
|
37009
|
-
if (!gitDir || gitDir ===
|
|
37010
|
-
const commondirFile =
|
|
37011
|
-
if (!
|
|
37238
|
+
if (!gitDir || gitDir === join12(root, ".git")) return null;
|
|
37239
|
+
const commondirFile = join12(gitDir, "commondir");
|
|
37240
|
+
if (!existsSync13(commondirFile)) return null;
|
|
37012
37241
|
let common;
|
|
37013
37242
|
try {
|
|
37014
|
-
common =
|
|
37243
|
+
common = readFileSync11(commondirFile, "utf8").trim();
|
|
37015
37244
|
} catch {
|
|
37016
37245
|
return null;
|
|
37017
37246
|
}
|
|
37018
37247
|
const commonDir = resolve3(isAbsolute3(common) ? common : resolve3(gitDir, common));
|
|
37019
37248
|
if (basename3(commonDir) !== ".git") return null;
|
|
37020
|
-
const main2 =
|
|
37021
|
-
return
|
|
37249
|
+
const main2 = dirname8(commonDir);
|
|
37250
|
+
return existsSync13(join12(main2, ".git")) ? main2 : null;
|
|
37022
37251
|
}
|
|
37023
37252
|
function checkoutRootOf(cwd) {
|
|
37024
37253
|
const root = nearestGitRoot(cwd);
|
|
@@ -37037,7 +37266,7 @@ var init_checkout_root = __esm({
|
|
|
37037
37266
|
|
|
37038
37267
|
// src/process-identity.ts
|
|
37039
37268
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
37040
|
-
import { readFileSync as
|
|
37269
|
+
import { readFileSync as readFileSync12 } from "node:fs";
|
|
37041
37270
|
function readProcessIdentity(pid, fresh = false) {
|
|
37042
37271
|
if (!Number.isSafeInteger(pid) || pid <= 0) return null;
|
|
37043
37272
|
if (pid === process.pid && self) return self;
|
|
@@ -37062,10 +37291,10 @@ function readProcessIdentity(pid, fresh = false) {
|
|
|
37062
37291
|
if (!/^\d+$/.test(ticks)) return null;
|
|
37063
37292
|
value = { key: `win32:${ticks}`, bornAt: Number((BigInt(ticks) - 621355968000000000n) / 10000n) };
|
|
37064
37293
|
} else if (process.platform === "linux") {
|
|
37065
|
-
const stat4 =
|
|
37294
|
+
const stat4 = readFileSync12(`/proc/${pid}/stat`, "utf8");
|
|
37066
37295
|
const ticks = stat4.slice(stat4.lastIndexOf(")") + 2).split(" ")[19];
|
|
37067
|
-
const bootId =
|
|
37068
|
-
const boot = /^btime (\d+)$/m.exec(
|
|
37296
|
+
const bootId = readFileSync12("/proc/sys/kernel/random/boot_id", "utf8").trim();
|
|
37297
|
+
const boot = /^btime (\d+)$/m.exec(readFileSync12("/proc/stat", "utf8"))?.[1];
|
|
37069
37298
|
const hz = Number(run3("getconf", ["CLK_TCK"]));
|
|
37070
37299
|
if (!boot || !/^\d+$/.test(ticks) || !Number.isFinite(hz) || hz <= 0) return null;
|
|
37071
37300
|
value = { key: `linux:${bootId}:${ticks}`, bornAt: Number(boot) * 1e3 + Number(ticks) * 1e3 / hz };
|
|
@@ -37091,7 +37320,7 @@ var init_process_identity = __esm({
|
|
|
37091
37320
|
});
|
|
37092
37321
|
|
|
37093
37322
|
// src/lock.ts
|
|
37094
|
-
import { existsSync as
|
|
37323
|
+
import { existsSync as existsSync14, readFileSync as readFileSync13, unlinkSync as unlinkSync2 } from "node:fs";
|
|
37095
37324
|
function daemonLockPayload(lock) {
|
|
37096
37325
|
return JSON.stringify({
|
|
37097
37326
|
pid: lock.pid,
|
|
@@ -37133,9 +37362,9 @@ function isProcessAlive(pid) {
|
|
|
37133
37362
|
}
|
|
37134
37363
|
}
|
|
37135
37364
|
function readDaemonLock(lockPath) {
|
|
37136
|
-
if (!
|
|
37365
|
+
if (!existsSync14(lockPath)) return null;
|
|
37137
37366
|
try {
|
|
37138
|
-
return parseDaemonLock(
|
|
37367
|
+
return parseDaemonLock(readFileSync13(lockPath, "utf8"));
|
|
37139
37368
|
} catch {
|
|
37140
37369
|
return null;
|
|
37141
37370
|
}
|
|
@@ -37172,14 +37401,14 @@ async function waitForDaemonExit(lock, timeoutMs, pollMs = 200) {
|
|
|
37172
37401
|
}
|
|
37173
37402
|
function releaseOwnLock(lockPath) {
|
|
37174
37403
|
try {
|
|
37175
|
-
if (parseDaemonLock(
|
|
37404
|
+
if (parseDaemonLock(readFileSync13(lockPath, "utf8"))?.pid === process.pid) unlinkSync2(lockPath);
|
|
37176
37405
|
} catch {
|
|
37177
37406
|
}
|
|
37178
37407
|
}
|
|
37179
37408
|
function stopLockedDaemon(lockPath) {
|
|
37180
37409
|
let original;
|
|
37181
37410
|
try {
|
|
37182
|
-
original =
|
|
37411
|
+
original = readFileSync13(lockPath, "utf8");
|
|
37183
37412
|
} catch {
|
|
37184
37413
|
return "missing";
|
|
37185
37414
|
}
|
|
@@ -37187,7 +37416,7 @@ function stopLockedDaemon(lockPath) {
|
|
|
37187
37416
|
if (!lock) return "unknown";
|
|
37188
37417
|
const state = daemonLockState(lock, true);
|
|
37189
37418
|
try {
|
|
37190
|
-
if (
|
|
37419
|
+
if (readFileSync13(lockPath, "utf8") !== original) return "changed";
|
|
37191
37420
|
} catch {
|
|
37192
37421
|
return "changed";
|
|
37193
37422
|
}
|
|
@@ -37212,16 +37441,16 @@ var init_lock = __esm({
|
|
|
37212
37441
|
});
|
|
37213
37442
|
|
|
37214
37443
|
// src/registry.ts
|
|
37215
|
-
import { existsSync as
|
|
37216
|
-
import { join as
|
|
37444
|
+
import { existsSync as existsSync15, readFileSync as readFileSync14, writeFileSync as writeFileSync10 } from "node:fs";
|
|
37445
|
+
import { join as join13 } from "node:path";
|
|
37217
37446
|
function registryPath() {
|
|
37218
|
-
return process.env["ERRATA_REGISTRY_PATH"] ??
|
|
37447
|
+
return process.env["ERRATA_REGISTRY_PATH"] ?? join13(globalDir(), "workspaces.json");
|
|
37219
37448
|
}
|
|
37220
37449
|
function read() {
|
|
37221
37450
|
const p = registryPath();
|
|
37222
|
-
if (!
|
|
37451
|
+
if (!existsSync15(p)) return { version: 1, workspaces: {} };
|
|
37223
37452
|
try {
|
|
37224
|
-
const parsed = JSON.parse(
|
|
37453
|
+
const parsed = JSON.parse(readFileSync14(p, "utf8"));
|
|
37225
37454
|
return { version: 1, workspaces: parsed.workspaces ?? {} };
|
|
37226
37455
|
} catch {
|
|
37227
37456
|
return { version: 1, workspaces: {} };
|
|
@@ -37229,9 +37458,9 @@ function read() {
|
|
|
37229
37458
|
}
|
|
37230
37459
|
function registryCorrupt() {
|
|
37231
37460
|
const p = registryPath();
|
|
37232
|
-
if (!
|
|
37461
|
+
if (!existsSync15(p)) return false;
|
|
37233
37462
|
try {
|
|
37234
|
-
JSON.parse(
|
|
37463
|
+
JSON.parse(readFileSync14(p, "utf8"));
|
|
37235
37464
|
return false;
|
|
37236
37465
|
} catch {
|
|
37237
37466
|
return true;
|
|
@@ -37284,7 +37513,7 @@ function pruneMissingWorkspaces() {
|
|
|
37284
37513
|
const reg = read();
|
|
37285
37514
|
const removed = [];
|
|
37286
37515
|
for (const [id, entry] of Object.entries(reg.workspaces)) {
|
|
37287
|
-
if (!
|
|
37516
|
+
if (!existsSync15(entry.path)) {
|
|
37288
37517
|
removed.push(entry);
|
|
37289
37518
|
delete reg.workspaces[id];
|
|
37290
37519
|
}
|
|
@@ -37293,7 +37522,7 @@ function pruneMissingWorkspaces() {
|
|
|
37293
37522
|
return removed;
|
|
37294
37523
|
}
|
|
37295
37524
|
function workspaceStatus(entry) {
|
|
37296
|
-
const missing = !
|
|
37525
|
+
const missing = !existsSync15(entry.path);
|
|
37297
37526
|
const lockPath = workspacePaths(entry.path).daemonLock;
|
|
37298
37527
|
let running = false;
|
|
37299
37528
|
let webUiUrl = null;
|
|
@@ -38458,14 +38687,14 @@ var init_generalize_graph = __esm({
|
|
|
38458
38687
|
});
|
|
38459
38688
|
|
|
38460
38689
|
// src/dual-burst.ts
|
|
38461
|
-
function collectiveScore(hit,
|
|
38462
|
-
if (hit.cloudScore != null) return
|
|
38690
|
+
function collectiveScore(hit, cap2) {
|
|
38691
|
+
if (hit.cloudScore != null) return cap2 * Math.max(0, Math.min(1, hit.cloudScore));
|
|
38463
38692
|
const u = hit.usageCount ?? 0;
|
|
38464
|
-
return Math.min(
|
|
38693
|
+
return Math.min(cap2, Math.log10(u + 1) / 3);
|
|
38465
38694
|
}
|
|
38466
38695
|
function mergeDualBurst(local, cloud, opts = {}) {
|
|
38467
38696
|
const boost = opts.corroborationBoost ?? 0.15;
|
|
38468
|
-
const
|
|
38697
|
+
const cap2 = opts.collectiveScoreCap ?? 0.5;
|
|
38469
38698
|
const twins = opts.twins;
|
|
38470
38699
|
const cloudIdsOf = (id) => twins?.cloudIdsOf(id) ?? [];
|
|
38471
38700
|
const seedSet = /* @__PURE__ */ new Set();
|
|
@@ -38536,7 +38765,7 @@ function mergeDualBurst(local, cloud, opts = {}) {
|
|
|
38536
38765
|
id: mine.id,
|
|
38537
38766
|
label: mine.label,
|
|
38538
38767
|
name: mine.description,
|
|
38539
|
-
score: collectiveScore(c,
|
|
38768
|
+
score: collectiveScore(c, cap2),
|
|
38540
38769
|
hops: 1,
|
|
38541
38770
|
provenance: "local"
|
|
38542
38771
|
};
|
|
@@ -38553,7 +38782,7 @@ function mergeDualBurst(local, cloud, opts = {}) {
|
|
|
38553
38782
|
id: c.id,
|
|
38554
38783
|
label: c.label,
|
|
38555
38784
|
name: c.description,
|
|
38556
|
-
score: collectiveScore(c,
|
|
38785
|
+
score: collectiveScore(c, cap2),
|
|
38557
38786
|
hops: 1,
|
|
38558
38787
|
// adapters surface 1-hop neighbors of the seed
|
|
38559
38788
|
provenance: "collective",
|
|
@@ -39324,22 +39553,22 @@ var init_daemon_generalize_client = __esm({
|
|
|
39324
39553
|
|
|
39325
39554
|
// ../../packages/indexer/src/parse-cache.ts
|
|
39326
39555
|
import { createHash as createHash6 } from "node:crypto";
|
|
39327
|
-
import { existsSync as
|
|
39556
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync6, readFileSync as readFileSync15, readdirSync as readdirSync2, rmSync as rmSync2, statSync as statSync4, writeFileSync as writeFileSync11 } from "node:fs";
|
|
39328
39557
|
import { homedir as homedir3 } from "node:os";
|
|
39329
|
-
import { join as
|
|
39558
|
+
import { join as join14 } from "node:path";
|
|
39330
39559
|
function parseCacheDir() {
|
|
39331
|
-
return process.env["ERRATA_PARSE_CACHE"] ??
|
|
39560
|
+
return process.env["ERRATA_PARSE_CACHE"] ?? join14(homedir3(), ".errata", "parse-cache");
|
|
39332
39561
|
}
|
|
39333
39562
|
function parseCacheKey(source, providerId) {
|
|
39334
39563
|
return createHash6("sha256").update(`${PARSE_CACHE_VERSION}:${providerId}:${source}`).digest("hex");
|
|
39335
39564
|
}
|
|
39336
39565
|
function entryPath(dir, key) {
|
|
39337
|
-
return
|
|
39566
|
+
return join14(dir, key.slice(0, 2), `${key.slice(2)}.json`);
|
|
39338
39567
|
}
|
|
39339
39568
|
function readParseCache(dir, key) {
|
|
39340
39569
|
const file2 = entryPath(dir, key);
|
|
39341
39570
|
try {
|
|
39342
|
-
const raw2 =
|
|
39571
|
+
const raw2 = readFileSync15(file2, "utf8");
|
|
39343
39572
|
const parsed = JSON.parse(raw2);
|
|
39344
39573
|
if (parsed.v !== PARSE_CACHE_VERSION || !Array.isArray(parsed.symbols)) return null;
|
|
39345
39574
|
return { symbols: parsed.symbols, reExports: parsed.reExports ?? [] };
|
|
@@ -39358,7 +39587,7 @@ function writeParseCache(dir, key, providerId, value) {
|
|
|
39358
39587
|
const body2 = JSON.stringify(envelope);
|
|
39359
39588
|
if (body2.length > MAX_ENTRY_BYTES) return;
|
|
39360
39589
|
const file2 = entryPath(dir, key);
|
|
39361
|
-
mkdirSync6(
|
|
39590
|
+
mkdirSync6(join14(dir, key.slice(0, 2)), { recursive: true });
|
|
39362
39591
|
writeFileSync11(file2, body2);
|
|
39363
39592
|
} catch {
|
|
39364
39593
|
}
|
|
@@ -39368,9 +39597,9 @@ function sweepParseCacheOnce(dir, now = Date.now()) {
|
|
|
39368
39597
|
sweptThisProcess = true;
|
|
39369
39598
|
let removed = 0;
|
|
39370
39599
|
try {
|
|
39371
|
-
if (!
|
|
39600
|
+
if (!existsSync16(dir)) return 0;
|
|
39372
39601
|
for (const bucket of readdirSync2(dir)) {
|
|
39373
|
-
const bucketDir =
|
|
39602
|
+
const bucketDir = join14(dir, bucket);
|
|
39374
39603
|
let names;
|
|
39375
39604
|
try {
|
|
39376
39605
|
names = readdirSync2(bucketDir);
|
|
@@ -39378,7 +39607,7 @@ function sweepParseCacheOnce(dir, now = Date.now()) {
|
|
|
39378
39607
|
continue;
|
|
39379
39608
|
}
|
|
39380
39609
|
for (const name2 of names) {
|
|
39381
|
-
const file2 =
|
|
39610
|
+
const file2 = join14(bucketDir, name2);
|
|
39382
39611
|
try {
|
|
39383
39612
|
if (now - statSync4(file2).mtimeMs > ENTRY_TTL_MS) {
|
|
39384
39613
|
rmSync2(file2, { force: true });
|
|
@@ -39626,9 +39855,9 @@ var init_identity3 = __esm({
|
|
|
39626
39855
|
});
|
|
39627
39856
|
|
|
39628
39857
|
// ../../packages/indexer/src/pipeline.ts
|
|
39629
|
-
import { appendFileSync, readFileSync as
|
|
39858
|
+
import { appendFileSync, readFileSync as readFileSync16, statSync as statSync5 } from "node:fs";
|
|
39630
39859
|
import { readdir } from "node:fs/promises";
|
|
39631
|
-
import { extname, join as
|
|
39860
|
+
import { extname, join as join15, relative as relative2, sep } from "node:path";
|
|
39632
39861
|
import { createHash as createHash7 } from "node:crypto";
|
|
39633
39862
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
39634
39863
|
function nowTs() {
|
|
@@ -39777,7 +40006,7 @@ async function incrementalReindex(store, rootPath, workspaceId2, changedAbsPaths
|
|
|
39777
40006
|
for (const rel of [...changedRelPaths]) {
|
|
39778
40007
|
let h;
|
|
39779
40008
|
try {
|
|
39780
|
-
h = createHash7("sha256").update(
|
|
40009
|
+
h = createHash7("sha256").update(readFileSync16(join15(rootPath, rel))).digest("hex");
|
|
39781
40010
|
} catch {
|
|
39782
40011
|
continue;
|
|
39783
40012
|
}
|
|
@@ -39826,13 +40055,13 @@ async function incrementalReindex(store, rootPath, workspaceId2, changedAbsPaths
|
|
|
39826
40055
|
let parsedFiles = 0;
|
|
39827
40056
|
for (const rel of changedRelPaths) {
|
|
39828
40057
|
if (parsedFiles++ > 0) await new Promise((r2) => setImmediate(r2));
|
|
39829
|
-
const abs =
|
|
40058
|
+
const abs = join15(rootPath, ...rel.split("/"));
|
|
39830
40059
|
const ext = extname(abs).toLowerCase();
|
|
39831
40060
|
const provider = providers.find((p) => p.fileExtensions.includes(ext));
|
|
39832
40061
|
if (!provider) continue;
|
|
39833
40062
|
let symbols;
|
|
39834
40063
|
try {
|
|
39835
|
-
symbols = provider.extractSymbols(
|
|
40064
|
+
symbols = provider.extractSymbols(readFileSync16(abs, "utf8"), abs);
|
|
39836
40065
|
} catch {
|
|
39837
40066
|
continue;
|
|
39838
40067
|
}
|
|
@@ -40176,7 +40405,7 @@ async function runIndexer(store, opts) {
|
|
|
40176
40405
|
report.filesSkipped++;
|
|
40177
40406
|
continue;
|
|
40178
40407
|
}
|
|
40179
|
-
source =
|
|
40408
|
+
source = readFileSync16(f.absPath, "utf8");
|
|
40180
40409
|
} catch {
|
|
40181
40410
|
report.filesSkipped++;
|
|
40182
40411
|
continue;
|
|
@@ -40255,7 +40484,7 @@ async function runIndexer(store, opts) {
|
|
|
40255
40484
|
const depth = fileNode.relPath.split("/").length;
|
|
40256
40485
|
if (depth !== 3) continue;
|
|
40257
40486
|
try {
|
|
40258
|
-
const pkg = JSON.parse(
|
|
40487
|
+
const pkg = JSON.parse(readFileSync16(fileNode.absPath, "utf8"));
|
|
40259
40488
|
if (!pkg.name) continue;
|
|
40260
40489
|
const pkgDir = fileNode.relPath.replace(/\/package\.json$/, "");
|
|
40261
40490
|
const candidates = [
|
|
@@ -40646,7 +40875,7 @@ async function scan(root, current, ignores, providers, out2) {
|
|
|
40646
40875
|
for (const ent of entries) {
|
|
40647
40876
|
if (ignores.has(ent.name)) continue;
|
|
40648
40877
|
if (ent.name.startsWith(".") && ent.name !== ".") continue;
|
|
40649
|
-
const abs =
|
|
40878
|
+
const abs = join15(current, ent.name);
|
|
40650
40879
|
if (ent.isDirectory()) {
|
|
40651
40880
|
await scan(root, abs, ignores, providers, out2);
|
|
40652
40881
|
} else if (ent.isFile()) {
|
|
@@ -40705,7 +40934,7 @@ function gitListFiles(root, ignores, providers) {
|
|
|
40705
40934
|
if (rels === null) return null;
|
|
40706
40935
|
const out2 = [];
|
|
40707
40936
|
for (const rel of rels) {
|
|
40708
|
-
const abs =
|
|
40937
|
+
const abs = join15(root, rel);
|
|
40709
40938
|
let size;
|
|
40710
40939
|
let mtimeMs;
|
|
40711
40940
|
try {
|
|
@@ -40734,7 +40963,7 @@ function upsertFile(store, id, f, workspaceId2, skip) {
|
|
|
40734
40963
|
if (existing && fileUnchanged(existing.attrs, f, skip)) return;
|
|
40735
40964
|
let contentHash;
|
|
40736
40965
|
try {
|
|
40737
|
-
contentHash = createHash7("sha256").update(
|
|
40966
|
+
contentHash = createHash7("sha256").update(readFileSync16(f.absPath)).digest("hex");
|
|
40738
40967
|
} catch {
|
|
40739
40968
|
}
|
|
40740
40969
|
const carried = { ...existing?.attrs ?? {} };
|
|
@@ -45116,43 +45345,43 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
45116
45345
|
});
|
|
45117
45346
|
|
|
45118
45347
|
// ../../packages/indexer/src/languages/tree-sitter-loader.ts
|
|
45119
|
-
import { fileURLToPath } from "node:url";
|
|
45120
|
-
import { dirname as
|
|
45121
|
-
import { existsSync as
|
|
45348
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
45349
|
+
import { dirname as dirname9, join as join16 } from "node:path";
|
|
45350
|
+
import { existsSync as existsSync17, readdirSync as readdirSync3 } from "node:fs";
|
|
45122
45351
|
import { createRequire as createRequire2 } from "node:module";
|
|
45123
45352
|
function entryDir() {
|
|
45124
45353
|
try {
|
|
45125
45354
|
const url2 = import.meta?.url;
|
|
45126
45355
|
if (typeof url2 === "string" && url2.length > 0) {
|
|
45127
|
-
return
|
|
45356
|
+
return dirname9(fileURLToPath2(url2));
|
|
45128
45357
|
}
|
|
45129
45358
|
} catch {
|
|
45130
45359
|
}
|
|
45131
|
-
return
|
|
45360
|
+
return dirname9(process.execPath);
|
|
45132
45361
|
}
|
|
45133
45362
|
function findWasmDir() {
|
|
45134
45363
|
const here = entryDir();
|
|
45135
|
-
const seaWasm =
|
|
45136
|
-
if (
|
|
45364
|
+
const seaWasm = join16(here, "resources", "wasm");
|
|
45365
|
+
if (existsSync17(join16(seaWasm, "tree-sitter-typescript.wasm"))) return seaWasm;
|
|
45137
45366
|
let dir = here;
|
|
45138
45367
|
for (let i2 = 0; i2 < 6; i2++) {
|
|
45139
|
-
const flat =
|
|
45368
|
+
const flat = join16(
|
|
45140
45369
|
dir,
|
|
45141
45370
|
"node_modules",
|
|
45142
45371
|
"@vscode",
|
|
45143
45372
|
"tree-sitter-wasm",
|
|
45144
45373
|
"wasm"
|
|
45145
45374
|
);
|
|
45146
|
-
if (
|
|
45147
|
-
dir =
|
|
45375
|
+
if (existsSync17(join16(flat, "tree-sitter-typescript.wasm"))) return flat;
|
|
45376
|
+
dir = dirname9(dir);
|
|
45148
45377
|
}
|
|
45149
45378
|
let root = here;
|
|
45150
45379
|
for (let i2 = 0; i2 < 6; i2++) {
|
|
45151
|
-
const pnpmDir =
|
|
45152
|
-
if (
|
|
45380
|
+
const pnpmDir = join16(root, "node_modules", ".pnpm");
|
|
45381
|
+
if (existsSync17(pnpmDir)) {
|
|
45153
45382
|
for (const entry of readdirSync3(pnpmDir)) {
|
|
45154
45383
|
if (entry.startsWith("@vscode+tree-sitter-wasm@")) {
|
|
45155
|
-
const candidate =
|
|
45384
|
+
const candidate = join16(
|
|
45156
45385
|
pnpmDir,
|
|
45157
45386
|
entry,
|
|
45158
45387
|
"node_modules",
|
|
@@ -45160,13 +45389,13 @@ function findWasmDir() {
|
|
|
45160
45389
|
"tree-sitter-wasm",
|
|
45161
45390
|
"wasm"
|
|
45162
45391
|
);
|
|
45163
|
-
if (
|
|
45392
|
+
if (existsSync17(join16(candidate, "tree-sitter-typescript.wasm"))) {
|
|
45164
45393
|
return candidate;
|
|
45165
45394
|
}
|
|
45166
45395
|
}
|
|
45167
45396
|
}
|
|
45168
45397
|
}
|
|
45169
|
-
root =
|
|
45398
|
+
root = dirname9(root);
|
|
45170
45399
|
}
|
|
45171
45400
|
throw new Error(
|
|
45172
45401
|
"@vscode/tree-sitter-wasm grammar files not found \u2014 is the package installed?"
|
|
@@ -45174,33 +45403,33 @@ function findWasmDir() {
|
|
|
45174
45403
|
}
|
|
45175
45404
|
function findRuntimeDir() {
|
|
45176
45405
|
const here = entryDir();
|
|
45177
|
-
const seaRuntime =
|
|
45178
|
-
if (
|
|
45406
|
+
const seaRuntime = join16(here, "resources", "wasm");
|
|
45407
|
+
if (existsSync17(join16(seaRuntime, "web-tree-sitter.wasm"))) return seaRuntime;
|
|
45179
45408
|
let dir = here;
|
|
45180
45409
|
for (let i2 = 0; i2 < 6; i2++) {
|
|
45181
|
-
const flat =
|
|
45182
|
-
if (
|
|
45183
|
-
dir =
|
|
45410
|
+
const flat = join16(dir, "node_modules", "web-tree-sitter");
|
|
45411
|
+
if (existsSync17(join16(flat, "web-tree-sitter.wasm"))) return flat;
|
|
45412
|
+
dir = dirname9(dir);
|
|
45184
45413
|
}
|
|
45185
45414
|
let root = here;
|
|
45186
45415
|
for (let i2 = 0; i2 < 6; i2++) {
|
|
45187
|
-
const pnpmDir =
|
|
45188
|
-
if (
|
|
45416
|
+
const pnpmDir = join16(root, "node_modules", ".pnpm");
|
|
45417
|
+
if (existsSync17(pnpmDir)) {
|
|
45189
45418
|
for (const entry of readdirSync3(pnpmDir)) {
|
|
45190
45419
|
if (entry.startsWith("web-tree-sitter@")) {
|
|
45191
|
-
const candidate =
|
|
45420
|
+
const candidate = join16(
|
|
45192
45421
|
pnpmDir,
|
|
45193
45422
|
entry,
|
|
45194
45423
|
"node_modules",
|
|
45195
45424
|
"web-tree-sitter"
|
|
45196
45425
|
);
|
|
45197
|
-
if (
|
|
45426
|
+
if (existsSync17(join16(candidate, "web-tree-sitter.wasm"))) {
|
|
45198
45427
|
return candidate;
|
|
45199
45428
|
}
|
|
45200
45429
|
}
|
|
45201
45430
|
}
|
|
45202
45431
|
}
|
|
45203
|
-
root =
|
|
45432
|
+
root = dirname9(root);
|
|
45204
45433
|
}
|
|
45205
45434
|
throw new Error("web-tree-sitter runtime WASM not found");
|
|
45206
45435
|
}
|
|
@@ -45211,7 +45440,7 @@ async function loadWebTreeSitter() {
|
|
|
45211
45440
|
void err2;
|
|
45212
45441
|
}
|
|
45213
45442
|
const here = entryDir();
|
|
45214
|
-
const seaResourceBase =
|
|
45443
|
+
const seaResourceBase = join16(here, "resources", "_resolve.js");
|
|
45215
45444
|
const resourceRequire = createRequire2(seaResourceBase);
|
|
45216
45445
|
return resourceRequire("web-tree-sitter");
|
|
45217
45446
|
}
|
|
@@ -45226,9 +45455,9 @@ async function ensureTreeSitterReady() {
|
|
|
45226
45455
|
await Parser2.init({
|
|
45227
45456
|
locateFile: (name2) => {
|
|
45228
45457
|
if (name2 === "tree-sitter.wasm" || name2 === "web-tree-sitter.wasm") {
|
|
45229
|
-
return
|
|
45458
|
+
return join16(runtime, name2);
|
|
45230
45459
|
}
|
|
45231
|
-
return
|
|
45460
|
+
return join16(grammars, name2);
|
|
45232
45461
|
}
|
|
45233
45462
|
});
|
|
45234
45463
|
})();
|
|
@@ -45240,7 +45469,7 @@ async function loadGrammar(name2) {
|
|
|
45240
45469
|
if (cached2) return cached2;
|
|
45241
45470
|
if (!languageClass) throw new Error("tree-sitter not initialized");
|
|
45242
45471
|
const grammars = findWasmDir();
|
|
45243
|
-
const lang = await languageClass.load(
|
|
45472
|
+
const lang = await languageClass.load(join16(grammars, `${name2}.wasm`));
|
|
45244
45473
|
grammarCache.set(name2, lang);
|
|
45245
45474
|
return lang;
|
|
45246
45475
|
}
|
|
@@ -48145,7 +48374,7 @@ var init_src11 = __esm({
|
|
|
48145
48374
|
// src/reconcile.ts
|
|
48146
48375
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
48147
48376
|
import { readdirSync as readdirSync4, statSync as statSync6 } from "node:fs";
|
|
48148
|
-
import { join as
|
|
48377
|
+
import { join as join17, relative as relative3, sep as sep2 } from "node:path";
|
|
48149
48378
|
function indexerWouldScan(rel) {
|
|
48150
48379
|
for (const seg of rel.split(/[\\/]/)) {
|
|
48151
48380
|
if (seg.length === 0) continue;
|
|
@@ -48168,7 +48397,7 @@ function gitSourceFiles(root) {
|
|
|
48168
48397
|
const out2 = [];
|
|
48169
48398
|
for (const rel of stdout.split("\0")) {
|
|
48170
48399
|
if (!rel || !SOURCE_RE.test(rel) || !indexerWouldScan(rel)) continue;
|
|
48171
|
-
const abs =
|
|
48400
|
+
const abs = join17(root, rel);
|
|
48172
48401
|
if (IGNORED.test(abs)) continue;
|
|
48173
48402
|
out2.push(abs);
|
|
48174
48403
|
}
|
|
@@ -48183,7 +48412,7 @@ function* walkSource(dir) {
|
|
|
48183
48412
|
}
|
|
48184
48413
|
for (const e of entries) {
|
|
48185
48414
|
const name2 = String(e.name);
|
|
48186
|
-
const full =
|
|
48415
|
+
const full = join17(dir, name2);
|
|
48187
48416
|
if (IGNORED.test(full)) continue;
|
|
48188
48417
|
if (!indexerWouldScan(name2)) continue;
|
|
48189
48418
|
if (e.isDirectory()) yield* walkSource(full);
|
|
@@ -48401,7 +48630,7 @@ __export(mcp_exports, {
|
|
|
48401
48630
|
textMatches: () => textMatches,
|
|
48402
48631
|
withLinks: () => withLinks
|
|
48403
48632
|
});
|
|
48404
|
-
import { existsSync as
|
|
48633
|
+
import { existsSync as existsSync18, readFileSync as readFileSync17 } from "node:fs";
|
|
48405
48634
|
import { resolve as resolve4 } from "node:path";
|
|
48406
48635
|
function collectEnrichmentPulls(store, opts = {}) {
|
|
48407
48636
|
const pending = store.findLiveNodesByAttr("Solution", "enrichmentPending", 1).filter((s) => s.attrs["enrichmentPending"] === true).filter((s) => !opts.onlyUnsurfaced || s.attrs["enrichmentSurfaced"] !== true);
|
|
@@ -48447,7 +48676,7 @@ function takeEnrichmentNudge(store) {
|
|
|
48447
48676
|
` + items;
|
|
48448
48677
|
}
|
|
48449
48678
|
function takeDiscriminatorNudge(path3) {
|
|
48450
|
-
if (!path3 || !
|
|
48679
|
+
if (!path3 || !existsSync18(path3)) return null;
|
|
48451
48680
|
let shared;
|
|
48452
48681
|
try {
|
|
48453
48682
|
shared = openGraphStore({ path: path3 });
|
|
@@ -48714,10 +48943,10 @@ function showNode(store, node2, maxLines) {
|
|
|
48714
48943
|
if (!relPath) return { found: false, reason: "no file owner for node" };
|
|
48715
48944
|
const workspaceRoot = process.cwd();
|
|
48716
48945
|
const absPath = resolve4(workspaceRoot, relPath);
|
|
48717
|
-
if (!
|
|
48946
|
+
if (!existsSync18(absPath)) {
|
|
48718
48947
|
return { found: false, reason: `file not found on disk: ${absPath}` };
|
|
48719
48948
|
}
|
|
48720
|
-
const source =
|
|
48949
|
+
const source = readFileSync17(absPath, "utf8");
|
|
48721
48950
|
const attrs = node2.attrs;
|
|
48722
48951
|
let startByte = attrs["bodyStartByte"] ?? attrs["startByte"];
|
|
48723
48952
|
let endByte = attrs["bodyEndByte"] ?? attrs["endByte"];
|
|
@@ -48780,15 +49009,17 @@ function similarNodes(store, seed, limit) {
|
|
|
48780
49009
|
hits: []
|
|
48781
49010
|
};
|
|
48782
49011
|
}
|
|
49012
|
+
const versionOf = (attrs) => String(attrs?.["embeddingVersion"] ?? "hash-v1");
|
|
49013
|
+
const seedVersion = versionOf(seed.attrs);
|
|
48783
49014
|
const candidates = [];
|
|
48784
49015
|
for (const n of store.selectNodes({
|
|
48785
49016
|
labels: ["Problem", "Pattern", "Technique", "AntiPattern", "Function", "Method", "Class"],
|
|
48786
|
-
attrs: ["test", "relPath"],
|
|
49017
|
+
attrs: ["test", "relPath", "embeddingVersion"],
|
|
48787
49018
|
where: [{ embedding: "present" }],
|
|
48788
49019
|
withEmbedding: true
|
|
48789
49020
|
})) {
|
|
48790
49021
|
if (n.id === seed.id) continue;
|
|
48791
|
-
if (n.embedding.length === seed.embedding.length) {
|
|
49022
|
+
if (n.embedding.length === seed.embedding.length && versionOf(n.attrs) === seedVersion) {
|
|
48792
49023
|
candidates.push(n);
|
|
48793
49024
|
}
|
|
48794
49025
|
}
|
|
@@ -49554,7 +49785,7 @@ var init_mcp = __esm({
|
|
|
49554
49785
|
const local = causalChain(store, { seedId: id, direction: "both", maxHops, limit });
|
|
49555
49786
|
try {
|
|
49556
49787
|
const path3 = sharedStorePath();
|
|
49557
|
-
if (!
|
|
49788
|
+
if (!existsSync18(path3)) return { found: true, ...local };
|
|
49558
49789
|
const shared = openGraphStore({ path: path3 });
|
|
49559
49790
|
try {
|
|
49560
49791
|
if (!shared.getNode(id)) return { found: true, ...local };
|
|
@@ -50213,7 +50444,7 @@ var init_mcp = __esm({
|
|
|
50213
50444
|
inputSchema: { type: "object", properties: {} },
|
|
50214
50445
|
handler: () => {
|
|
50215
50446
|
const path3 = sharedStorePath();
|
|
50216
|
-
if (!
|
|
50447
|
+
if (!existsSync18(path3)) return { count: 0, pending: [] };
|
|
50217
50448
|
const shared = openGraphStore({ path: path3 });
|
|
50218
50449
|
try {
|
|
50219
50450
|
const pending = pendingAbstractions(shared);
|
|
@@ -50241,7 +50472,7 @@ var init_mcp = __esm({
|
|
|
50241
50472
|
},
|
|
50242
50473
|
handler: (args2) => {
|
|
50243
50474
|
const path3 = sharedStorePath();
|
|
50244
|
-
if (!
|
|
50475
|
+
if (!existsSync18(path3)) return { count: 0, pending: [] };
|
|
50245
50476
|
const shared = openGraphStore({ path: path3 });
|
|
50246
50477
|
try {
|
|
50247
50478
|
const pending = pendingDiscriminators(shared, {
|
|
@@ -50285,7 +50516,7 @@ var init_mcp = __esm({
|
|
|
50285
50516
|
},
|
|
50286
50517
|
handler: (args2) => {
|
|
50287
50518
|
const path3 = sharedStorePath();
|
|
50288
|
-
if (!
|
|
50519
|
+
if (!existsSync18(path3)) return { count: 0, routes: [] };
|
|
50289
50520
|
const shared = openGraphStore({ path: path3 });
|
|
50290
50521
|
try {
|
|
50291
50522
|
const result = triageOf(shared, {
|
|
@@ -50677,7 +50908,7 @@ __export(vfile_exports, {
|
|
|
50677
50908
|
segmentsOf: () => segmentsOf
|
|
50678
50909
|
});
|
|
50679
50910
|
import { writeFileSync as writeFileSync12 } from "node:fs";
|
|
50680
|
-
import { join as
|
|
50911
|
+
import { join as join18, resolve as resolve5, sep as sep3 } from "node:path";
|
|
50681
50912
|
function segmentsOf(rawPath) {
|
|
50682
50913
|
let p = rawPath.replace(/\\/g, "/");
|
|
50683
50914
|
p = p.replace(/^.*\.errata\/g\//, "").replace(/^\/?g\//, "").replace(/^\/+/, "");
|
|
@@ -50751,7 +50982,7 @@ async function renderVFile(rawPath, store, ctx = {}) {
|
|
|
50751
50982
|
}
|
|
50752
50983
|
async function materializeVFile(rawPath, workspaceRoot, store, ctx = {}) {
|
|
50753
50984
|
const segs = segmentsOf(rawPath);
|
|
50754
|
-
const gRoot =
|
|
50985
|
+
const gRoot = join18(workspaceRoot, ".errata", "g");
|
|
50755
50986
|
const abs = resolve5(gRoot, ...segs.length ? segs : ["index"]);
|
|
50756
50987
|
if (abs !== gRoot && !abs.startsWith(gRoot + sep3)) {
|
|
50757
50988
|
throw new Error(`refusing to materialize outside .errata/g: ${rawPath}`);
|
|
@@ -58178,25 +58409,25 @@ var init_tool_index = __esm({
|
|
|
58178
58409
|
|
|
58179
58410
|
// src/outbox.ts
|
|
58180
58411
|
import {
|
|
58181
|
-
existsSync as
|
|
58412
|
+
existsSync as existsSync19,
|
|
58182
58413
|
readdirSync as readdirSync5,
|
|
58183
|
-
readFileSync as
|
|
58414
|
+
readFileSync as readFileSync18,
|
|
58184
58415
|
renameSync as renameSync2,
|
|
58185
58416
|
unlinkSync as unlinkSync3,
|
|
58186
58417
|
writeFileSync as writeFileSync13
|
|
58187
58418
|
} from "node:fs";
|
|
58188
|
-
import { join as
|
|
58419
|
+
import { join as join19 } from "node:path";
|
|
58189
58420
|
import { createHash as createHash15 } from "node:crypto";
|
|
58190
58421
|
function enqueueOutbox(paths, payload) {
|
|
58191
58422
|
ensureDir(paths.outbox);
|
|
58192
58423
|
const id = createHash15("sha256").update(JSON.stringify(payload)).digest("hex").slice(0, 16);
|
|
58193
|
-
const file2 =
|
|
58424
|
+
const file2 = join19(paths.outbox, `${Date.now()}-${id}.json`);
|
|
58194
58425
|
writeFileSync13(file2, JSON.stringify(payload, null, 2), "utf8");
|
|
58195
58426
|
return file2;
|
|
58196
58427
|
}
|
|
58197
58428
|
async function flushOutbox(paths, client, store) {
|
|
58198
58429
|
ensureDir(paths.outbox);
|
|
58199
|
-
const entries =
|
|
58430
|
+
const entries = existsSync19(paths.outbox) ? readdirSync5(paths.outbox) : [];
|
|
58200
58431
|
let uploaded = 0;
|
|
58201
58432
|
let failed = 0;
|
|
58202
58433
|
const quarantine = (abs, reason) => {
|
|
@@ -58207,10 +58438,10 @@ async function flushOutbox(paths, client, store) {
|
|
|
58207
58438
|
}
|
|
58208
58439
|
};
|
|
58209
58440
|
for (const f of entries.filter((e) => e.endsWith(".json")).sort()) {
|
|
58210
|
-
const abs =
|
|
58441
|
+
const abs = join19(paths.outbox, f);
|
|
58211
58442
|
let payload;
|
|
58212
58443
|
try {
|
|
58213
|
-
payload = JSON.parse(
|
|
58444
|
+
payload = JSON.parse(readFileSync18(abs, "utf8"));
|
|
58214
58445
|
} catch {
|
|
58215
58446
|
failed++;
|
|
58216
58447
|
quarantine(abs, "unparseable JSON");
|
|
@@ -58255,7 +58486,7 @@ async function flushOutbox(paths, client, store) {
|
|
|
58255
58486
|
}
|
|
58256
58487
|
}
|
|
58257
58488
|
}
|
|
58258
|
-
const remainingFiles =
|
|
58489
|
+
const remainingFiles = existsSync19(paths.outbox) ? readdirSync5(paths.outbox).filter((e) => e.endsWith(".json")) : [];
|
|
58259
58490
|
return { uploaded, failed, remaining: remainingFiles.length };
|
|
58260
58491
|
}
|
|
58261
58492
|
var init_outbox = __esm({
|
|
@@ -78158,27 +78389,27 @@ __export(witness_ledger_exports, {
|
|
|
78158
78389
|
summarizeWitnessLedger: () => summarizeWitnessLedger,
|
|
78159
78390
|
witnessLedgerPath: () => witnessLedgerPath
|
|
78160
78391
|
});
|
|
78161
|
-
import { appendFileSync as appendFileSync3, existsSync as
|
|
78162
|
-
import { join as
|
|
78392
|
+
import { appendFileSync as appendFileSync3, existsSync as existsSync29, readFileSync as readFileSync34, writeFileSync as writeFileSync23 } from "node:fs";
|
|
78393
|
+
import { join as join38 } from "node:path";
|
|
78163
78394
|
function witnessLedgerPath(configDir) {
|
|
78164
|
-
return
|
|
78395
|
+
return join38(configDir, "witness-ledger.jsonl");
|
|
78165
78396
|
}
|
|
78166
78397
|
function appendWitnessLedger(configDir, entry) {
|
|
78167
78398
|
const path3 = witnessLedgerPath(configDir);
|
|
78168
78399
|
try {
|
|
78169
78400
|
appendFileSync3(path3, JSON.stringify(entry) + "\n");
|
|
78170
|
-
const lines =
|
|
78401
|
+
const lines = readFileSync34(path3, "utf8").split("\n").filter(Boolean);
|
|
78171
78402
|
if (lines.length > LEDGER_MAX_LINES) {
|
|
78172
|
-
|
|
78403
|
+
writeFileSync23(path3, lines.slice(-Math.floor(LEDGER_MAX_LINES / 2)).join("\n") + "\n");
|
|
78173
78404
|
}
|
|
78174
78405
|
} catch {
|
|
78175
78406
|
}
|
|
78176
78407
|
}
|
|
78177
78408
|
function readWitnessLedger(configDir) {
|
|
78178
78409
|
const path3 = witnessLedgerPath(configDir);
|
|
78179
|
-
if (!
|
|
78410
|
+
if (!existsSync29(path3)) return [];
|
|
78180
78411
|
try {
|
|
78181
|
-
return
|
|
78412
|
+
return readFileSync34(path3, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter((e) => typeof e.ts === "number" && typeof e.channel === "string");
|
|
78182
78413
|
} catch {
|
|
78183
78414
|
return [];
|
|
78184
78415
|
}
|
|
@@ -78617,12 +78848,12 @@ var init_report_render = __esm({
|
|
|
78617
78848
|
|
|
78618
78849
|
// src/cli.ts
|
|
78619
78850
|
init_src6();
|
|
78620
|
-
import { closeSync as closeSync3, existsSync as
|
|
78621
|
-
import { join as
|
|
78851
|
+
import { closeSync as closeSync3, existsSync as existsSync42, openSync as openSync3, readFileSync as readFileSync51, renameSync as renameSync11, statSync as statSync17, writeFileSync as writeFileSync35 } from "node:fs";
|
|
78852
|
+
import { join as join59, resolve as pathResolve2 } from "node:path";
|
|
78622
78853
|
import { spawn as spawn5 } from "node:child_process";
|
|
78623
78854
|
|
|
78624
78855
|
// src/daemon.ts
|
|
78625
|
-
import { existsSync as
|
|
78856
|
+
import { existsSync as existsSync31, writeFileSync as writeFileSync26 } from "node:fs";
|
|
78626
78857
|
|
|
78627
78858
|
// ../../node_modules/.pnpm/@hono+node-server@1.19.11_hono@4.12.34/node_modules/@hono/node-server/dist/index.mjs
|
|
78628
78859
|
import { createServer as createServerHTTP } from "http";
|
|
@@ -79202,16 +79433,16 @@ init_config();
|
|
|
79202
79433
|
init_lock();
|
|
79203
79434
|
|
|
79204
79435
|
// src/replay-checkout.ts
|
|
79205
|
-
import { existsSync as
|
|
79206
|
-
import { dirname as
|
|
79436
|
+
import { existsSync as existsSync20, readFileSync as readFileSync19, statSync as statSync7 } from "node:fs";
|
|
79437
|
+
import { dirname as dirname10, isAbsolute as isAbsolute4, join as join20, resolve as resolve6 } from "node:path";
|
|
79207
79438
|
var REPLAY_MARKER = "errata-replay";
|
|
79208
79439
|
function gitDirOf(cwd) {
|
|
79209
|
-
for (let dir = resolve6(cwd); ; dir =
|
|
79210
|
-
const dotGit =
|
|
79211
|
-
if (
|
|
79440
|
+
for (let dir = resolve6(cwd); ; dir = dirname10(dir)) {
|
|
79441
|
+
const dotGit = join20(dir, ".git");
|
|
79442
|
+
if (existsSync20(dotGit)) {
|
|
79212
79443
|
try {
|
|
79213
79444
|
if (statSync7(dotGit).isDirectory()) return dotGit;
|
|
79214
|
-
const m = /^gitdir:\s*(.+)$/m.exec(
|
|
79445
|
+
const m = /^gitdir:\s*(.+)$/m.exec(readFileSync19(dotGit, "utf8"));
|
|
79215
79446
|
if (!m) return null;
|
|
79216
79447
|
const target = m[1].trim();
|
|
79217
79448
|
return isAbsolute4(target) ? target : resolve6(dir, target);
|
|
@@ -79219,12 +79450,12 @@ function gitDirOf(cwd) {
|
|
|
79219
79450
|
return null;
|
|
79220
79451
|
}
|
|
79221
79452
|
}
|
|
79222
|
-
if (
|
|
79453
|
+
if (dirname10(dir) === dir) return null;
|
|
79223
79454
|
}
|
|
79224
79455
|
}
|
|
79225
79456
|
function isReplayCheckout(cwd) {
|
|
79226
79457
|
const gitDir = gitDirOf(cwd);
|
|
79227
|
-
return gitDir != null &&
|
|
79458
|
+
return gitDir != null && existsSync20(join20(gitDir, REPLAY_MARKER));
|
|
79228
79459
|
}
|
|
79229
79460
|
|
|
79230
79461
|
// src/activity-feed.ts
|
|
@@ -79332,8 +79563,8 @@ function knowledgeTag(label, attrs) {
|
|
|
79332
79563
|
|
|
79333
79564
|
// src/engine.ts
|
|
79334
79565
|
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
79335
|
-
import { existsSync as
|
|
79336
|
-
import { basename as basename8, join as
|
|
79566
|
+
import { existsSync as existsSync30, statSync as statSync12, appendFileSync as appendFileSync4, readdirSync as readdirSync11, renameSync as renameSync6, readFileSync as readFileSync36, writeFileSync as writeFileSync25 } from "node:fs";
|
|
79567
|
+
import { basename as basename8, join as join40, relative as relative6, sep as sep5 } from "node:path";
|
|
79337
79568
|
|
|
79338
79569
|
// src/coalesced-file-pass.ts
|
|
79339
79570
|
function createCoalescedFilePass(delayMs, run3, onError) {
|
|
@@ -79378,7 +79609,7 @@ function createCoalescedFilePass(delayMs, run3, onError) {
|
|
|
79378
79609
|
// src/source-watcher.ts
|
|
79379
79610
|
import { EventEmitter as EventEmitter2 } from "node:events";
|
|
79380
79611
|
import { readdirSync as readdirSync6, statSync as statSync8, watch as watch2 } from "node:fs";
|
|
79381
|
-
import { join as
|
|
79612
|
+
import { join as join23, sep as sep4 } from "node:path";
|
|
79382
79613
|
|
|
79383
79614
|
// ../../node_modules/.pnpm/chokidar@4.0.3/node_modules/chokidar/esm/index.js
|
|
79384
79615
|
import { stat as statcb } from "fs";
|
|
@@ -80109,9 +80340,9 @@ var NodeFsHandler = class {
|
|
|
80109
80340
|
if (this.fsw.closed) {
|
|
80110
80341
|
return;
|
|
80111
80342
|
}
|
|
80112
|
-
const
|
|
80343
|
+
const dirname24 = sysPath.dirname(file2);
|
|
80113
80344
|
const basename11 = sysPath.basename(file2);
|
|
80114
|
-
const parent = this.fsw._getWatchedDir(
|
|
80345
|
+
const parent = this.fsw._getWatchedDir(dirname24);
|
|
80115
80346
|
let prevStats = stats;
|
|
80116
80347
|
if (parent.has(basename11))
|
|
80117
80348
|
return;
|
|
@@ -80138,7 +80369,7 @@ var NodeFsHandler = class {
|
|
|
80138
80369
|
prevStats = newStats2;
|
|
80139
80370
|
}
|
|
80140
80371
|
} catch (error48) {
|
|
80141
|
-
this.fsw._remove(
|
|
80372
|
+
this.fsw._remove(dirname24, basename11);
|
|
80142
80373
|
}
|
|
80143
80374
|
} else if (parent.has(basename11)) {
|
|
80144
80375
|
const at = newStats.atimeMs;
|
|
@@ -81114,7 +81345,7 @@ var NativeSourceWatcher = class extends EventEmitter2 {
|
|
|
81114
81345
|
}
|
|
81115
81346
|
try {
|
|
81116
81347
|
const h = watch2(target, { recursive: isDir, persistent: true }, (event, name2) => {
|
|
81117
|
-
const path3 = isDir ? name2 ?
|
|
81348
|
+
const path3 = isDir ? name2 ? join23(target, name2.toString()) : null : target;
|
|
81118
81349
|
if (!path3) {
|
|
81119
81350
|
this.emit("raw", event, target, { watchedPath: target, filenameMissing: true });
|
|
81120
81351
|
this.scheduleReconcile(target, isDir);
|
|
@@ -81180,7 +81411,7 @@ var NativeSourceWatcher = class extends EventEmitter2 {
|
|
|
81180
81411
|
continue;
|
|
81181
81412
|
}
|
|
81182
81413
|
for (const entry of entries) {
|
|
81183
|
-
const path3 =
|
|
81414
|
+
const path3 = join23(dir, entry.name);
|
|
81184
81415
|
if (this.ignored(path3)) continue;
|
|
81185
81416
|
if (entry.isDirectory()) dirs.push(path3);
|
|
81186
81417
|
else if (entry.isFile()) add(path3);
|
|
@@ -81491,9 +81722,9 @@ init_src6();
|
|
|
81491
81722
|
init_session_registry();
|
|
81492
81723
|
|
|
81493
81724
|
// src/snapshot-reuse.ts
|
|
81494
|
-
import { readFileSync as
|
|
81495
|
-
import { fileURLToPath as
|
|
81496
|
-
import { dirname as
|
|
81725
|
+
import { readFileSync as readFileSync20, renameSync as renameSync3, statSync as statSync9, writeFileSync as writeFileSync14 } from "node:fs";
|
|
81726
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
81727
|
+
import { dirname as dirname13, join as join24 } from "node:path";
|
|
81497
81728
|
function revisitFlagsUnchanged(store, held, flaggedNow) {
|
|
81498
81729
|
if (held.anySeq === void 0 || held.revisitIds === void 0 || !store.changedAmong) return false;
|
|
81499
81730
|
const watched = [.../* @__PURE__ */ new Set([...held.revisitIds, ...flaggedNow])];
|
|
@@ -81509,7 +81740,7 @@ function snapshotCodeIdentity(version3) {
|
|
|
81509
81740
|
if (codeIdentityMemo === void 0) {
|
|
81510
81741
|
let built = "unknown";
|
|
81511
81742
|
try {
|
|
81512
|
-
built = String(statSync9(
|
|
81743
|
+
built = String(statSync9(fileURLToPath3(import.meta.url)).mtimeMs);
|
|
81513
81744
|
} catch {
|
|
81514
81745
|
}
|
|
81515
81746
|
codeIdentityMemo = `${version3}@${built}`;
|
|
@@ -81517,11 +81748,11 @@ function snapshotCodeIdentity(version3) {
|
|
|
81517
81748
|
return codeIdentityMemo;
|
|
81518
81749
|
}
|
|
81519
81750
|
function heldSnapshotPath(configDir) {
|
|
81520
|
-
return
|
|
81751
|
+
return join24(configDir, "snapshot-held.json");
|
|
81521
81752
|
}
|
|
81522
81753
|
function loadHeldSnapshot(path3) {
|
|
81523
81754
|
try {
|
|
81524
|
-
const held = JSON.parse(
|
|
81755
|
+
const held = JSON.parse(readFileSync20(path3, "utf8"));
|
|
81525
81756
|
return typeof held?.key === "string" && typeof held.at === "number" ? held : null;
|
|
81526
81757
|
} catch {
|
|
81527
81758
|
return null;
|
|
@@ -81529,7 +81760,7 @@ function loadHeldSnapshot(path3) {
|
|
|
81529
81760
|
}
|
|
81530
81761
|
function saveHeldSnapshot(path3, held) {
|
|
81531
81762
|
try {
|
|
81532
|
-
const tmp =
|
|
81763
|
+
const tmp = join24(dirname13(path3), `.${process.pid}.snapshot-held.tmp`);
|
|
81533
81764
|
writeFileSync14(tmp, JSON.stringify(held));
|
|
81534
81765
|
renameSync3(tmp, path3);
|
|
81535
81766
|
} catch {
|
|
@@ -81725,8 +81956,8 @@ init_review2();
|
|
|
81725
81956
|
|
|
81726
81957
|
// src/turn.ts
|
|
81727
81958
|
init_checkout_root();
|
|
81728
|
-
import { closeSync as closeSync2, existsSync as
|
|
81729
|
-
import { basename as basename6, delimiter, dirname as
|
|
81959
|
+
import { closeSync as closeSync2, existsSync as existsSync21, fstatSync, openSync as openSync2, readdirSync as readdirSync7, readSync as readSync2, realpathSync as realpathSync2, statSync as statSync10 } from "node:fs";
|
|
81960
|
+
import { basename as basename6, delimiter, dirname as dirname14, join as join25, normalize as normalize4 } from "node:path";
|
|
81730
81961
|
import { homedir as homedir4 } from "node:os";
|
|
81731
81962
|
import { createHash as createHash16 } from "node:crypto";
|
|
81732
81963
|
function completeJsonlPrefix(buf) {
|
|
@@ -81751,9 +81982,9 @@ function readFrom(path3, fromByte, maxBytes) {
|
|
|
81751
81982
|
const start2 = fromByte > 0 && fromByte <= size ? fromByte : 0;
|
|
81752
81983
|
const remaining = size - start2;
|
|
81753
81984
|
if (remaining <= 0) return { text: "", nextOffset: size, more: false, ioFailed: false };
|
|
81754
|
-
let
|
|
81985
|
+
let cap2 = maxBytes && maxBytes > 0 ? maxBytes : remaining;
|
|
81755
81986
|
for (; ; ) {
|
|
81756
|
-
const len = Math.min(
|
|
81987
|
+
const len = Math.min(cap2, remaining);
|
|
81757
81988
|
const buf = Buffer.allocUnsafe(len);
|
|
81758
81989
|
const read2 = readSync2(fd, buf, 0, len, start2);
|
|
81759
81990
|
if (len >= remaining || read2 < len) {
|
|
@@ -81769,7 +82000,7 @@ function readFrom(path3, fromByte, maxBytes) {
|
|
|
81769
82000
|
ioFailed: false
|
|
81770
82001
|
};
|
|
81771
82002
|
}
|
|
81772
|
-
|
|
82003
|
+
cap2 *= 2;
|
|
81773
82004
|
}
|
|
81774
82005
|
} catch {
|
|
81775
82006
|
return { text: "", nextOffset: fromByte, more: false, ioFailed: true };
|
|
@@ -82114,11 +82345,11 @@ function turnsSince(turns, mark) {
|
|
|
82114
82345
|
return at >= 0 ? turns.slice(at + 1) : turns;
|
|
82115
82346
|
}
|
|
82116
82347
|
function claudeProjectDir(cwd, home = homedir4()) {
|
|
82117
|
-
return
|
|
82348
|
+
return join25(home, ".claude", "projects", cwd.replace(/[\\/:.]/g, "-"));
|
|
82118
82349
|
}
|
|
82119
82350
|
function recentTranscripts(cwd, opts = {}) {
|
|
82120
82351
|
const dir = claudeProjectDir(cwd, opts.home ?? homedir4());
|
|
82121
|
-
if (!
|
|
82352
|
+
if (!existsSync21(dir)) return [];
|
|
82122
82353
|
let names;
|
|
82123
82354
|
try {
|
|
82124
82355
|
names = readdirSync7(dir);
|
|
@@ -82129,7 +82360,7 @@ function recentTranscripts(cwd, opts = {}) {
|
|
|
82129
82360
|
const refs = [];
|
|
82130
82361
|
for (const name2 of names) {
|
|
82131
82362
|
if (!name2.endsWith(".jsonl")) continue;
|
|
82132
|
-
const path3 =
|
|
82363
|
+
const path3 = join25(dir, name2);
|
|
82133
82364
|
let mtimeMs;
|
|
82134
82365
|
try {
|
|
82135
82366
|
mtimeMs = statSync10(path3).mtimeMs;
|
|
@@ -82144,8 +82375,8 @@ function recentTranscripts(cwd, opts = {}) {
|
|
|
82144
82375
|
}
|
|
82145
82376
|
function subagentTranscripts(mainTranscriptPath, sessionId) {
|
|
82146
82377
|
if (!mainTranscriptPath || !sessionId) return [];
|
|
82147
|
-
const dir =
|
|
82148
|
-
if (!
|
|
82378
|
+
const dir = join25(dirname14(mainTranscriptPath), sessionId, "subagents");
|
|
82379
|
+
if (!existsSync21(dir)) return [];
|
|
82149
82380
|
let names;
|
|
82150
82381
|
try {
|
|
82151
82382
|
names = readdirSync7(dir);
|
|
@@ -82155,7 +82386,7 @@ function subagentTranscripts(mainTranscriptPath, sessionId) {
|
|
|
82155
82386
|
const refs = [];
|
|
82156
82387
|
for (const name2 of names) {
|
|
82157
82388
|
if (!name2.endsWith(".jsonl")) continue;
|
|
82158
|
-
const path3 =
|
|
82389
|
+
const path3 = join25(dir, name2);
|
|
82159
82390
|
let mtimeMs;
|
|
82160
82391
|
try {
|
|
82161
82392
|
mtimeMs = statSync10(path3).mtimeMs;
|
|
@@ -82169,13 +82400,13 @@ function subagentTranscripts(mainTranscriptPath, sessionId) {
|
|
|
82169
82400
|
}
|
|
82170
82401
|
function splitPathList(value, sep7 = delimiter) {
|
|
82171
82402
|
if (!value) return [];
|
|
82172
|
-
return value.split(sep7).map((d) => d.trim()).filter(Boolean).map((d) =>
|
|
82403
|
+
return value.split(sep7).map((d) => d.trim()).filter(Boolean).map((d) => normalize4(d));
|
|
82173
82404
|
}
|
|
82174
82405
|
function codexSessionRoots(env2 = process.env, home = homedir4()) {
|
|
82175
82406
|
const roots = /* @__PURE__ */ new Set();
|
|
82176
82407
|
for (const d of splitPathList(env2["ERRATA_CODEX_SESSIONS_DIRS"])) roots.add(d);
|
|
82177
|
-
if (env2["CODEX_HOME"]) roots.add(
|
|
82178
|
-
roots.add(
|
|
82408
|
+
if (env2["CODEX_HOME"]) roots.add(join25(env2["CODEX_HOME"], "sessions"));
|
|
82409
|
+
roots.add(join25(home, ".codex", "sessions"));
|
|
82179
82410
|
return [...roots];
|
|
82180
82411
|
}
|
|
82181
82412
|
function readCodexRolloutIdentity(path3) {
|
|
@@ -82229,7 +82460,7 @@ function codexRolloutsForCwd(cwd, opts = {}) {
|
|
|
82229
82460
|
const owner = checkoutRootOf(cwd);
|
|
82230
82461
|
const owners = /* @__PURE__ */ new Map();
|
|
82231
82462
|
for (const root of codexSessionRoots(opts.env, opts.home)) {
|
|
82232
|
-
if (!
|
|
82463
|
+
if (!existsSync21(root)) {
|
|
82233
82464
|
codexRolloutActivity.delete(root);
|
|
82234
82465
|
continue;
|
|
82235
82466
|
}
|
|
@@ -82247,7 +82478,7 @@ function codexRolloutsForCwd(cwd, opts = {}) {
|
|
|
82247
82478
|
continue;
|
|
82248
82479
|
}
|
|
82249
82480
|
for (const name2 of names) {
|
|
82250
|
-
const full =
|
|
82481
|
+
const full = join25(dir, name2);
|
|
82251
82482
|
let st;
|
|
82252
82483
|
try {
|
|
82253
82484
|
st = statSync10(full);
|
|
@@ -82289,8 +82520,8 @@ function codexRolloutsForCwd(cwd, opts = {}) {
|
|
|
82289
82520
|
function geminiSessionRoots(env2 = process.env, home = homedir4()) {
|
|
82290
82521
|
const roots = /* @__PURE__ */ new Set();
|
|
82291
82522
|
for (const d of splitPathList(env2["ERRATA_GEMINI_SESSIONS_DIRS"])) roots.add(d);
|
|
82292
|
-
if (env2["GEMINI_CLI_HOME"]) roots.add(
|
|
82293
|
-
roots.add(
|
|
82523
|
+
if (env2["GEMINI_CLI_HOME"]) roots.add(join25(env2["GEMINI_CLI_HOME"], ".gemini", "tmp"));
|
|
82524
|
+
roots.add(join25(home, ".gemini", "tmp"));
|
|
82294
82525
|
return [...roots];
|
|
82295
82526
|
}
|
|
82296
82527
|
function geminiProjectHash(cwd) {
|
|
@@ -82330,7 +82561,7 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
|
|
|
82330
82561
|
const hashes = geminiHashesFor(cwd);
|
|
82331
82562
|
const out2 = [];
|
|
82332
82563
|
for (const root of geminiSessionRoots(opts.env, opts.home)) {
|
|
82333
|
-
if (!
|
|
82564
|
+
if (!existsSync21(root)) continue;
|
|
82334
82565
|
let slugs;
|
|
82335
82566
|
try {
|
|
82336
82567
|
slugs = readdirSync7(root);
|
|
@@ -82338,7 +82569,7 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
|
|
|
82338
82569
|
continue;
|
|
82339
82570
|
}
|
|
82340
82571
|
for (const slug2 of slugs) {
|
|
82341
|
-
const chats =
|
|
82572
|
+
const chats = join25(root, slug2, "chats");
|
|
82342
82573
|
let names;
|
|
82343
82574
|
try {
|
|
82344
82575
|
names = readdirSync7(chats);
|
|
@@ -82347,7 +82578,7 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
|
|
|
82347
82578
|
}
|
|
82348
82579
|
for (const name2 of names) {
|
|
82349
82580
|
if (!name2.startsWith("session-") || !name2.endsWith(".jsonl")) continue;
|
|
82350
|
-
const full =
|
|
82581
|
+
const full = join25(chats, name2);
|
|
82351
82582
|
let st;
|
|
82352
82583
|
try {
|
|
82353
82584
|
st = statSync10(full);
|
|
@@ -82367,8 +82598,8 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
|
|
|
82367
82598
|
function opencodeSessionRoots(env2 = process.env, home = homedir4()) {
|
|
82368
82599
|
const roots = /* @__PURE__ */ new Set();
|
|
82369
82600
|
for (const d of splitPathList(env2["ERRATA_OPENCODE_SESSIONS_DIRS"])) roots.add(d);
|
|
82370
|
-
if (env2["XDG_DATA_HOME"]) roots.add(
|
|
82371
|
-
roots.add(
|
|
82601
|
+
if (env2["XDG_DATA_HOME"]) roots.add(join25(env2["XDG_DATA_HOME"], "opencode", "errata"));
|
|
82602
|
+
roots.add(join25(home, ".local", "share", "opencode", "errata"));
|
|
82372
82603
|
return [...roots];
|
|
82373
82604
|
}
|
|
82374
82605
|
function readOpencodeTranscriptDirectory(path3) {
|
|
@@ -82401,7 +82632,7 @@ function opencodeTranscriptsForCwd(cwd, opts = {}) {
|
|
|
82401
82632
|
}
|
|
82402
82633
|
const out2 = [];
|
|
82403
82634
|
for (const root of opencodeSessionRoots(opts.env, opts.home)) {
|
|
82404
|
-
if (!
|
|
82635
|
+
if (!existsSync21(root)) continue;
|
|
82405
82636
|
let names;
|
|
82406
82637
|
try {
|
|
82407
82638
|
names = readdirSync7(root);
|
|
@@ -82410,7 +82641,7 @@ function opencodeTranscriptsForCwd(cwd, opts = {}) {
|
|
|
82410
82641
|
}
|
|
82411
82642
|
for (const name2 of names) {
|
|
82412
82643
|
if (!name2.endsWith(".jsonl")) continue;
|
|
82413
|
-
const full =
|
|
82644
|
+
const full = join25(root, name2);
|
|
82414
82645
|
let st;
|
|
82415
82646
|
try {
|
|
82416
82647
|
st = statSync10(full);
|
|
@@ -82433,7 +82664,7 @@ init_src2();
|
|
|
82433
82664
|
init_agent_signals();
|
|
82434
82665
|
init_tool_index();
|
|
82435
82666
|
init_src5();
|
|
82436
|
-
import { readFileSync as
|
|
82667
|
+
import { readFileSync as readFileSync21, writeFileSync as writeFileSync15 } from "node:fs";
|
|
82437
82668
|
var NEG = /n['']t|\b(?:not|never|no|none|neither|nor|unrelated|irrelevant|would|might|could|if)\b/i;
|
|
82438
82669
|
var CITE_GROUP_RE = /\(((?:[^()\n]|\([^()\n]*\)){1,200})\)/g;
|
|
82439
82670
|
var HANDLE_RE2 = new RegExp(TAG_HANDLE_SOURCE, "gi");
|
|
@@ -83268,7 +83499,7 @@ function writePrimingHandles(path3, nodes, now = Date.now()) {
|
|
|
83268
83499
|
}
|
|
83269
83500
|
function readPrimingHandles(path3) {
|
|
83270
83501
|
try {
|
|
83271
|
-
return JSON.parse(
|
|
83502
|
+
return JSON.parse(readFileSync21(path3, "utf8"));
|
|
83272
83503
|
} catch {
|
|
83273
83504
|
return {};
|
|
83274
83505
|
}
|
|
@@ -83446,7 +83677,7 @@ function harvestInlineTags(store, text, opts) {
|
|
|
83446
83677
|
plan.fixes.push({ problemId, ...tag.fixRationale ? { fixNote: tag.fixRationale } : {} });
|
|
83447
83678
|
const witnessKey = `corrob:${problemId}:${digest({ h: tag.handle })}`.slice(0, 72);
|
|
83448
83679
|
if (!plan.corroborations.some((c) => c.witnessKey === witnessKey)) {
|
|
83449
|
-
plan.corroborations.push({ nodeId: problemId, witnessKey });
|
|
83680
|
+
plan.corroborations.push({ nodeId: problemId, witnessKey, via: "fix" });
|
|
83450
83681
|
}
|
|
83451
83682
|
} else plan.unresolvedFixes.push({ handle: tag.handle, ...tag.fixRationale ? { fixNote: tag.fixRationale } : {} });
|
|
83452
83683
|
} else if (tag.fixRationale) {
|
|
@@ -83607,7 +83838,7 @@ function harvestInlineTags(store, text, opts) {
|
|
|
83607
83838
|
if (!plan.corroborations.some((c) => c.witnessKey === witnessKey)) {
|
|
83608
83839
|
const exposure = typeof store.currentIngestSeq === "function" ? priorExposure(store, targetId, { seq: store.currentIngestSeq(), ts: opts.ts }) : "unshown";
|
|
83609
83840
|
countExposure(plan, exposure);
|
|
83610
|
-
plan.corroborations.push({ nodeId: targetId, witnessKey, exposure });
|
|
83841
|
+
plan.corroborations.push({ nodeId: targetId, witnessKey, exposure, via: "confirm" });
|
|
83611
83842
|
}
|
|
83612
83843
|
} else {
|
|
83613
83844
|
const witnessKey = `refute:${targetId}:${digest({ s: tag.statement ?? "" })}`.slice(0, 72);
|
|
@@ -83626,7 +83857,7 @@ function harvestInlineTags(store, text, opts) {
|
|
|
83626
83857
|
if (!plan.corroborations.some((c) => c.witnessKey === witnessKey)) {
|
|
83627
83858
|
const exposure = typeof store.currentIngestSeq === "function" ? priorExposure(store, targetId, { seq: store.currentIngestSeq(), ts: opts.ts }) : "unshown";
|
|
83628
83859
|
countExposure(plan, exposure);
|
|
83629
|
-
plan.corroborations.push({ nodeId: targetId, witnessKey, exposure });
|
|
83860
|
+
plan.corroborations.push({ nodeId: targetId, witnessKey, exposure, via: "lean" });
|
|
83630
83861
|
}
|
|
83631
83862
|
}
|
|
83632
83863
|
if (mintPriors && source && target) {
|
|
@@ -83782,6 +84013,154 @@ var SupersessionAsks = class {
|
|
|
83782
84013
|
}
|
|
83783
84014
|
};
|
|
83784
84015
|
|
|
84016
|
+
// src/held-asks.ts
|
|
84017
|
+
import { readFileSync as readFileSync22, renameSync as renameSync4, writeFileSync as writeFileSync16 } from "node:fs";
|
|
84018
|
+
import { dirname as dirname15, join as join26 } from "node:path";
|
|
84019
|
+
var HELD_ASK_TTL_MS = 2 * 60 * 6e4;
|
|
84020
|
+
var HELD_ASK_END_GRACE_MS = 2 * 6e4;
|
|
84021
|
+
var HELD_ASKS_SHOWN = 3;
|
|
84022
|
+
var REMEMBERED_PER_SESSION = 200;
|
|
84023
|
+
var SESSION_IDLE_MS2 = 24 * 60 * 6e4;
|
|
84024
|
+
var cap = (xs) => xs.slice(-REMEMBERED_PER_SESSION);
|
|
84025
|
+
var HeldAsks = class {
|
|
84026
|
+
sessions = /* @__PURE__ */ new Map();
|
|
84027
|
+
constructor(snapshot) {
|
|
84028
|
+
const isWitness = (w) => typeof w?.nodeId === "string" && typeof w?.witnessKey === "string";
|
|
84029
|
+
for (const s of snapshot?.sessions ?? []) {
|
|
84030
|
+
if (typeof s?.id !== "string" || !Array.isArray(s.asks)) continue;
|
|
84031
|
+
this.sessions.set(s.id, {
|
|
84032
|
+
asks: s.asks.filter((a) => typeof a?.priorId === "string" && isWitness(a.witness)),
|
|
84033
|
+
judged: Array.isArray(s.judged) ? s.judged.filter((j) => typeof j === "string") : [],
|
|
84034
|
+
released: Array.isArray(s.released) ? s.released.filter(isWitness) : [],
|
|
84035
|
+
touchedAt: Number(s.touchedAt) || 0,
|
|
84036
|
+
...typeof s.endedAt === "number" ? { endedAt: s.endedAt } : {}
|
|
84037
|
+
});
|
|
84038
|
+
}
|
|
84039
|
+
}
|
|
84040
|
+
/**
|
|
84041
|
+
* One harvest's leans and verdicts for a session — see the module doc for the
|
|
84042
|
+
* rules. `canOpen` is whether this turn can be asked (a live main session's own
|
|
84043
|
+
* turn); when it can't, leans still settle against what the session holds but
|
|
84044
|
+
* open nothing, and a lean on a prior it holds nothing for passes through.
|
|
84045
|
+
*/
|
|
84046
|
+
record(sessionId, harvest, now = Date.now()) {
|
|
84047
|
+
const out2 = {
|
|
84048
|
+
withheld: /* @__PURE__ */ new Set(),
|
|
84049
|
+
opened: [],
|
|
84050
|
+
answered: [],
|
|
84051
|
+
answeredShown: [],
|
|
84052
|
+
release: [],
|
|
84053
|
+
changed: false
|
|
84054
|
+
};
|
|
84055
|
+
if (!sessionId) return out2;
|
|
84056
|
+
const existing = this.sessions.get(sessionId);
|
|
84057
|
+
if (!existing && harvest.leaned.length === 0) return out2;
|
|
84058
|
+
const state = existing ?? { asks: [], judged: [], released: [], touchedAt: now };
|
|
84059
|
+
state.touchedAt = now;
|
|
84060
|
+
if (harvest.canOpen) delete state.endedAt;
|
|
84061
|
+
out2.changed = true;
|
|
84062
|
+
const said = new Set(state.judged);
|
|
84063
|
+
for (const v of harvest.verdicts) {
|
|
84064
|
+
const open2 = state.asks.find((a) => a.priorId === v.priorId);
|
|
84065
|
+
if (open2) {
|
|
84066
|
+
state.asks = state.asks.filter((a) => a !== open2);
|
|
84067
|
+
if (v.kind === "link") {
|
|
84068
|
+
out2.release.push({ sessionId, witness: open2.witness });
|
|
84069
|
+
state.released = cap([...state.released, open2.witness]);
|
|
84070
|
+
} else {
|
|
84071
|
+
out2.answered.push(v.priorId);
|
|
84072
|
+
if (open2.shownAt != null && open2.shownAt < now) out2.answeredShown.push(v.priorId);
|
|
84073
|
+
}
|
|
84074
|
+
} else if ((v.kind === "confirm" || v.kind === "fix") && v.witnessKey && state.released.some((w) => w.nodeId === v.priorId)) {
|
|
84075
|
+
out2.withheld.add(v.witnessKey);
|
|
84076
|
+
}
|
|
84077
|
+
if (v.kind !== "link") said.add(v.priorId);
|
|
84078
|
+
}
|
|
84079
|
+
state.judged = cap([...said]);
|
|
84080
|
+
for (const w of harvest.leaned) {
|
|
84081
|
+
const open2 = state.asks.find((a) => a.priorId === w.nodeId);
|
|
84082
|
+
if (open2 || said.has(w.nodeId) || state.released.some((r) => r.nodeId === w.nodeId)) {
|
|
84083
|
+
out2.withheld.add(w.witnessKey);
|
|
84084
|
+
if (open2) open2.leanedAt = Math.max(open2.leanedAt, now);
|
|
84085
|
+
continue;
|
|
84086
|
+
}
|
|
84087
|
+
if (!harvest.canOpen || harvest.verdicts.some((v) => v.priorId === w.nodeId && v.kind === "link")) {
|
|
84088
|
+
state.released = cap([...state.released, w]);
|
|
84089
|
+
continue;
|
|
84090
|
+
}
|
|
84091
|
+
out2.withheld.add(w.witnessKey);
|
|
84092
|
+
state.asks.push({ priorId: w.nodeId, leanedAt: now, witness: w });
|
|
84093
|
+
out2.opened.push(w.nodeId);
|
|
84094
|
+
}
|
|
84095
|
+
this.sessions.set(sessionId, state);
|
|
84096
|
+
return out2;
|
|
84097
|
+
}
|
|
84098
|
+
/** Open questions, newest first (the caller drops dead priors, then shows the first few). */
|
|
84099
|
+
forSession(sessionId, now = Date.now()) {
|
|
84100
|
+
const state = this.sessions.get(sessionId);
|
|
84101
|
+
if (!state || state.endedAt != null) return [];
|
|
84102
|
+
return state.asks.filter((a) => now - a.leanedAt < HELD_ASK_TTL_MS).sort((a, b) => b.leanedAt - a.leanedAt);
|
|
84103
|
+
}
|
|
84104
|
+
/** A render showed these questions. */
|
|
84105
|
+
markShown(sessionId, priorIds, now = Date.now()) {
|
|
84106
|
+
for (const a of this.sessions.get(sessionId)?.asks ?? []) if (priorIds.includes(a.priorId)) a.shownAt ??= now;
|
|
84107
|
+
}
|
|
84108
|
+
/** The prior is gone (invalidated): drop the question and its witness — there is nothing to corroborate. */
|
|
84109
|
+
discard(sessionId, priorId) {
|
|
84110
|
+
const state = this.sessions.get(sessionId);
|
|
84111
|
+
if (state) state.asks = state.asks.filter((a) => a.priorId !== priorId);
|
|
84112
|
+
}
|
|
84113
|
+
/** The session ended: its questions are released after a short grace (see {@link HELD_ASK_END_GRACE_MS}). */
|
|
84114
|
+
endSession(sessionId, now = Date.now()) {
|
|
84115
|
+
const state = this.sessions.get(sessionId);
|
|
84116
|
+
if (!state || state.endedAt != null) return false;
|
|
84117
|
+
state.endedAt = now;
|
|
84118
|
+
return true;
|
|
84119
|
+
}
|
|
84120
|
+
/** Questions past their TTL, or of sessions ended past the grace, across sessions: their leans are released. */
|
|
84121
|
+
expire(now = Date.now()) {
|
|
84122
|
+
const released = [];
|
|
84123
|
+
for (const [sessionId, state] of this.sessions) {
|
|
84124
|
+
const ended = state.endedAt != null && now - state.endedAt >= HELD_ASK_END_GRACE_MS;
|
|
84125
|
+
const keep = [];
|
|
84126
|
+
for (const a of state.asks) {
|
|
84127
|
+
if (ended || now - a.leanedAt >= HELD_ASK_TTL_MS) {
|
|
84128
|
+
released.push({ sessionId, witness: a.witness });
|
|
84129
|
+
state.released = cap([...state.released, a.witness]);
|
|
84130
|
+
} else keep.push(a);
|
|
84131
|
+
}
|
|
84132
|
+
state.asks = keep;
|
|
84133
|
+
if (keep.length === 0 && now - state.touchedAt > SESSION_IDLE_MS2) this.sessions.delete(sessionId);
|
|
84134
|
+
}
|
|
84135
|
+
return released;
|
|
84136
|
+
}
|
|
84137
|
+
/** A cache-key fingerprint of what this session's block could show. */
|
|
84138
|
+
version(sessionId, now = Date.now()) {
|
|
84139
|
+
return this.forSession(sessionId, now).map((a) => a.priorId).join(",");
|
|
84140
|
+
}
|
|
84141
|
+
snapshot() {
|
|
84142
|
+
return { sessions: [...this.sessions].map(([id, s]) => ({ id, ...s })) };
|
|
84143
|
+
}
|
|
84144
|
+
};
|
|
84145
|
+
function heldAsksPath(workspaceConfigDir) {
|
|
84146
|
+
return join26(workspaceConfigDir, "held-asks.json");
|
|
84147
|
+
}
|
|
84148
|
+
function loadHeldAsks(path3) {
|
|
84149
|
+
try {
|
|
84150
|
+
return new HeldAsks(JSON.parse(readFileSync22(path3, "utf8")));
|
|
84151
|
+
} catch {
|
|
84152
|
+
return new HeldAsks();
|
|
84153
|
+
}
|
|
84154
|
+
}
|
|
84155
|
+
function saveHeldAsks(path3, asks) {
|
|
84156
|
+
try {
|
|
84157
|
+
const tmp = join26(dirname15(path3), `.${Date.now()}.held-asks.tmp`);
|
|
84158
|
+
writeFileSync16(tmp, JSON.stringify(asks.snapshot()), "utf8");
|
|
84159
|
+
renameSync4(tmp, path3);
|
|
84160
|
+
} catch {
|
|
84161
|
+
}
|
|
84162
|
+
}
|
|
84163
|
+
|
|
83785
84164
|
// src/rollup.ts
|
|
83786
84165
|
function readConversation(transcriptPath, includeThinking = true, maxChars = 6e4) {
|
|
83787
84166
|
const raw2 = readTail(transcriptPath, 4e6);
|
|
@@ -83870,8 +84249,8 @@ ${conversation}` }]
|
|
|
83870
84249
|
// src/constraint-backfill.ts
|
|
83871
84250
|
init_src5();
|
|
83872
84251
|
init_src2();
|
|
83873
|
-
import { existsSync as
|
|
83874
|
-
import { join as
|
|
84252
|
+
import { existsSync as existsSync22, readFileSync as readFileSync23, readdirSync as readdirSync8, writeFileSync as writeFileSync17 } from "node:fs";
|
|
84253
|
+
import { join as join27 } from "node:path";
|
|
83875
84254
|
import { homedir as homedir5 } from "node:os";
|
|
83876
84255
|
var BACKFILL_VERSION = 1;
|
|
83877
84256
|
var EMPTY = {
|
|
@@ -83885,13 +84264,13 @@ var EMPTY = {
|
|
|
83885
84264
|
recoverable: 0
|
|
83886
84265
|
};
|
|
83887
84266
|
function markerPath(configDir) {
|
|
83888
|
-
return
|
|
84267
|
+
return join27(configDir, "constraint-backfill.json");
|
|
83889
84268
|
}
|
|
83890
84269
|
function alreadyDone(configDir) {
|
|
83891
84270
|
const p = markerPath(configDir);
|
|
83892
|
-
if (!
|
|
84271
|
+
if (!existsSync22(p)) return false;
|
|
83893
84272
|
try {
|
|
83894
|
-
const raw2 = JSON.parse(
|
|
84273
|
+
const raw2 = JSON.parse(readFileSync23(p, "utf8"));
|
|
83895
84274
|
return raw2?.version === BACKFILL_VERSION;
|
|
83896
84275
|
} catch {
|
|
83897
84276
|
return false;
|
|
@@ -83901,7 +84280,7 @@ function replay(root) {
|
|
|
83901
84280
|
const statements2 = /* @__PURE__ */ new Set();
|
|
83902
84281
|
const citedByFix = /* @__PURE__ */ new Set();
|
|
83903
84282
|
const dir = claudeProjectDir(root, homedir5());
|
|
83904
|
-
if (!
|
|
84283
|
+
if (!existsSync22(dir)) return { statements: statements2, citedByFix };
|
|
83905
84284
|
let names;
|
|
83906
84285
|
try {
|
|
83907
84286
|
names = readdirSync8(dir).filter((n) => n.endsWith(".jsonl"));
|
|
@@ -83911,7 +84290,7 @@ function replay(root) {
|
|
|
83911
84290
|
for (const f of names) {
|
|
83912
84291
|
let lines;
|
|
83913
84292
|
try {
|
|
83914
|
-
lines =
|
|
84293
|
+
lines = readFileSync23(join27(dir, f), "utf8").split("\n");
|
|
83915
84294
|
} catch {
|
|
83916
84295
|
continue;
|
|
83917
84296
|
}
|
|
@@ -84025,7 +84404,7 @@ function backfillConstraintKind(store, opts) {
|
|
|
84025
84404
|
}
|
|
84026
84405
|
});
|
|
84027
84406
|
try {
|
|
84028
|
-
|
|
84407
|
+
writeFileSync17(
|
|
84029
84408
|
markerPath(opts.configDir),
|
|
84030
84409
|
JSON.stringify({ version: BACKFILL_VERSION, at: opts.now, ...report, cloudTwins: report.cloudTwins.length }, null, 2),
|
|
84031
84410
|
"utf8"
|
|
@@ -84038,8 +84417,8 @@ function backfillConstraintKind(store, opts) {
|
|
|
84038
84417
|
// src/edge-repair.ts
|
|
84039
84418
|
init_src();
|
|
84040
84419
|
init_src5();
|
|
84041
|
-
import { existsSync as
|
|
84042
|
-
import { join as
|
|
84420
|
+
import { existsSync as existsSync23, readFileSync as readFileSync24, writeFileSync as writeFileSync18 } from "node:fs";
|
|
84421
|
+
import { join as join28 } from "node:path";
|
|
84043
84422
|
function citeEdgeId(from, type, to) {
|
|
84044
84423
|
return `edge_${digest({ from, type, to })}`.slice(0, 24);
|
|
84045
84424
|
}
|
|
@@ -84054,13 +84433,13 @@ var EMPTY2 = {
|
|
|
84054
84433
|
byType: {}
|
|
84055
84434
|
};
|
|
84056
84435
|
function markerPath2(configDir) {
|
|
84057
|
-
return
|
|
84436
|
+
return join28(configDir, "edge-repair.json");
|
|
84058
84437
|
}
|
|
84059
84438
|
function alreadyDone2(configDir) {
|
|
84060
84439
|
const p = markerPath2(configDir);
|
|
84061
|
-
if (!
|
|
84440
|
+
if (!existsSync23(p)) return false;
|
|
84062
84441
|
try {
|
|
84063
|
-
return JSON.parse(
|
|
84442
|
+
return JSON.parse(readFileSync24(p, "utf8"))?.version === EDGE_REPAIR_VERSION;
|
|
84064
84443
|
} catch {
|
|
84065
84444
|
return false;
|
|
84066
84445
|
}
|
|
@@ -84109,7 +84488,7 @@ function repairInvalidEdges(store, opts) {
|
|
|
84109
84488
|
});
|
|
84110
84489
|
store.pruneEdgeRejections(opts.now - REJECTION_RETENTION_MS);
|
|
84111
84490
|
try {
|
|
84112
|
-
|
|
84491
|
+
writeFileSync18(
|
|
84113
84492
|
markerPath2(opts.configDir),
|
|
84114
84493
|
JSON.stringify({ version: EDGE_REPAIR_VERSION, at: opts.now, ...report }, null, 2),
|
|
84115
84494
|
"utf8"
|
|
@@ -84123,8 +84502,8 @@ function repairInvalidEdges(store, opts) {
|
|
|
84123
84502
|
init_reconcile();
|
|
84124
84503
|
|
|
84125
84504
|
// src/pass-ledger.ts
|
|
84126
|
-
import { appendFileSync as appendFileSync2, existsSync as
|
|
84127
|
-
import { join as
|
|
84505
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync24, readFileSync as readFileSync25, writeFileSync as writeFileSync19 } from "node:fs";
|
|
84506
|
+
import { join as join29 } from "node:path";
|
|
84128
84507
|
|
|
84129
84508
|
// src/isolate-census.ts
|
|
84130
84509
|
var live3 = 0;
|
|
@@ -84155,7 +84534,7 @@ var HOUR_MS = 36e5;
|
|
|
84155
84534
|
var TRIM_EVERY = 50;
|
|
84156
84535
|
var appendsSinceTrim = /* @__PURE__ */ new Map();
|
|
84157
84536
|
function passLedgerPath(configDir) {
|
|
84158
|
-
return
|
|
84537
|
+
return join29(configDir, "pass-ledger.jsonl");
|
|
84159
84538
|
}
|
|
84160
84539
|
function appendPassLedger(configDir, kind, durationMs, counts) {
|
|
84161
84540
|
const path3 = passLedgerPath(configDir);
|
|
@@ -84187,7 +84566,7 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
|
|
|
84187
84566
|
return;
|
|
84188
84567
|
}
|
|
84189
84568
|
appendsSinceTrim.set(path3, 0);
|
|
84190
|
-
const lines =
|
|
84569
|
+
const lines = readFileSync25(path3, "utf8").split("\n").filter(Boolean);
|
|
84191
84570
|
const keptByKind = /* @__PURE__ */ new Map();
|
|
84192
84571
|
const tailHours = /* @__PURE__ */ new Map();
|
|
84193
84572
|
const tailFloor = Date.now() - LEVEL_TAIL_DAYS * 24 * HOUR_MS;
|
|
@@ -84215,16 +84594,16 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
|
|
|
84215
84594
|
kept.push(lines[i2]);
|
|
84216
84595
|
}
|
|
84217
84596
|
if (kept.length < lines.length) {
|
|
84218
|
-
|
|
84597
|
+
writeFileSync19(path3, kept.reverse().join("\n") + "\n");
|
|
84219
84598
|
}
|
|
84220
84599
|
} catch {
|
|
84221
84600
|
}
|
|
84222
84601
|
}
|
|
84223
84602
|
function readPassLedger(configDir) {
|
|
84224
84603
|
const path3 = passLedgerPath(configDir);
|
|
84225
|
-
if (!
|
|
84604
|
+
if (!existsSync24(path3)) return [];
|
|
84226
84605
|
try {
|
|
84227
|
-
return
|
|
84606
|
+
return readFileSync25(path3, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter(
|
|
84228
84607
|
(e) => typeof e?.ts === "number" && typeof e?.kind === "string" && typeof e?.durationMs === "number"
|
|
84229
84608
|
).map((e) => ({ ...e, counts: e.counts ?? {} }));
|
|
84230
84609
|
} catch {
|
|
@@ -84667,11 +85046,11 @@ init_outbox();
|
|
|
84667
85046
|
init_src10();
|
|
84668
85047
|
init_src();
|
|
84669
85048
|
init_src2();
|
|
84670
|
-
import { readFileSync as
|
|
84671
|
-
import { join as
|
|
85049
|
+
import { readFileSync as readFileSync26 } from "node:fs";
|
|
85050
|
+
import { join as join30 } from "node:path";
|
|
84672
85051
|
function loadClaimIgnorePatterns(workspaceRoot) {
|
|
84673
85052
|
try {
|
|
84674
|
-
return
|
|
85053
|
+
return readFileSync26(join30(workspaceRoot, ".errataignore"), "utf8").split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#")).map((l) => l.toLowerCase());
|
|
84675
85054
|
} catch {
|
|
84676
85055
|
return [];
|
|
84677
85056
|
}
|
|
@@ -85054,9 +85433,9 @@ async function pullCloudTriage(shared, cloud, profile, limit = 50) {
|
|
|
85054
85433
|
// src/retrieval-stack.ts
|
|
85055
85434
|
init_src();
|
|
85056
85435
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
85057
|
-
import { existsSync as
|
|
85436
|
+
import { existsSync as existsSync25, readFileSync as readFileSync27, statSync as statSync11 } from "node:fs";
|
|
85058
85437
|
import { homedir as homedir6 } from "node:os";
|
|
85059
|
-
import { join as
|
|
85438
|
+
import { join as join31 } from "node:path";
|
|
85060
85439
|
var RETRIEVAL_STACK_CAP = 24;
|
|
85061
85440
|
var MANIFEST_SCAN_CAP = 400;
|
|
85062
85441
|
var RUNTIME_TOKENS = /* @__PURE__ */ new Set([
|
|
@@ -85346,51 +85725,51 @@ function mavenGroupIsSelfDisclosing(name2, selfTokens) {
|
|
|
85346
85725
|
function loadRegistryPolicy(root, env2 = process.env, repoLocator) {
|
|
85347
85726
|
const read2 = (p) => {
|
|
85348
85727
|
try {
|
|
85349
|
-
return
|
|
85728
|
+
return readFileSync27(p, "utf8");
|
|
85350
85729
|
} catch {
|
|
85351
85730
|
return null;
|
|
85352
85731
|
}
|
|
85353
85732
|
};
|
|
85354
85733
|
const texts = (...paths) => paths.map(read2).filter((t) => t !== null);
|
|
85355
85734
|
const home = homedir6();
|
|
85356
|
-
const npm = parseNpmrcPolicy(texts(
|
|
85735
|
+
const npm = parseNpmrcPolicy(texts(join31(root, ".npmrc"), join31(home, ".npmrc")));
|
|
85357
85736
|
const blocked = /* @__PURE__ */ new Set();
|
|
85358
85737
|
if (!npm.defaultPublic) blocked.add("npm");
|
|
85359
85738
|
if (pypiIndexIsPrivate(
|
|
85360
85739
|
texts(
|
|
85361
|
-
|
|
85362
|
-
|
|
85363
|
-
|
|
85364
|
-
|
|
85365
|
-
|
|
85366
|
-
|
|
85367
|
-
|
|
85740
|
+
join31(root, "pip.conf"),
|
|
85741
|
+
join31(root, "pip.ini"),
|
|
85742
|
+
join31(root, "pyproject.toml"),
|
|
85743
|
+
join31(root, "requirements.txt"),
|
|
85744
|
+
join31(home, ".pip", "pip.conf"),
|
|
85745
|
+
join31(home, ".config", "pip", "pip.conf"),
|
|
85746
|
+
join31(env2["APPDATA"] ?? home, "pip", "pip.ini")
|
|
85368
85747
|
)
|
|
85369
85748
|
)) {
|
|
85370
85749
|
blocked.add("pypi");
|
|
85371
85750
|
}
|
|
85372
85751
|
if (cargoRegistryIsPrivate(
|
|
85373
85752
|
texts(
|
|
85374
|
-
|
|
85375
|
-
|
|
85376
|
-
|
|
85377
|
-
|
|
85753
|
+
join31(root, ".cargo", "config.toml"),
|
|
85754
|
+
join31(root, ".cargo", "config"),
|
|
85755
|
+
join31(home, ".cargo", "config.toml"),
|
|
85756
|
+
join31(home, ".cargo", "config")
|
|
85378
85757
|
)
|
|
85379
85758
|
)) {
|
|
85380
85759
|
blocked.add("cargo");
|
|
85381
85760
|
}
|
|
85382
85761
|
if (nugetSourcesArePrivate(
|
|
85383
85762
|
texts(
|
|
85384
|
-
|
|
85385
|
-
|
|
85386
|
-
|
|
85387
|
-
|
|
85388
|
-
|
|
85763
|
+
join31(root, "NuGet.config"),
|
|
85764
|
+
join31(root, "nuget.config"),
|
|
85765
|
+
join31(root, "NuGet.Config"),
|
|
85766
|
+
join31(env2["APPDATA"] ?? home, "NuGet", "NuGet.Config"),
|
|
85767
|
+
join31(home, ".nuget", "NuGet", "NuGet.Config")
|
|
85389
85768
|
)
|
|
85390
85769
|
)) {
|
|
85391
85770
|
blocked.add("nuget");
|
|
85392
85771
|
}
|
|
85393
|
-
const goEnvFile = env2["GOENV"] ??
|
|
85772
|
+
const goEnvFile = env2["GOENV"] ?? join31(env2["APPDATA"] ?? join31(home, ".config"), "go", "env");
|
|
85394
85773
|
const goEnvText = read2(goEnvFile) ?? "";
|
|
85395
85774
|
const fromFile = ["GOPRIVATE", "GONOSUMDB", "GONOSUMCHECK"].map(
|
|
85396
85775
|
(k) => new RegExp(`^${k}=(.*)$`, "m").exec(goEnvText)?.[1]
|
|
@@ -85401,10 +85780,10 @@ function loadRegistryPolicy(root, env2 = process.env, repoLocator) {
|
|
|
85401
85780
|
env2["GONOSUMCHECK"],
|
|
85402
85781
|
...fromFile
|
|
85403
85782
|
]);
|
|
85404
|
-
const gemfiles = texts(
|
|
85783
|
+
const gemfiles = texts(join31(root, "Gemfile"));
|
|
85405
85784
|
if (gemSourceIsPrivate(gemfiles)) blocked.add("gem");
|
|
85406
85785
|
if (mavenReposArePrivate(
|
|
85407
|
-
texts(
|
|
85786
|
+
texts(join31(root, "pom.xml"), join31(home, ".m2", "settings.xml"))
|
|
85408
85787
|
)) {
|
|
85409
85788
|
blocked.add("maven");
|
|
85410
85789
|
}
|
|
@@ -85476,7 +85855,7 @@ function isLocalSpec(version3) {
|
|
|
85476
85855
|
return v.startsWith("workspace:") || v.startsWith("link:") || v.startsWith("file:") || v.startsWith("portal:") || v.startsWith("path:") || v.startsWith("git:") || v.startsWith("git+") || v.includes("://") || VCS_HOST_SHORTHAND.test(v) || SCP_STYLE_REMOTE.test(v) || BARE_REPO_SHORTHAND.test(v);
|
|
85477
85856
|
}
|
|
85478
85857
|
function retrievalStackTokens(input) {
|
|
85479
|
-
const
|
|
85858
|
+
const cap2 = input.cap ?? RETRIEVAL_STACK_CAP;
|
|
85480
85859
|
const registry2 = input.registry ?? PUBLIC_REGISTRY_POLICY;
|
|
85481
85860
|
const ignore2 = input.ignorePatterns ?? [];
|
|
85482
85861
|
const ignored = (token) => ignore2.length > 0 && ignore2.some((p) => token.includes(p));
|
|
@@ -85534,10 +85913,10 @@ function retrievalStackTokens(input) {
|
|
|
85534
85913
|
}
|
|
85535
85914
|
const queues = [...byEcosystem.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([ecosystem, cs]) => ({ ecosystem, items: rankCandidates(cs) }));
|
|
85536
85915
|
const usedEcosystems = /* @__PURE__ */ new Set();
|
|
85537
|
-
for (let round2 = 0; tokens.length <
|
|
85916
|
+
for (let round2 = 0; tokens.length < cap2; round2++) {
|
|
85538
85917
|
let emittedThisRound = false;
|
|
85539
85918
|
for (const q of queues) {
|
|
85540
|
-
if (tokens.length >=
|
|
85919
|
+
if (tokens.length >= cap2) break;
|
|
85541
85920
|
const c = q.items[round2];
|
|
85542
85921
|
if (!c) continue;
|
|
85543
85922
|
emittedThisRound = true;
|
|
@@ -85550,14 +85929,14 @@ function retrievalStackTokens(input) {
|
|
|
85550
85929
|
}
|
|
85551
85930
|
if (packagesAllowed) {
|
|
85552
85931
|
for (const t of normStackTokens(input.profileStack)) {
|
|
85553
|
-
if (tokens.length >=
|
|
85932
|
+
if (tokens.length >= cap2) break;
|
|
85554
85933
|
if (isRuntimeToken(t)) continue;
|
|
85555
85934
|
if (!isPublicDep({ ecosystem: "npm", name: t }, registry2)) continue;
|
|
85556
85935
|
push(t);
|
|
85557
85936
|
}
|
|
85558
85937
|
}
|
|
85559
85938
|
const source = fromLockfile > 0 && fromManifest > 0 ? "both" : fromLockfile > 0 ? "lockfile" : fromManifest > 0 ? "manifest" : "profile";
|
|
85560
|
-
return { tokens: tokens.slice(0,
|
|
85939
|
+
return { tokens: tokens.slice(0, cap2), source, ecosystems: [...usedEcosystems].sort() };
|
|
85561
85940
|
}
|
|
85562
85941
|
var LOCKFILES = [
|
|
85563
85942
|
{ file: "pnpm-lock.yaml", family: "npm", parse: parsePnpmLock },
|
|
@@ -85571,8 +85950,8 @@ function readDirectDependencies(root) {
|
|
|
85571
85950
|
const familiesSeen = /* @__PURE__ */ new Set();
|
|
85572
85951
|
for (const c of LOCKFILES) {
|
|
85573
85952
|
if (familiesSeen.has(c.family)) continue;
|
|
85574
|
-
const p =
|
|
85575
|
-
if (!
|
|
85953
|
+
const p = join31(root, c.file);
|
|
85954
|
+
if (!existsSync25(p)) continue;
|
|
85576
85955
|
try {
|
|
85577
85956
|
const s = statSync11(p);
|
|
85578
85957
|
stamps.push(`${c.file}:${s.mtimeMs}:${s.size}`);
|
|
@@ -85592,7 +85971,7 @@ function readDirectDependencies(root) {
|
|
|
85592
85971
|
const direct = [];
|
|
85593
85972
|
for (const { c, path: path3 } of found) {
|
|
85594
85973
|
try {
|
|
85595
|
-
direct.push(...c.parse(
|
|
85974
|
+
direct.push(...c.parse(readFileSync27(path3, "utf8")).direct ?? []);
|
|
85596
85975
|
} catch {
|
|
85597
85976
|
}
|
|
85598
85977
|
}
|
|
@@ -85635,14 +86014,14 @@ function manifestPaths(root) {
|
|
|
85635
86014
|
"project.godot"
|
|
85636
86015
|
];
|
|
85637
86016
|
return {
|
|
85638
|
-
paths: ROOT_MANIFESTS.filter((f) =>
|
|
86017
|
+
paths: ROOT_MANIFESTS.filter((f) => existsSync25(join31(root, f))),
|
|
85639
86018
|
tracked: false,
|
|
85640
86019
|
truncated: false
|
|
85641
86020
|
};
|
|
85642
86021
|
}
|
|
85643
86022
|
var WORKSPACE_MARKERS = ["pnpm-workspace.yaml", "lerna.json", "go.work", "settings.gradle", "settings.gradle.kts"];
|
|
85644
86023
|
function rootDeclaresWorkspace(root, texts) {
|
|
85645
|
-
if (WORKSPACE_MARKERS.some((f) =>
|
|
86024
|
+
if (WORKSPACE_MARKERS.some((f) => existsSync25(join31(root, f)))) return true;
|
|
85646
86025
|
return /"workspaces"\s*:/.test(texts.get("package.json") ?? "") || /<modules>/.test(texts.get("pom.xml") ?? "") || /^\s*\[workspace\]/m.test(texts.get("Cargo.toml") ?? "");
|
|
85647
86026
|
}
|
|
85648
86027
|
var EMPTY_SCAN = { deps: [], self: [], complete: true };
|
|
@@ -85656,11 +86035,11 @@ function scanManifests(root) {
|
|
|
85656
86035
|
const texts = /* @__PURE__ */ new Map();
|
|
85657
86036
|
const stamps = [];
|
|
85658
86037
|
for (const rel of paths) {
|
|
85659
|
-
const abs =
|
|
86038
|
+
const abs = join31(root, rel);
|
|
85660
86039
|
try {
|
|
85661
86040
|
const s = statSync11(abs);
|
|
85662
86041
|
stamps.push(`${rel}:${s.mtimeMs}:${s.size}`);
|
|
85663
|
-
texts.set(rel,
|
|
86042
|
+
texts.set(rel, readFileSync27(abs, "utf8"));
|
|
85664
86043
|
} catch {
|
|
85665
86044
|
}
|
|
85666
86045
|
}
|
|
@@ -85696,22 +86075,22 @@ function readRetrievalInputs(root, repoLocator) {
|
|
|
85696
86075
|
}
|
|
85697
86076
|
|
|
85698
86077
|
// src/git-sensor.ts
|
|
85699
|
-
import { existsSync as
|
|
85700
|
-
import { join as
|
|
86078
|
+
import { existsSync as existsSync26, readFileSync as readFileSync28, watch as fsWatch } from "node:fs";
|
|
86079
|
+
import { join as join32 } from "node:path";
|
|
85701
86080
|
function readFirstLine(path3) {
|
|
85702
86081
|
try {
|
|
85703
|
-
return
|
|
86082
|
+
return readFileSync28(path3, "utf8").split(/\r?\n/, 1)[0].trim();
|
|
85704
86083
|
} catch {
|
|
85705
86084
|
return null;
|
|
85706
86085
|
}
|
|
85707
86086
|
}
|
|
85708
86087
|
function readGitRefState(gitDir) {
|
|
85709
|
-
const head2 = readFirstLine(
|
|
86088
|
+
const head2 = readFirstLine(join32(gitDir, "HEAD"));
|
|
85710
86089
|
const m = head2 ? /^ref:\s*refs\/heads\/(.+)$/.exec(head2) : null;
|
|
85711
86090
|
const branch = m ? m[1] : null;
|
|
85712
86091
|
let sha2 = null;
|
|
85713
86092
|
if (branch) {
|
|
85714
|
-
sha2 = readFirstLine(
|
|
86093
|
+
sha2 = readFirstLine(join32(gitDir, "refs", "heads", branch));
|
|
85715
86094
|
if (!sha2) sha2 = shaFromPackedRefs(gitDir, `refs/heads/${branch}`);
|
|
85716
86095
|
} else if (head2 && /^[0-9a-f]{7,40}$/i.test(head2)) {
|
|
85717
86096
|
sha2 = head2;
|
|
@@ -85719,13 +86098,13 @@ function readGitRefState(gitDir) {
|
|
|
85719
86098
|
return {
|
|
85720
86099
|
branch,
|
|
85721
86100
|
sha: sha2,
|
|
85722
|
-
mergeHeadExists:
|
|
85723
|
-
origHeadExists:
|
|
86101
|
+
mergeHeadExists: existsSync26(join32(gitDir, "MERGE_HEAD")),
|
|
86102
|
+
origHeadExists: existsSync26(join32(gitDir, "ORIG_HEAD"))
|
|
85724
86103
|
};
|
|
85725
86104
|
}
|
|
85726
86105
|
function shaFromPackedRefs(gitDir, ref) {
|
|
85727
86106
|
try {
|
|
85728
|
-
for (const line of
|
|
86107
|
+
for (const line of readFileSync28(join32(gitDir, "packed-refs"), "utf8").split(/\r?\n/)) {
|
|
85729
86108
|
const [sha2, name2] = line.split(/\s+/);
|
|
85730
86109
|
if (name2 === ref && sha2) return sha2;
|
|
85731
86110
|
}
|
|
@@ -85759,7 +86138,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
|
|
|
85759
86138
|
const settle = () => {
|
|
85760
86139
|
if (timer) clearTimeout(timer);
|
|
85761
86140
|
timer = setTimeout(() => {
|
|
85762
|
-
if (
|
|
86141
|
+
if (existsSync26(join32(gitDir, "index.lock"))) {
|
|
85763
86142
|
settle();
|
|
85764
86143
|
return;
|
|
85765
86144
|
}
|
|
@@ -85770,7 +86149,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
|
|
|
85770
86149
|
}, debounceMs);
|
|
85771
86150
|
};
|
|
85772
86151
|
for (const sub of ["HEAD", "logs/HEAD", "MERGE_HEAD", "ORIG_HEAD"]) {
|
|
85773
|
-
const p =
|
|
86152
|
+
const p = join32(gitDir, sub);
|
|
85774
86153
|
try {
|
|
85775
86154
|
watchers.push(fsWatch(p, settle));
|
|
85776
86155
|
} catch {
|
|
@@ -86000,8 +86379,8 @@ var TelemetryRecorder = class {
|
|
|
86000
86379
|
};
|
|
86001
86380
|
|
|
86002
86381
|
// src/file-activity.ts
|
|
86003
|
-
import { readFileSync as
|
|
86004
|
-
import { join as
|
|
86382
|
+
import { readFileSync as readFileSync30 } from "node:fs";
|
|
86383
|
+
import { join as join34 } from "node:path";
|
|
86005
86384
|
import { createHash as createHash17 } from "node:crypto";
|
|
86006
86385
|
|
|
86007
86386
|
// ../../packages/privacy/src/patterns/credentials.ts
|
|
@@ -86753,8 +87132,8 @@ init_git_remote();
|
|
|
86753
87132
|
// src/history-bundle.ts
|
|
86754
87133
|
init_src();
|
|
86755
87134
|
import { execFile as execFile3 } from "node:child_process";
|
|
86756
|
-
import { readFileSync as
|
|
86757
|
-
import { join as
|
|
87135
|
+
import { readFileSync as readFileSync29 } from "node:fs";
|
|
87136
|
+
import { join as join33 } from "node:path";
|
|
86758
87137
|
var DEFAULT_MAX_TOKENS = 6e3;
|
|
86759
87138
|
var FILE_LIST_CAP = 60;
|
|
86760
87139
|
var DIFF_FILE_CAP = 40;
|
|
@@ -86793,7 +87172,7 @@ function pathAllowedByFloor(path3) {
|
|
|
86793
87172
|
function loadRepoIgnore(root, extraPatterns = []) {
|
|
86794
87173
|
let source = "";
|
|
86795
87174
|
try {
|
|
86796
|
-
source =
|
|
87175
|
+
source = readFileSync29(join33(root, ".errataignore"), "utf8");
|
|
86797
87176
|
} catch {
|
|
86798
87177
|
source = "";
|
|
86799
87178
|
}
|
|
@@ -87098,7 +87477,7 @@ function readActivityBranch(root) {
|
|
|
87098
87477
|
try {
|
|
87099
87478
|
const gitDir = resolveGitDir(root);
|
|
87100
87479
|
if (!gitDir) return null;
|
|
87101
|
-
const head2 =
|
|
87480
|
+
const head2 = readFileSync30(join34(gitDir, "HEAD"), "utf8").trim();
|
|
87102
87481
|
const branch = head2.startsWith("ref: refs/heads/") ? head2.slice(16) : /^[a-f0-9]{40,64}$/i.test(head2) ? "HEAD" : null;
|
|
87103
87482
|
return branch && branch.length <= 256 && !/[\x00-\x1f\x7f]/.test(branch) ? branch : null;
|
|
87104
87483
|
} catch {
|
|
@@ -87255,21 +87634,21 @@ var FileActivityReporter = class {
|
|
|
87255
87634
|
|
|
87256
87635
|
// src/skills.ts
|
|
87257
87636
|
import {
|
|
87258
|
-
existsSync as
|
|
87637
|
+
existsSync as existsSync27,
|
|
87259
87638
|
mkdirSync as mkdirSync7,
|
|
87260
|
-
readFileSync as
|
|
87639
|
+
readFileSync as readFileSync31,
|
|
87261
87640
|
readdirSync as readdirSync9,
|
|
87262
87641
|
unlinkSync as unlinkSync4,
|
|
87263
|
-
writeFileSync as
|
|
87642
|
+
writeFileSync as writeFileSync20
|
|
87264
87643
|
} from "node:fs";
|
|
87265
|
-
import { basename as basename7, join as
|
|
87644
|
+
import { basename as basename7, join as join35 } from "node:path";
|
|
87266
87645
|
function skillFileName(id) {
|
|
87267
87646
|
return `${id.replace(/[^A-Za-z0-9_.-]/g, "_")}.md`;
|
|
87268
87647
|
}
|
|
87269
87648
|
function readSkillManifest(manifestPath) {
|
|
87270
|
-
if (!
|
|
87649
|
+
if (!existsSync27(manifestPath)) return [];
|
|
87271
87650
|
try {
|
|
87272
|
-
const parsed = JSON.parse(
|
|
87651
|
+
const parsed = JSON.parse(readFileSync31(manifestPath, "utf8"));
|
|
87273
87652
|
return (parsed.skills ?? []).map((s) => ({
|
|
87274
87653
|
title: s.title ?? "",
|
|
87275
87654
|
layer: s.layer ?? "technique",
|
|
@@ -87293,7 +87672,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
|
|
|
87293
87672
|
for (const s of res.skills) {
|
|
87294
87673
|
const fileName = skillFileName(s.id);
|
|
87295
87674
|
keep.add(fileName);
|
|
87296
|
-
|
|
87675
|
+
writeFileSync20(join35(paths.skillsDir, fileName), s.markdown, "utf8");
|
|
87297
87676
|
rows.push({
|
|
87298
87677
|
id: s.id,
|
|
87299
87678
|
title: s.title,
|
|
@@ -87306,7 +87685,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
|
|
|
87306
87685
|
const fileName = skillFileName(p.id);
|
|
87307
87686
|
if (keep.has(fileName)) continue;
|
|
87308
87687
|
keep.add(fileName);
|
|
87309
|
-
|
|
87688
|
+
writeFileSync20(join35(paths.skillsDir, fileName), p.markdown, "utf8");
|
|
87310
87689
|
rows.push({
|
|
87311
87690
|
id: p.id,
|
|
87312
87691
|
title: p.title,
|
|
@@ -87320,13 +87699,13 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
|
|
|
87320
87699
|
if (!f.endsWith(".md")) continue;
|
|
87321
87700
|
if (keep.has(basename7(f))) continue;
|
|
87322
87701
|
try {
|
|
87323
|
-
unlinkSync4(
|
|
87702
|
+
unlinkSync4(join35(paths.skillsDir, f));
|
|
87324
87703
|
pruned++;
|
|
87325
87704
|
} catch {
|
|
87326
87705
|
}
|
|
87327
87706
|
}
|
|
87328
87707
|
rows.sort((a, b) => a.id.localeCompare(b.id));
|
|
87329
|
-
|
|
87708
|
+
writeFileSync20(
|
|
87330
87709
|
paths.skillsManifest,
|
|
87331
87710
|
JSON.stringify({ generatedAt: Date.now(), skills: rows }, null, 2),
|
|
87332
87711
|
"utf8"
|
|
@@ -87338,22 +87717,22 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
|
|
|
87338
87717
|
init_src2();
|
|
87339
87718
|
import {
|
|
87340
87719
|
cpSync,
|
|
87341
|
-
existsSync as
|
|
87720
|
+
existsSync as existsSync28,
|
|
87342
87721
|
lstatSync,
|
|
87343
87722
|
mkdirSync as mkdirSync8,
|
|
87344
|
-
readFileSync as
|
|
87723
|
+
readFileSync as readFileSync32,
|
|
87345
87724
|
readdirSync as readdirSync10,
|
|
87346
87725
|
rmSync as rmSync3,
|
|
87347
87726
|
symlinkSync,
|
|
87348
|
-
writeFileSync as
|
|
87727
|
+
writeFileSync as writeFileSync21
|
|
87349
87728
|
} from "node:fs";
|
|
87350
|
-
import { join as
|
|
87729
|
+
import { join as join36 } from "node:path";
|
|
87351
87730
|
var SKILL_NS = "errata-";
|
|
87352
87731
|
var HARNESS_SKILL_DIRS = [
|
|
87353
|
-
{ configDir: ".claude", skillsDir:
|
|
87732
|
+
{ configDir: ".claude", skillsDir: join36(".claude", "skills") },
|
|
87354
87733
|
// Cursor adopted the standard; its exact project dir is still moving — kept
|
|
87355
87734
|
// best-effort and gated on `.cursor/` presence so we never create it blind.
|
|
87356
|
-
{ configDir: ".cursor", skillsDir:
|
|
87735
|
+
{ configDir: ".cursor", skillsDir: join36(".cursor", "skills") }
|
|
87357
87736
|
];
|
|
87358
87737
|
function skillSlug(title, id) {
|
|
87359
87738
|
const base = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || id.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "skill";
|
|
@@ -87398,12 +87777,12 @@ function skillCiteHandle(s) {
|
|
|
87398
87777
|
return priorHandle({ id: s.id, description: s.title });
|
|
87399
87778
|
}
|
|
87400
87779
|
function reconcileNamespaced(dir, keep) {
|
|
87401
|
-
if (!
|
|
87780
|
+
if (!existsSync28(dir)) return 0;
|
|
87402
87781
|
let pruned = 0;
|
|
87403
87782
|
for (const name2 of readdirSync10(dir)) {
|
|
87404
87783
|
if (!name2.startsWith(SKILL_NS) || keep.has(name2)) continue;
|
|
87405
87784
|
try {
|
|
87406
|
-
rmSync3(
|
|
87785
|
+
rmSync3(join36(dir, name2), { recursive: true, force: true });
|
|
87407
87786
|
pruned++;
|
|
87408
87787
|
} catch {
|
|
87409
87788
|
}
|
|
@@ -87412,7 +87791,7 @@ function reconcileNamespaced(dir, keep) {
|
|
|
87412
87791
|
}
|
|
87413
87792
|
function linkOrCopy(linkPath, target) {
|
|
87414
87793
|
try {
|
|
87415
|
-
if (
|
|
87794
|
+
if (existsSync28(linkPath) || safeLstat(linkPath)) rmSync3(linkPath, { recursive: true, force: true });
|
|
87416
87795
|
} catch {
|
|
87417
87796
|
}
|
|
87418
87797
|
try {
|
|
@@ -87433,7 +87812,7 @@ function safeLstat(p) {
|
|
|
87433
87812
|
}
|
|
87434
87813
|
}
|
|
87435
87814
|
function emitAndProjectSkills(root, skills) {
|
|
87436
|
-
const agentsSkillsDir =
|
|
87815
|
+
const agentsSkillsDir = join36(root, ".agents", "skills");
|
|
87437
87816
|
mkdirSync8(agentsSkillsDir, { recursive: true });
|
|
87438
87817
|
const slugs = [];
|
|
87439
87818
|
const keep = /* @__PURE__ */ new Set();
|
|
@@ -87441,7 +87820,7 @@ function emitAndProjectSkills(root, skills) {
|
|
|
87441
87820
|
for (const s of skills) {
|
|
87442
87821
|
let body2;
|
|
87443
87822
|
try {
|
|
87444
|
-
body2 =
|
|
87823
|
+
body2 = readFileSync32(s.bodyPath, "utf8");
|
|
87445
87824
|
} catch {
|
|
87446
87825
|
continue;
|
|
87447
87826
|
}
|
|
@@ -87450,9 +87829,9 @@ function emitAndProjectSkills(root, skills) {
|
|
|
87450
87829
|
keep.add(slug2);
|
|
87451
87830
|
slugs.push(slug2);
|
|
87452
87831
|
const description = deriveDescription(s.title, s.layer, body2);
|
|
87453
|
-
mkdirSync8(
|
|
87454
|
-
|
|
87455
|
-
|
|
87832
|
+
mkdirSync8(join36(agentsSkillsDir, slug2), { recursive: true });
|
|
87833
|
+
writeFileSync21(
|
|
87834
|
+
join36(agentsSkillsDir, slug2, "SKILL.md"),
|
|
87456
87835
|
renderSkillMd(slug2, description, body2, skillCiteHandle(s)),
|
|
87457
87836
|
"utf8"
|
|
87458
87837
|
);
|
|
@@ -87461,11 +87840,11 @@ function emitAndProjectSkills(root, skills) {
|
|
|
87461
87840
|
reconcileNamespaced(agentsSkillsDir, keep);
|
|
87462
87841
|
let projected = 0;
|
|
87463
87842
|
for (const h of HARNESS_SKILL_DIRS) {
|
|
87464
|
-
if (!
|
|
87465
|
-
const dir =
|
|
87843
|
+
if (!existsSync28(join36(root, h.configDir))) continue;
|
|
87844
|
+
const dir = join36(root, h.skillsDir);
|
|
87466
87845
|
mkdirSync8(dir, { recursive: true });
|
|
87467
87846
|
for (const slug2 of slugs) {
|
|
87468
|
-
linkOrCopy(
|
|
87847
|
+
linkOrCopy(join36(dir, slug2), join36(agentsSkillsDir, slug2));
|
|
87469
87848
|
projected++;
|
|
87470
87849
|
}
|
|
87471
87850
|
reconcileNamespaced(dir, keep);
|
|
@@ -87474,15 +87853,15 @@ function emitAndProjectSkills(root, skills) {
|
|
|
87474
87853
|
return { slugs, emitted, projected };
|
|
87475
87854
|
}
|
|
87476
87855
|
function emitInputsFromManifest(erretaDir, manifestPath) {
|
|
87477
|
-
if (!
|
|
87856
|
+
if (!existsSync28(manifestPath)) return [];
|
|
87478
87857
|
try {
|
|
87479
|
-
const parsed = JSON.parse(
|
|
87858
|
+
const parsed = JSON.parse(readFileSync32(manifestPath, "utf8"));
|
|
87480
87859
|
return (parsed.skills ?? []).filter((s) => Boolean(s.id && s.file)).map((s) => ({
|
|
87481
87860
|
id: s.id,
|
|
87482
87861
|
title: s.title ?? s.id,
|
|
87483
87862
|
layer: s.layer ?? "technique",
|
|
87484
87863
|
confidence: s.confidence ?? 0,
|
|
87485
|
-
bodyPath:
|
|
87864
|
+
bodyPath: join36(erretaDir, s.file)
|
|
87486
87865
|
}));
|
|
87487
87866
|
} catch {
|
|
87488
87867
|
return [];
|
|
@@ -87496,17 +87875,17 @@ var GITIGNORE_LINES = [
|
|
|
87496
87875
|
".cursor/skills/errata-*/"
|
|
87497
87876
|
];
|
|
87498
87877
|
function ensureSkillGitignore(root) {
|
|
87499
|
-
const path3 =
|
|
87878
|
+
const path3 = join36(root, ".gitignore");
|
|
87500
87879
|
let current = "";
|
|
87501
87880
|
try {
|
|
87502
|
-
current =
|
|
87881
|
+
current = existsSync28(path3) ? readFileSync32(path3, "utf8") : "";
|
|
87503
87882
|
} catch {
|
|
87504
87883
|
return;
|
|
87505
87884
|
}
|
|
87506
87885
|
if (current.includes(GITIGNORE_MARK)) return;
|
|
87507
87886
|
const prefix = current.length > 0 && !current.endsWith("\n") ? "\n" : "";
|
|
87508
87887
|
try {
|
|
87509
|
-
|
|
87888
|
+
writeFileSync21(path3, `${current}${prefix}
|
|
87510
87889
|
${GITIGNORE_LINES.join("\n")}
|
|
87511
87890
|
`, "utf8");
|
|
87512
87891
|
} catch {
|
|
@@ -87696,18 +88075,18 @@ init_paths();
|
|
|
87696
88075
|
init_profile2();
|
|
87697
88076
|
|
|
87698
88077
|
// src/witness-queue.ts
|
|
87699
|
-
import { readFileSync as
|
|
87700
|
-
import { dirname as
|
|
88078
|
+
import { readFileSync as readFileSync33, renameSync as renameSync5, writeFileSync as writeFileSync22 } from "node:fs";
|
|
88079
|
+
import { dirname as dirname16, join as join37 } from "node:path";
|
|
87701
88080
|
var WITNESS_QUEUE_CAP = 500;
|
|
87702
88081
|
var WITNESS_TTL_MS = 14 * 24 * 60 * 60 * 1e3;
|
|
87703
88082
|
var WITNESS_MAX_ATTEMPTS = 5;
|
|
87704
88083
|
function witnessQueuePath(workspaceConfigDir) {
|
|
87705
|
-
return
|
|
88084
|
+
return join37(workspaceConfigDir, "witness-queue.json");
|
|
87706
88085
|
}
|
|
87707
88086
|
function loadWitnessQueueWithLosses(path3) {
|
|
87708
88087
|
let raw2;
|
|
87709
88088
|
try {
|
|
87710
|
-
raw2 = JSON.parse(
|
|
88089
|
+
raw2 = JSON.parse(readFileSync33(path3, "utf8"));
|
|
87711
88090
|
} catch (err2) {
|
|
87712
88091
|
const absent = err2?.code === "ENOENT";
|
|
87713
88092
|
return { queue: [], fileUnreadable: !absent, malformedEntries: 0 };
|
|
@@ -87720,9 +88099,9 @@ function loadWitnessQueueWithLosses(path3) {
|
|
|
87720
88099
|
}
|
|
87721
88100
|
function saveWitnessQueue(path3, queue) {
|
|
87722
88101
|
try {
|
|
87723
|
-
const tmp =
|
|
87724
|
-
|
|
87725
|
-
|
|
88102
|
+
const tmp = join37(dirname16(path3), `.${Date.now()}.witness-queue.tmp`);
|
|
88103
|
+
writeFileSync22(tmp, JSON.stringify(queue), "utf8");
|
|
88104
|
+
renameSync5(tmp, path3);
|
|
87726
88105
|
} catch {
|
|
87727
88106
|
}
|
|
87728
88107
|
}
|
|
@@ -87740,6 +88119,9 @@ function pruneWitnessQueueWithDispositions(queue, now) {
|
|
|
87740
88119
|
}
|
|
87741
88120
|
return { queue: live4, dropped };
|
|
87742
88121
|
}
|
|
88122
|
+
function enqueueWitnesses(queue, fresh, now) {
|
|
88123
|
+
return enqueueWitnessesWithDispositions(queue, fresh, now).queue;
|
|
88124
|
+
}
|
|
87743
88125
|
function enqueueWitnessesWithDispositions(queue, fresh, now) {
|
|
87744
88126
|
const byKey = new Map(queue.map((w) => [`${w.channel}:${w.witnessKey}`, w]));
|
|
87745
88127
|
for (const f of fresh) {
|
|
@@ -88030,8 +88412,8 @@ function maybeFlushDigests() {
|
|
|
88030
88412
|
|
|
88031
88413
|
// src/liveness-watch.ts
|
|
88032
88414
|
init_src5();
|
|
88033
|
-
import { readFileSync as
|
|
88034
|
-
import { join as
|
|
88415
|
+
import { readFileSync as readFileSync35, writeFileSync as writeFileSync24 } from "node:fs";
|
|
88416
|
+
import { join as join39 } from "node:path";
|
|
88035
88417
|
|
|
88036
88418
|
// src/loop-lag.ts
|
|
88037
88419
|
var HEARTBEAT_MS = 500;
|
|
@@ -88163,11 +88545,11 @@ function watchCensusLine(c = watchCensus(), now = Date.now()) {
|
|
|
88163
88545
|
var LIVENESS_WATCH_INTERVAL_MS = 60 * 60 * 1e3;
|
|
88164
88546
|
var ALARM_RENOTIFY_MS = 24 * 60 * 60 * 1e3;
|
|
88165
88547
|
function alarmStatePath(configDir) {
|
|
88166
|
-
return
|
|
88548
|
+
return join39(configDir, "liveness-alarms.json");
|
|
88167
88549
|
}
|
|
88168
88550
|
function loadAlarmState(path3) {
|
|
88169
88551
|
try {
|
|
88170
|
-
const raw2 = JSON.parse(
|
|
88552
|
+
const raw2 = JSON.parse(readFileSync35(path3, "utf8"));
|
|
88171
88553
|
return new Map(Object.entries(raw2).filter((e) => typeof e[1] === "number"));
|
|
88172
88554
|
} catch {
|
|
88173
88555
|
return /* @__PURE__ */ new Map();
|
|
@@ -88175,7 +88557,7 @@ function loadAlarmState(path3) {
|
|
|
88175
88557
|
}
|
|
88176
88558
|
function saveAlarmState(path3, state) {
|
|
88177
88559
|
try {
|
|
88178
|
-
|
|
88560
|
+
writeFileSync24(path3, JSON.stringify(Object.fromEntries(state)));
|
|
88179
88561
|
} catch {
|
|
88180
88562
|
}
|
|
88181
88563
|
}
|
|
@@ -88431,7 +88813,7 @@ function createWatchBreaker(deps) {
|
|
|
88431
88813
|
}
|
|
88432
88814
|
|
|
88433
88815
|
// src/engine.ts
|
|
88434
|
-
var DAEMON_VERSION = true ? "2.0.23-dev.
|
|
88816
|
+
var DAEMON_VERSION = true ? "2.0.23-dev.4938" : "2.0.0-alpha.0";
|
|
88435
88817
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
88436
88818
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
88437
88819
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -88443,8 +88825,8 @@ var CODEX_SWEEP_LOOKBACK_MS = 10 * 6e4;
|
|
|
88443
88825
|
function appendIdentityAudit(path3, record2, line) {
|
|
88444
88826
|
if (!record2.accepted && record2.score <= 0) return;
|
|
88445
88827
|
try {
|
|
88446
|
-
if (
|
|
88447
|
-
|
|
88828
|
+
if (existsSync30(path3) && statSync12(path3).size >= IDENTITY_AUDIT_MAX_BYTES) {
|
|
88829
|
+
renameSync6(path3, `${path3}.1`);
|
|
88448
88830
|
}
|
|
88449
88831
|
appendFileSync4(path3, line);
|
|
88450
88832
|
} catch {
|
|
@@ -88453,7 +88835,7 @@ function appendIdentityAudit(path3, record2, line) {
|
|
|
88453
88835
|
var yieldToLoop = () => new Promise((r) => setImmediate(r));
|
|
88454
88836
|
function loadTurnCursors(path3) {
|
|
88455
88837
|
try {
|
|
88456
|
-
const raw2 = JSON.parse(
|
|
88838
|
+
const raw2 = JSON.parse(readFileSync36(path3, "utf8"));
|
|
88457
88839
|
return new Map(
|
|
88458
88840
|
Object.entries(raw2).map(([k, v]) => [k, typeof v === "string" ? v : String(v?.uuid ?? "")])
|
|
88459
88841
|
);
|
|
@@ -88463,7 +88845,7 @@ function loadTurnCursors(path3) {
|
|
|
88463
88845
|
}
|
|
88464
88846
|
function loadTurnOffsets(path3) {
|
|
88465
88847
|
try {
|
|
88466
|
-
const raw2 = JSON.parse(
|
|
88848
|
+
const raw2 = JSON.parse(readFileSync36(path3, "utf8"));
|
|
88467
88849
|
const out2 = /* @__PURE__ */ new Map();
|
|
88468
88850
|
for (const [k, v] of Object.entries(raw2)) {
|
|
88469
88851
|
const off2 = typeof v === "object" && v !== null ? v.offset : void 0;
|
|
@@ -88476,7 +88858,7 @@ function loadTurnOffsets(path3) {
|
|
|
88476
88858
|
}
|
|
88477
88859
|
function loadTurnMoves(path3) {
|
|
88478
88860
|
try {
|
|
88479
|
-
const raw2 = JSON.parse(
|
|
88861
|
+
const raw2 = JSON.parse(readFileSync36(path3, "utf8"));
|
|
88480
88862
|
const out2 = /* @__PURE__ */ new Map();
|
|
88481
88863
|
for (const [k, v] of Object.entries(raw2)) {
|
|
88482
88864
|
const to = typeof v === "object" && v !== null ? v.movedTo : void 0;
|
|
@@ -88493,11 +88875,11 @@ function saveTurnCursors(path3, cursors, offsets, moves = /* @__PURE__ */ new Ma
|
|
|
88493
88875
|
for (const [k, uuid3] of cursors) merged[k] = { uuid: uuid3, offset: offsets.get(k) ?? 0 };
|
|
88494
88876
|
for (const [k, offset] of offsets) if (!merged[k]) merged[k] = { uuid: "", offset };
|
|
88495
88877
|
for (const [k, movedTo] of moves) merged[k] = { ...merged[k] ?? { uuid: "", offset: 0 }, movedTo };
|
|
88496
|
-
|
|
88878
|
+
writeFileSync25(path3, JSON.stringify(merged), "utf8");
|
|
88497
88879
|
} catch {
|
|
88498
88880
|
}
|
|
88499
88881
|
}
|
|
88500
|
-
var turnCursorFile = (configDir) =>
|
|
88882
|
+
var turnCursorFile = (configDir) => join40(configDir, "turn-cursors.json");
|
|
88501
88883
|
function turnCursorOnDisk(configDir, sessionId) {
|
|
88502
88884
|
const path3 = turnCursorFile(configDir);
|
|
88503
88885
|
const offset = loadTurnOffsets(path3).get(sessionId);
|
|
@@ -88529,7 +88911,7 @@ function gitSourceWatchTargets(root) {
|
|
|
88529
88911
|
["-C", root, "ls-files", "--others", "--ignored", "--exclude-standard", "--directory", "-z"],
|
|
88530
88912
|
{ encoding: "utf8", maxBuffer: 256 * 1024 * 1024, windowsHide: true, stdio: ["ignore", "pipe", "ignore"] }
|
|
88531
88913
|
);
|
|
88532
|
-
ignoredDirs = igOut.split("\0").filter(Boolean).map((d) => d.replace(/\/+$/, "")).filter((d) => !IGNORED_PATH.test(
|
|
88914
|
+
ignoredDirs = igOut.split("\0").filter(Boolean).map((d) => d.replace(/\/+$/, "")).filter((d) => !IGNORED_PATH.test(join40(root, d) + sep5));
|
|
88533
88915
|
} catch {
|
|
88534
88916
|
}
|
|
88535
88917
|
const hasIgnoredChild = (dir) => ignoredDirs.some((ig) => ig.startsWith(dir + "/"));
|
|
@@ -88541,19 +88923,19 @@ function gitSourceWatchTargets(root) {
|
|
|
88541
88923
|
if (!f.startsWith(prefix)) continue;
|
|
88542
88924
|
const rest2 = f.slice(prefix.length);
|
|
88543
88925
|
if (rest2.includes("/")) children.add(dir === "" ? rest2.slice(0, rest2.indexOf("/")) : dir + "/" + rest2.slice(0, rest2.indexOf("/")));
|
|
88544
|
-
else targets.add(
|
|
88926
|
+
else targets.add(join40(root, f));
|
|
88545
88927
|
}
|
|
88546
88928
|
for (const c of children) {
|
|
88547
|
-
if (IGNORED_PATH.test(
|
|
88929
|
+
if (IGNORED_PATH.test(join40(root, c) + sep5)) continue;
|
|
88548
88930
|
if (hasIgnoredChild(c)) addUnder(c);
|
|
88549
|
-
else targets.add(
|
|
88931
|
+
else targets.add(join40(root, c));
|
|
88550
88932
|
}
|
|
88551
88933
|
};
|
|
88552
88934
|
addUnder("");
|
|
88553
88935
|
if (targets.size > 0) return [...targets];
|
|
88554
88936
|
} catch {
|
|
88555
88937
|
}
|
|
88556
|
-
return readdirSync11(root, { withFileTypes: true }).filter((e) => e.isDirectory() && !IGNORED_PATH.test(
|
|
88938
|
+
return readdirSync11(root, { withFileTypes: true }).filter((e) => e.isDirectory() && !IGNORED_PATH.test(join40(root, String(e.name)) + sep5)).map((e) => join40(root, String(e.name)));
|
|
88557
88939
|
}
|
|
88558
88940
|
function createWorkspaceEngine(opts) {
|
|
88559
88941
|
const paths = workspacePaths(opts.workspaceRoot);
|
|
@@ -88755,7 +89137,7 @@ function createWorkspaceEngine(opts) {
|
|
|
88755
89137
|
const srcPaths = diff.changedPaths.filter((p) => /\.(ts|tsx|js|jsx|mjs|cjs|py)$/i.test(p));
|
|
88756
89138
|
let episodeId2;
|
|
88757
89139
|
if (srcPaths.length > 0) {
|
|
88758
|
-
const abs = srcPaths.map((p) =>
|
|
89140
|
+
const abs = srcPaths.map((p) => join40(opts.workspaceRoot, p));
|
|
88759
89141
|
try {
|
|
88760
89142
|
const r = await runReindexPass(
|
|
88761
89143
|
`git-reindex:${profile.name} (${abs.length} files)`,
|
|
@@ -88791,8 +89173,8 @@ function createWorkspaceEngine(opts) {
|
|
|
88791
89173
|
`[errata] git: ${ev.kind} ${ev.newSha.slice(0, 7)} by ${meta3.authorName} \u2014 ${diff.changedPaths.length} file(s), ${diff.renames.length} rename(s)`
|
|
88792
89174
|
);
|
|
88793
89175
|
};
|
|
88794
|
-
const gitDir =
|
|
88795
|
-
if (
|
|
89176
|
+
const gitDir = join40(opts.workspaceRoot, ".git");
|
|
89177
|
+
if (existsSync30(gitDir)) {
|
|
88796
89178
|
stopGit = startGitSensor(gitDir, (ev) => {
|
|
88797
89179
|
void handleGitEvent(ev).catch((err2) => {
|
|
88798
89180
|
console.warn("[errata] git event handler failed:", err2);
|
|
@@ -88853,7 +89235,7 @@ function createWorkspaceEngine(opts) {
|
|
|
88853
89235
|
},
|
|
88854
89236
|
onAlarms: (alarms) => {
|
|
88855
89237
|
toastLivenessAlarms(
|
|
88856
|
-
sharedAlarmToastGate(
|
|
89238
|
+
sharedAlarmToastGate(join40(globalDir(), "liveness-toasts.json")),
|
|
88857
89239
|
{ root: opts.workspaceRoot, name: profile.name },
|
|
88858
89240
|
alarms,
|
|
88859
89241
|
(body2, key) => notifyEvent("mechanism-stalled", body2, { key }),
|
|
@@ -88880,10 +89262,27 @@ function createWorkspaceEngine(opts) {
|
|
|
88880
89262
|
let subagentBase = null;
|
|
88881
89263
|
let subagentBaseVersion = 0;
|
|
88882
89264
|
const subagentRenders = /* @__PURE__ */ new Map();
|
|
88883
|
-
const sessions = createSessionRegistry({ originsPath:
|
|
89265
|
+
const sessions = createSessionRegistry({ originsPath: join40(paths.configDir, "session-origins.json") });
|
|
88884
89266
|
const sessionRenders = /* @__PURE__ */ new Map();
|
|
88885
89267
|
const selfCiteSkipsBySession = /* @__PURE__ */ new Map();
|
|
88886
89268
|
const supersessionAsks = new SupersessionAsks();
|
|
89269
|
+
const heldAsks = loadHeldAsks(heldAsksPath(paths.configDir));
|
|
89270
|
+
const releaseHeld = (all, t) => {
|
|
89271
|
+
const released = all.filter((r) => store.getNode(r.witness.nodeId)?.validTo == null);
|
|
89272
|
+
if (all.length > 0 && released.length === 0) saveHeldAsks(heldAsksPath(paths.configDir), heldAsks);
|
|
89273
|
+
if (released.length === 0) return { stamped: 0, fixHeld: 0 };
|
|
89274
|
+
const { stamped } = applyLocalConfirmations(store, released.map((r) => r.witness), t);
|
|
89275
|
+
let fixHeld = 0;
|
|
89276
|
+
for (const r of released) if (store.getNode(r.witness.nodeId)?.label === "Solution") fixHeld += confirmFixHeld(store, r.witness.nodeId, t);
|
|
89277
|
+
witnessQueue = enqueueWitnesses(
|
|
89278
|
+
witnessQueue,
|
|
89279
|
+
released.map((r) => ({ channel: "corroborate", ...r.witness, sessionKey: sessionOriginKey(r.sessionId), counted: false })),
|
|
89280
|
+
Date.now()
|
|
89281
|
+
);
|
|
89282
|
+
saveWitnessQueue(witnessQueuePath(paths.configDir), witnessQueue);
|
|
89283
|
+
saveHeldAsks(heldAsksPath(paths.configDir), heldAsks);
|
|
89284
|
+
return { stamped, fixHeld };
|
|
89285
|
+
};
|
|
88887
89286
|
const toolRuns = createToolRunState();
|
|
88888
89287
|
let ctxRefreshTimer = null;
|
|
88889
89288
|
let contextDirty = false;
|
|
@@ -88963,6 +89362,23 @@ function createWorkspaceEngine(opts) {
|
|
|
88963
89362
|
const priors = a.priorIds.map((id) => store.getNode(id)).filter((n) => n !== null && n.validTo == null).map((n) => ({ id: n.id, description: n.description, ...lifecycleField(n) }));
|
|
88964
89363
|
return fix && priors.length > 0 ? [{ fix: { id: fix.id, description: fix.description }, priors }] : [];
|
|
88965
89364
|
});
|
|
89365
|
+
const heldAsksFor = (sessionId) => {
|
|
89366
|
+
const shown = [];
|
|
89367
|
+
let discarded = false;
|
|
89368
|
+
for (const a of heldAsks.forSession(sessionId)) {
|
|
89369
|
+
if (shown.length >= HELD_ASKS_SHOWN) break;
|
|
89370
|
+
const n = store.getNode(a.priorId);
|
|
89371
|
+
if (n && n.validTo != null) {
|
|
89372
|
+
heldAsks.discard(sessionId, a.priorId);
|
|
89373
|
+
discarded = true;
|
|
89374
|
+
continue;
|
|
89375
|
+
}
|
|
89376
|
+
shown.push(n ? { id: n.id, description: n.description, ...lifecycleField(n) } : { id: a.priorId });
|
|
89377
|
+
}
|
|
89378
|
+
heldAsks.markShown(sessionId, shown.map((s) => s.id));
|
|
89379
|
+
if (discarded) saveHeldAsks(heldAsksPath(paths.configDir), heldAsks);
|
|
89380
|
+
return shown;
|
|
89381
|
+
};
|
|
88966
89382
|
const statedIntentFor = (intent) => {
|
|
88967
89383
|
const collective = intentRemote?.forIntent === intent ? intentRemote : null;
|
|
88968
89384
|
return {
|
|
@@ -88985,7 +89401,7 @@ function createWorkspaceEngine(opts) {
|
|
|
88985
89401
|
const elicit = isEdgeElicitationEnabled();
|
|
88986
89402
|
const snapOpts = {
|
|
88987
89403
|
profile,
|
|
88988
|
-
atCommit: readGitRefState(
|
|
89404
|
+
atCommit: readGitRefState(join40(opts.workspaceRoot, ".git")).sha ?? void 0,
|
|
88989
89405
|
reviewCount: pendingCount(paths),
|
|
88990
89406
|
reviewUiUrl: opts.reviewUrl(),
|
|
88991
89407
|
workingFile: workingFiles.mostRecent() ?? void 0,
|
|
@@ -89025,7 +89441,7 @@ function createWorkspaceEngine(opts) {
|
|
|
89025
89441
|
);
|
|
89026
89442
|
return null;
|
|
89027
89443
|
}) : null;
|
|
89028
|
-
if (snapOpts.atCommit !== (readGitRefState(
|
|
89444
|
+
if (snapOpts.atCommit !== (readGitRefState(join40(opts.workspaceRoot, ".git")).sha ?? void 0)) {
|
|
89029
89445
|
contextDirty = true;
|
|
89030
89446
|
return;
|
|
89031
89447
|
}
|
|
@@ -89071,10 +89487,10 @@ function createWorkspaceEngine(opts) {
|
|
|
89071
89487
|
} catch (err2) {
|
|
89072
89488
|
console.warn("[errata] context card failed:", err2.message?.slice(0, 120));
|
|
89073
89489
|
}
|
|
89074
|
-
const target =
|
|
89490
|
+
const target = join40(opts.workspaceRoot, "AGENTS.md");
|
|
89075
89491
|
writeManagedBlock(target, { body: AGENTS_POINTER_BODY, stable: true, force: true });
|
|
89076
89492
|
if (elicit) {
|
|
89077
|
-
writePrimingHandles(
|
|
89493
|
+
writePrimingHandles(join40(paths.configDir, "priming-handles.json"), [
|
|
89078
89494
|
...snapshot.recentProblems.map((r) => r.node),
|
|
89079
89495
|
// Resolved-band handles: the ✓ problem AND its Solution are citable
|
|
89080
89496
|
// (a fix tag on an already-resolved problem no-ops idempotently; the
|
|
@@ -89382,8 +89798,8 @@ function createWorkspaceEngine(opts) {
|
|
|
89382
89798
|
const cached2 = subagentRenders.get(a.agentId);
|
|
89383
89799
|
if (cached2?.key === key) return cached2.block;
|
|
89384
89800
|
const elicit = isEdgeElicitationEnabled();
|
|
89385
|
-
const handlesPath =
|
|
89386
|
-
const atCommit = readGitRefState(
|
|
89801
|
+
const handlesPath = join40(paths.configDir, "priming-handles.json");
|
|
89802
|
+
const atCommit = readGitRefState(join40(opts.workspaceRoot, ".git")).sha ?? void 0;
|
|
89387
89803
|
const block = renderSubagentBlock({
|
|
89388
89804
|
store,
|
|
89389
89805
|
entry,
|
|
@@ -89416,8 +89832,10 @@ function createWorkspaceEngine(opts) {
|
|
|
89416
89832
|
sessions.touch(e.sessionId, now, origin);
|
|
89417
89833
|
return;
|
|
89418
89834
|
}
|
|
89419
|
-
if (e.ended)
|
|
89420
|
-
|
|
89835
|
+
if (e.ended) {
|
|
89836
|
+
sessions.end(e.sessionId);
|
|
89837
|
+
if (heldAsks.endSession(e.sessionId, now)) saveHeldAsks(heldAsksPath(paths.configDir), heldAsks);
|
|
89838
|
+
} else sessions.touch(e.sessionId, now, origin);
|
|
89421
89839
|
};
|
|
89422
89840
|
const sessionContext = (sessionId) => {
|
|
89423
89841
|
if (!sessionId || !subagentBase) return null;
|
|
@@ -89427,6 +89845,7 @@ function createWorkspaceEngine(opts) {
|
|
|
89427
89845
|
const skips = selfCiteSkipsBySession.get(sessionId) ?? 0;
|
|
89428
89846
|
const key = JSON.stringify([
|
|
89429
89847
|
supersessionAsks.version(sessionId),
|
|
89848
|
+
heldAsks.version(sessionId),
|
|
89430
89849
|
subagentBaseVersion,
|
|
89431
89850
|
lastRemoteAt,
|
|
89432
89851
|
sessions.version(now),
|
|
@@ -89438,7 +89857,7 @@ function createWorkspaceEngine(opts) {
|
|
|
89438
89857
|
const cached2 = sessionRenders.get(sessionId);
|
|
89439
89858
|
if (cached2?.key === key) return cached2.block;
|
|
89440
89859
|
const elicit = isEdgeElicitationEnabled();
|
|
89441
|
-
const atCommit = readGitRefState(
|
|
89860
|
+
const atCommit = readGitRefState(join40(opts.workspaceRoot, ".git")).sha ?? void 0;
|
|
89442
89861
|
const scoped = scopeSnapshot(structuredClone(subagentBase), (n) => !hiddenFrom(n, sessionId, sessions, now));
|
|
89443
89862
|
delete scoped.workingFile;
|
|
89444
89863
|
if (workingFile) {
|
|
@@ -89450,6 +89869,9 @@ function createWorkspaceEngine(opts) {
|
|
|
89450
89869
|
delete scoped.supersessionAsks;
|
|
89451
89870
|
const asks = supersessionAsksFor(sessionId);
|
|
89452
89871
|
if (asks.length > 0) scoped.supersessionAsks = asks;
|
|
89872
|
+
delete scoped.heldAsks;
|
|
89873
|
+
const held = heldAsksFor(sessionId);
|
|
89874
|
+
if (held.length > 0) scoped.heldAsks = held;
|
|
89453
89875
|
if (taskPriorsOn) {
|
|
89454
89876
|
scoped.recentProblems = [];
|
|
89455
89877
|
scoped.recentResolved = [];
|
|
@@ -89490,7 +89912,7 @@ function createWorkspaceEngine(opts) {
|
|
|
89490
89912
|
]
|
|
89491
89913
|
};
|
|
89492
89914
|
if (elicit && block.handleNodes.length) {
|
|
89493
|
-
writePrimingHandles(
|
|
89915
|
+
writePrimingHandles(join40(paths.configDir, "priming-handles.json"), block.handleNodes);
|
|
89494
89916
|
}
|
|
89495
89917
|
sessionRenders.delete(sessionId);
|
|
89496
89918
|
sessionRenders.set(sessionId, { key, block });
|
|
@@ -89598,6 +90020,8 @@ function createWorkspaceEngine(opts) {
|
|
|
89598
90020
|
let confirmsStamped = 0;
|
|
89599
90021
|
let supersessionAsked = 0;
|
|
89600
90022
|
let structureLinksMinted = 0;
|
|
90023
|
+
let heldAsked = 0;
|
|
90024
|
+
let heldAnswered = 0;
|
|
89601
90025
|
let recurrencesMarked = 0;
|
|
89602
90026
|
let reopenedFromRegression = 0;
|
|
89603
90027
|
let fixHeldConfirmed = 0;
|
|
@@ -89624,7 +90048,7 @@ function createWorkspaceEngine(opts) {
|
|
|
89624
90048
|
let processedTurns = 0;
|
|
89625
90049
|
const seqAtStart = store.currentIngestSeq();
|
|
89626
90050
|
const elicit = isEdgeElicitationEnabled();
|
|
89627
|
-
const handleMap = elicit ? readPrimingHandles(
|
|
90051
|
+
const handleMap = elicit ? readPrimingHandles(join40(paths.configDir, "priming-handles.json")) : {};
|
|
89628
90052
|
const wsRoot = (opts.workspaceRoot ?? "").replace(/\\/g, "/");
|
|
89629
90053
|
const toRel = (abs) => {
|
|
89630
90054
|
const p = abs.replace(/\\/g, "/");
|
|
@@ -89788,6 +90212,45 @@ function createWorkspaceEngine(opts) {
|
|
|
89788
90212
|
corroboratedEdges += plan.corroboratedEdges;
|
|
89789
90213
|
citeAnchorsAccrued += plan.citeAnchorsAccrued;
|
|
89790
90214
|
citeAnchorsPromoted += plan.citeAnchorsPromoted;
|
|
90215
|
+
{
|
|
90216
|
+
const expired = releaseHeld(heldAsks.expire(t), t);
|
|
90217
|
+
confirmsStamped += expired.stamped;
|
|
90218
|
+
fixHeldConfirmed += expired.fixHeld;
|
|
90219
|
+
}
|
|
90220
|
+
let withheldLeanIds = [];
|
|
90221
|
+
if (sessions.originOf(sessionId) === void 0) {
|
|
90222
|
+
const subagentTurn = turn.agentId != null || sessionId.startsWith("agent-");
|
|
90223
|
+
const canOpen = !subagentTurn && sessions.isLive(sessionId, t);
|
|
90224
|
+
const mintedBySession = (nodeId) => store.getNode(nodeId)?.attrs["sources"]?.[0] === sessionId;
|
|
90225
|
+
const held = heldAsks.record(
|
|
90226
|
+
sessionId,
|
|
90227
|
+
{
|
|
90228
|
+
canOpen,
|
|
90229
|
+
leaned: plan.corroborations.filter((c) => c.via === "lean" && !mintedBySession(c.nodeId)).map(({ nodeId, witnessKey }) => ({ nodeId, witnessKey })),
|
|
90230
|
+
// A subagent's verdict is its own, not an answer to the parent's question.
|
|
90231
|
+
verdicts: subagentTurn ? [] : [
|
|
90232
|
+
...plan.corroborations.filter((c) => c.via === "confirm" || c.via === "fix").map((c) => ({ priorId: c.nodeId, kind: c.via, witnessKey: c.witnessKey })),
|
|
90233
|
+
...plan.refutes.map((r) => ({ priorId: r.nodeId, kind: "refute" })),
|
|
90234
|
+
...plan.solutionLinks.flatMap((sl) => sl.targetIds.map((id) => ({ priorId: id, kind: "link" })))
|
|
90235
|
+
]
|
|
90236
|
+
},
|
|
90237
|
+
t
|
|
90238
|
+
);
|
|
90239
|
+
if (held.withheld.size > 0) {
|
|
90240
|
+
withheldLeanIds = plan.corroborations.filter((c) => c.via === "lean" && held.withheld.has(c.witnessKey)).map((c) => c.nodeId);
|
|
90241
|
+
plan.corroborations = plan.corroborations.filter((c) => !held.withheld.has(c.witnessKey));
|
|
90242
|
+
}
|
|
90243
|
+
const linked2 = releaseHeld(held.release, t);
|
|
90244
|
+
confirmsStamped += linked2.stamped;
|
|
90245
|
+
fixHeldConfirmed += linked2.fixHeld;
|
|
90246
|
+
heldAnswered += held.answeredShown.length;
|
|
90247
|
+
for (const id of held.opened) {
|
|
90248
|
+
const n = store.getNode(id);
|
|
90249
|
+
if (n) store.updateNode(id, { attrs: { ...n.attrs, heldAskedAt: t }, lastUpdatedAt: t });
|
|
90250
|
+
heldAsked++;
|
|
90251
|
+
}
|
|
90252
|
+
if (held.changed) saveHeldAsks(heldAsksPath(paths.configDir), heldAsks);
|
|
90253
|
+
}
|
|
89791
90254
|
const refuteResult = applyLocalRefutations(store, plan.refutes, t);
|
|
89792
90255
|
refutesStamped += refuteResult.stamped;
|
|
89793
90256
|
if (sessions.originOf(sessionId) === void 0) {
|
|
@@ -89847,7 +90310,7 @@ function createWorkspaceEngine(opts) {
|
|
|
89847
90310
|
let anchorReadFailed = false;
|
|
89848
90311
|
if (p.location) {
|
|
89849
90312
|
try {
|
|
89850
|
-
fileText =
|
|
90313
|
+
fileText = readFileSync36(join40(opts.workspaceRoot, p.location.path), "utf8");
|
|
89851
90314
|
} catch {
|
|
89852
90315
|
anchorReadFailed = true;
|
|
89853
90316
|
}
|
|
@@ -90010,10 +90473,10 @@ function createWorkspaceEngine(opts) {
|
|
|
90010
90473
|
let enclosing = {};
|
|
90011
90474
|
if (p.location?.line !== void 0) {
|
|
90012
90475
|
try {
|
|
90013
|
-
const headSha = readGitRefState(
|
|
90476
|
+
const headSha = readGitRefState(join40(opts.workspaceRoot, ".git")).sha ?? void 0;
|
|
90014
90477
|
enclosing = {
|
|
90015
90478
|
line: p.location.line,
|
|
90016
|
-
fileText:
|
|
90479
|
+
fileText: readFileSync36(join40(opts.workspaceRoot, anchorPath), "utf8"),
|
|
90017
90480
|
...headSha ? { headSha } : {}
|
|
90018
90481
|
};
|
|
90019
90482
|
} catch {
|
|
@@ -90302,6 +90765,7 @@ function createWorkspaceEngine(opts) {
|
|
|
90302
90765
|
/* @__PURE__ */ new Set([
|
|
90303
90766
|
...plan.solutionLinks.flatMap((sl) => sl.targetIds),
|
|
90304
90767
|
...plan.corroborations.map((c) => c.nodeId),
|
|
90768
|
+
...withheldLeanIds,
|
|
90305
90769
|
...plan.refutes.map((r) => r.nodeId)
|
|
90306
90770
|
])
|
|
90307
90771
|
);
|
|
@@ -90515,6 +90979,8 @@ function createWorkspaceEngine(opts) {
|
|
|
90515
90979
|
confirmsStamped,
|
|
90516
90980
|
supersessionAsked,
|
|
90517
90981
|
structureLinksMinted,
|
|
90982
|
+
heldAsked,
|
|
90983
|
+
heldAnswered,
|
|
90518
90984
|
// RG-recognize tier A: resolved problems the door saw recur this pass.
|
|
90519
90985
|
recurrencesMarked,
|
|
90520
90986
|
// RG-reopen: closes flipped open on the two-touch evidence bar.
|
|
@@ -90888,7 +91354,7 @@ B: ${b}`,
|
|
|
90888
91354
|
try {
|
|
90889
91355
|
const inputs = emitInputsFromManifest(paths.configDir, paths.skillsManifest);
|
|
90890
91356
|
emitAndProjectSkills(opts.workspaceRoot, inputs);
|
|
90891
|
-
writePrimingHandles(
|
|
91357
|
+
writePrimingHandles(join40(paths.configDir, "priming-handles.json"), skillHandleNodes(inputs));
|
|
90892
91358
|
} catch (err2) {
|
|
90893
91359
|
console.warn("[skills] agent-skills projection failed (non-fatal):", err2 instanceof Error ? err2.message : err2);
|
|
90894
91360
|
}
|
|
@@ -91259,7 +91725,7 @@ B: ${b}`,
|
|
|
91259
91725
|
console.log(
|
|
91260
91726
|
"[errata] sync skipped \u2014 cloud sync consent is off (enable with `errata consent sync on`)"
|
|
91261
91727
|
);
|
|
91262
|
-
const pending =
|
|
91728
|
+
const pending = existsSync30(paths.outbox) ? readdirSync11(paths.outbox).filter((f) => f.endsWith(".json")).length : 0;
|
|
91263
91729
|
return { uploaded: 0, failed: 0, remaining: pending };
|
|
91264
91730
|
}
|
|
91265
91731
|
if (!shipsFromWorkspace(opts.workspaceRoot)) {
|
|
@@ -91271,7 +91737,7 @@ B: ${b}`,
|
|
|
91271
91737
|
console.log(
|
|
91272
91738
|
"[errata] sync held \u2014 this repo is already on errata in another workspace; run `errata link` to join it or create your own project"
|
|
91273
91739
|
);
|
|
91274
|
-
const pending =
|
|
91740
|
+
const pending = existsSync30(paths.outbox) ? readdirSync11(paths.outbox).filter((f) => f.endsWith(".json")).length : 0;
|
|
91275
91741
|
return { uploaded: 0, failed: 0, remaining: pending };
|
|
91276
91742
|
}
|
|
91277
91743
|
try {
|
|
@@ -91399,7 +91865,7 @@ async function startDaemon(opts) {
|
|
|
91399
91865
|
reviewUrl: () => webUiUrl + "/review"
|
|
91400
91866
|
});
|
|
91401
91867
|
const writeLockFile = (url2) => {
|
|
91402
|
-
|
|
91868
|
+
writeFileSync26(
|
|
91403
91869
|
engine.paths.daemonLock,
|
|
91404
91870
|
daemonLockPayload({ pid: process.pid, webUiUrl: url2, processStartedAt, version: DAEMON_VERSION }),
|
|
91405
91871
|
"utf8"
|
|
@@ -91451,7 +91917,7 @@ async function startDaemon(opts) {
|
|
|
91451
91917
|
);
|
|
91452
91918
|
await engine.stop();
|
|
91453
91919
|
try {
|
|
91454
|
-
if (
|
|
91920
|
+
if (existsSync31(engine.paths.daemonLock)) {
|
|
91455
91921
|
}
|
|
91456
91922
|
} catch {
|
|
91457
91923
|
}
|
|
@@ -91652,8 +92118,8 @@ async function linkRegisteredWorkspaces(cfg, loggedInProfile = cfg.activeInstall
|
|
|
91652
92118
|
}
|
|
91653
92119
|
|
|
91654
92120
|
// src/edge-park.ts
|
|
91655
|
-
import { readFileSync as
|
|
91656
|
-
import { dirname as
|
|
92121
|
+
import { readFileSync as readFileSync37, renameSync as renameSync7, writeFileSync as writeFileSync27 } from "node:fs";
|
|
92122
|
+
import { dirname as dirname17, join as join41 } from "node:path";
|
|
91657
92123
|
var EDGE_PARK_CAP = 2e3;
|
|
91658
92124
|
var EDGE_PARK_TTL_MS = 14 * 24 * 60 * 60 * 1e3;
|
|
91659
92125
|
var EDGE_PARK_MAX_ATTEMPTS = 6;
|
|
@@ -91668,12 +92134,12 @@ function wireEdgeKey(from, type, to) {
|
|
|
91668
92134
|
return JSON.stringify([from, type, to]);
|
|
91669
92135
|
}
|
|
91670
92136
|
function edgeParkPath(workspaceConfigDir, destinationKey) {
|
|
91671
|
-
return
|
|
92137
|
+
return join41(workspaceConfigDir, `edge-park.${destinationKey.slice(0, 16)}.json`);
|
|
91672
92138
|
}
|
|
91673
92139
|
function loadEdgePark(path3) {
|
|
91674
92140
|
let raw2;
|
|
91675
92141
|
try {
|
|
91676
|
-
raw2 = JSON.parse(
|
|
92142
|
+
raw2 = JSON.parse(readFileSync37(path3, "utf8"));
|
|
91677
92143
|
} catch {
|
|
91678
92144
|
return [];
|
|
91679
92145
|
}
|
|
@@ -91684,9 +92150,9 @@ function loadEdgePark(path3) {
|
|
|
91684
92150
|
}
|
|
91685
92151
|
function saveEdgePark(path3, queue) {
|
|
91686
92152
|
try {
|
|
91687
|
-
const tmp =
|
|
91688
|
-
|
|
91689
|
-
|
|
92153
|
+
const tmp = join41(dirname17(path3), `.${Date.now()}.edge-park.tmp`);
|
|
92154
|
+
writeFileSync27(tmp, JSON.stringify(queue), "utf8");
|
|
92155
|
+
renameSync7(tmp, path3);
|
|
91690
92156
|
} catch {
|
|
91691
92157
|
}
|
|
91692
92158
|
}
|
|
@@ -92007,8 +92473,8 @@ function invalidateInstanceReceipt(current, destination, failedId, mirrorLegacy)
|
|
|
92007
92473
|
// src/multi.ts
|
|
92008
92474
|
init_dist();
|
|
92009
92475
|
init_src5();
|
|
92010
|
-
import { existsSync as
|
|
92011
|
-
import { basename as basename10, dirname as
|
|
92476
|
+
import { existsSync as existsSync36, readFileSync as readFileSync43, writeFileSync as writeFileSync30 } from "node:fs";
|
|
92477
|
+
import { basename as basename10, dirname as dirname20, join as join50, resolve as pathResolve } from "node:path";
|
|
92012
92478
|
|
|
92013
92479
|
// src/principle-sync.ts
|
|
92014
92480
|
init_src5();
|
|
@@ -92036,8 +92502,8 @@ init_reconcile();
|
|
|
92036
92502
|
|
|
92037
92503
|
// src/lockfile-auto.ts
|
|
92038
92504
|
init_src();
|
|
92039
|
-
import { existsSync as
|
|
92040
|
-
import { join as
|
|
92505
|
+
import { existsSync as existsSync32, readFileSync as readFileSync38 } from "node:fs";
|
|
92506
|
+
import { join as join42 } from "node:path";
|
|
92041
92507
|
|
|
92042
92508
|
// src/package-index.ts
|
|
92043
92509
|
init_src();
|
|
@@ -92210,11 +92676,11 @@ function runLockfilePass(opts) {
|
|
|
92210
92676
|
{ file: "package-lock.json", parse: parsePackageLockJson }
|
|
92211
92677
|
];
|
|
92212
92678
|
for (const c of candidates) {
|
|
92213
|
-
const p =
|
|
92214
|
-
if (!
|
|
92679
|
+
const p = join42(opts.root, c.file);
|
|
92680
|
+
if (!existsSync32(p)) continue;
|
|
92215
92681
|
let sbom;
|
|
92216
92682
|
try {
|
|
92217
|
-
sbom = c.parse(
|
|
92683
|
+
sbom = c.parse(readFileSync38(p, "utf8"));
|
|
92218
92684
|
} catch {
|
|
92219
92685
|
continue;
|
|
92220
92686
|
}
|
|
@@ -92234,7 +92700,7 @@ init_src10();
|
|
|
92234
92700
|
init_src();
|
|
92235
92701
|
|
|
92236
92702
|
// src/contribution-ready.ts
|
|
92237
|
-
|
|
92703
|
+
init_src4();
|
|
92238
92704
|
function cosine4(a, b) {
|
|
92239
92705
|
if (a.length === 0 || a.length !== b.length) return 0;
|
|
92240
92706
|
let dot = 0;
|
|
@@ -92248,7 +92714,9 @@ function cosine4(a, b) {
|
|
|
92248
92714
|
return na === 0 || nb === 0 ? 0 : dot / (Math.sqrt(na) * Math.sqrt(nb));
|
|
92249
92715
|
}
|
|
92250
92716
|
function noveltyAgainst(node2, neighbors, opts = {}) {
|
|
92251
|
-
const
|
|
92717
|
+
const versionOf = (n) => String(n.attrs?.["embeddingVersion"] ?? "hash-v1");
|
|
92718
|
+
const version3 = versionOf(node2);
|
|
92719
|
+
const floor = opts.dedupCosine ?? cosineBandsFor(version3).dedup;
|
|
92252
92720
|
const emb = node2.embedding ?? [];
|
|
92253
92721
|
if (emb.length === 0) {
|
|
92254
92722
|
return { ready: true, surprise: 1, topCosine: 0, reason: "no-embedding (fidelity-first)" };
|
|
@@ -92257,7 +92725,7 @@ function noveltyAgainst(node2, neighbors, opts = {}) {
|
|
|
92257
92725
|
for (const other of neighbors) {
|
|
92258
92726
|
if (other.id === node2.id) continue;
|
|
92259
92727
|
const oe = other.embedding ?? [];
|
|
92260
|
-
if (oe.length !== emb.length) continue;
|
|
92728
|
+
if (oe.length !== emb.length || versionOf(other) !== version3) continue;
|
|
92261
92729
|
const c = cosine4(emb, oe);
|
|
92262
92730
|
if (c > topCosine) topCosine = c;
|
|
92263
92731
|
}
|
|
@@ -92275,8 +92743,8 @@ init_profile2();
|
|
|
92275
92743
|
init_session_registry();
|
|
92276
92744
|
|
|
92277
92745
|
// src/public-symbols.ts
|
|
92278
|
-
import { readFileSync as
|
|
92279
|
-
import { join as
|
|
92746
|
+
import { readFileSync as readFileSync39, readdirSync as readdirSync12, existsSync as existsSync33 } from "node:fs";
|
|
92747
|
+
import { join as join43 } from "node:path";
|
|
92280
92748
|
var HEAD_BYTES = 8 * 1024;
|
|
92281
92749
|
var INDEX_TTL_MS = 10 * 60 * 1e3;
|
|
92282
92750
|
var MIN_SYMBOL_LEN = 4;
|
|
@@ -92309,20 +92777,20 @@ function bindingNames(clause) {
|
|
|
92309
92777
|
function internalPackageNames(workspaceRoot) {
|
|
92310
92778
|
const names = /* @__PURE__ */ new Set();
|
|
92311
92779
|
const tryRead = (dir) => {
|
|
92312
|
-
const pj =
|
|
92313
|
-
if (!
|
|
92780
|
+
const pj = join43(dir, "package.json");
|
|
92781
|
+
if (!existsSync33(pj)) return;
|
|
92314
92782
|
try {
|
|
92315
|
-
const name2 = JSON.parse(
|
|
92783
|
+
const name2 = JSON.parse(readFileSync39(pj, "utf8")).name;
|
|
92316
92784
|
if (typeof name2 === "string" && name2.length > 0) names.add(name2);
|
|
92317
92785
|
} catch {
|
|
92318
92786
|
}
|
|
92319
92787
|
};
|
|
92320
92788
|
tryRead(workspaceRoot);
|
|
92321
92789
|
for (const group of ["packages", "apps"]) {
|
|
92322
|
-
const groupDir =
|
|
92323
|
-
if (!
|
|
92790
|
+
const groupDir = join43(workspaceRoot, group);
|
|
92791
|
+
if (!existsSync33(groupDir)) continue;
|
|
92324
92792
|
try {
|
|
92325
|
-
for (const entry of readdirSync12(groupDir)) tryRead(
|
|
92793
|
+
for (const entry of readdirSync12(groupDir)) tryRead(join43(groupDir, entry));
|
|
92326
92794
|
} catch {
|
|
92327
92795
|
}
|
|
92328
92796
|
}
|
|
@@ -92341,7 +92809,7 @@ function publicSymbolIndex(store, workspaceRoot, deps = {}) {
|
|
|
92341
92809
|
}
|
|
92342
92810
|
const readHead = deps.readHead ?? ((absPath) => {
|
|
92343
92811
|
try {
|
|
92344
|
-
return
|
|
92812
|
+
return readFileSync39(absPath, "utf8").slice(0, HEAD_BYTES);
|
|
92345
92813
|
} catch {
|
|
92346
92814
|
return "";
|
|
92347
92815
|
}
|
|
@@ -92361,7 +92829,7 @@ function publicSymbolIndex(store, workspaceRoot, deps = {}) {
|
|
|
92361
92829
|
}
|
|
92362
92830
|
const symbols = /* @__PURE__ */ new Set();
|
|
92363
92831
|
for (const rel of files) {
|
|
92364
|
-
const head2 = readHead(
|
|
92832
|
+
const head2 = readHead(join43(workspaceRoot, rel));
|
|
92365
92833
|
if (!head2) continue;
|
|
92366
92834
|
for (const re of [NAMED_IMPORT_RE, REQUIRE_RE]) {
|
|
92367
92835
|
re.lastIndex = 0;
|
|
@@ -93392,7 +93860,7 @@ init_config();
|
|
|
93392
93860
|
|
|
93393
93861
|
// src/update.ts
|
|
93394
93862
|
import { spawn as spawn2 } from "node:child_process";
|
|
93395
|
-
import { isAbsolute as isAbsolute6, join as
|
|
93863
|
+
import { isAbsolute as isAbsolute6, join as join44 } from "node:path";
|
|
93396
93864
|
var PACKAGE_NAME = "@inerrata-corporation/errata";
|
|
93397
93865
|
function parse3(v) {
|
|
93398
93866
|
const m = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z][0-9A-Za-z.-]*))?/.exec(v.trim());
|
|
@@ -93541,7 +94009,7 @@ async function runInstalledHookRefresh() {
|
|
|
93541
94009
|
let worst = 0;
|
|
93542
94010
|
for (const harness of ["codex", "claude"]) {
|
|
93543
94011
|
const code = await new Promise((resolve11) => {
|
|
93544
|
-
const child = spawn2(process.execPath, [
|
|
94012
|
+
const child = spawn2(process.execPath, [join44(root, PACKAGE_NAME, "errata.mjs"), "install-hooks", harness, "--refresh-existing"], {
|
|
93545
94013
|
windowsHide: true,
|
|
93546
94014
|
stdio: "inherit",
|
|
93547
94015
|
timeout: 3e4
|
|
@@ -93690,12 +94158,12 @@ function landCloudEdge(store, e, from, to) {
|
|
|
93690
94158
|
}
|
|
93691
94159
|
|
|
93692
94160
|
// src/causal-edge-queue.ts
|
|
93693
|
-
import { readFileSync as
|
|
93694
|
-
import { dirname as
|
|
94161
|
+
import { readFileSync as readFileSync40, renameSync as renameSync8, writeFileSync as writeFileSync28 } from "node:fs";
|
|
94162
|
+
import { dirname as dirname18, join as join45 } from "node:path";
|
|
93695
94163
|
var CAUSAL_EDGE_QUEUE_CAP = 5e3;
|
|
93696
94164
|
var CAUSAL_EDGE_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
93697
94165
|
function causalEdgeQueuePath(workspaceConfigDir) {
|
|
93698
|
-
return
|
|
94166
|
+
return join45(workspaceConfigDir, "causal-edge-queue.json");
|
|
93699
94167
|
}
|
|
93700
94168
|
function parkedEdgeKey(e) {
|
|
93701
94169
|
return `${e.from}|${e.type}|${e.to}`;
|
|
@@ -93703,7 +94171,7 @@ function parkedEdgeKey(e) {
|
|
|
93703
94171
|
function loadCausalEdgeQueue(path3) {
|
|
93704
94172
|
let raw2;
|
|
93705
94173
|
try {
|
|
93706
|
-
raw2 = JSON.parse(
|
|
94174
|
+
raw2 = JSON.parse(readFileSync40(path3, "utf8"));
|
|
93707
94175
|
} catch {
|
|
93708
94176
|
return [];
|
|
93709
94177
|
}
|
|
@@ -93714,9 +94182,9 @@ function loadCausalEdgeQueue(path3) {
|
|
|
93714
94182
|
}
|
|
93715
94183
|
function saveCausalEdgeQueue(path3, queue) {
|
|
93716
94184
|
try {
|
|
93717
|
-
const tmp =
|
|
93718
|
-
|
|
93719
|
-
|
|
94185
|
+
const tmp = join45(dirname18(path3), `.${Date.now()}.causal-edge-queue.tmp`);
|
|
94186
|
+
writeFileSync28(tmp, JSON.stringify(queue), "utf8");
|
|
94187
|
+
renameSync8(tmp, path3);
|
|
93720
94188
|
} catch {
|
|
93721
94189
|
}
|
|
93722
94190
|
}
|
|
@@ -94146,9 +94614,9 @@ init_src11();
|
|
|
94146
94614
|
init_src();
|
|
94147
94615
|
import { execFile as execFile6 } from "node:child_process";
|
|
94148
94616
|
import { promisify as promisify4 } from "node:util";
|
|
94149
|
-
import { extname as extname3, join as
|
|
94617
|
+
import { extname as extname3, join as join46 } from "node:path";
|
|
94150
94618
|
import { createHash as createHash19 } from "node:crypto";
|
|
94151
|
-
import { readFileSync as
|
|
94619
|
+
import { readFileSync as readFileSync41 } from "node:fs";
|
|
94152
94620
|
|
|
94153
94621
|
// src/history-dependency-snapshot.ts
|
|
94154
94622
|
init_src();
|
|
@@ -94259,9 +94727,9 @@ var carryRefused = /* @__PURE__ */ new Set();
|
|
|
94259
94727
|
var carryFailures = /* @__PURE__ */ new Map();
|
|
94260
94728
|
var CARRY_ATTEMPTS = 3;
|
|
94261
94729
|
var Bounded = class extends Map {
|
|
94262
|
-
constructor(
|
|
94730
|
+
constructor(cap2) {
|
|
94263
94731
|
super();
|
|
94264
|
-
this.cap =
|
|
94732
|
+
this.cap = cap2;
|
|
94265
94733
|
}
|
|
94266
94734
|
set(key, value) {
|
|
94267
94735
|
if (!this.has(key) && this.size >= this.cap) this.delete(this.keys().next().value);
|
|
@@ -94271,7 +94739,7 @@ var Bounded = class extends Map {
|
|
|
94271
94739
|
var DEFAULT_GIT = {};
|
|
94272
94740
|
function readFileSafe(path3) {
|
|
94273
94741
|
try {
|
|
94274
|
-
return
|
|
94742
|
+
return readFileSync41(path3, "utf8");
|
|
94275
94743
|
} catch {
|
|
94276
94744
|
return "";
|
|
94277
94745
|
}
|
|
@@ -94325,7 +94793,7 @@ async function syncHistoryRevisionPage(opts, resolve11) {
|
|
|
94325
94793
|
const projectId = profile.projectId;
|
|
94326
94794
|
const git3 = opts.git ?? (async (args2) => (await exec2("git", ["-C", root, ...args2], { windowsHide: true, maxBuffer: 8 * 1024 * 1024 })).stdout);
|
|
94327
94795
|
const caches = cachesFor(opts.git ?? DEFAULT_GIT);
|
|
94328
|
-
const ignoreKey = createHash19("sha256").update(JSON.stringify(profile.ignoreExtra ?? [])).update(readFileSafe(
|
|
94796
|
+
const ignoreKey = createHash19("sha256").update(JSON.stringify(profile.ignoreExtra ?? [])).update(readFileSafe(join46(root, ".errataignore"))).digest("hex").slice(0, 16);
|
|
94329
94797
|
const atCommit = (await git3(["rev-parse", "--verify", "HEAD"])).trim();
|
|
94330
94798
|
if (!/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(atCommit)) throw new Error("history revision is not a full Git object id");
|
|
94331
94799
|
const oldCursor = profile.historyRevisionCursor;
|
|
@@ -94645,8 +95113,8 @@ ${await git3(["rev-list", "--parents", "-1", from])}`.split("\n").map((row) => r
|
|
|
94645
95113
|
init_src7();
|
|
94646
95114
|
init_src();
|
|
94647
95115
|
import { execFile as execFile7 } from "node:child_process";
|
|
94648
|
-
import { readFileSync as
|
|
94649
|
-
import { join as
|
|
95116
|
+
import { readFileSync as readFileSync42 } from "node:fs";
|
|
95117
|
+
import { join as join47 } from "node:path";
|
|
94650
95118
|
import { promisify as promisify5 } from "node:util";
|
|
94651
95119
|
|
|
94652
95120
|
// src/history-walk.ts
|
|
@@ -95205,7 +95673,7 @@ async function defaultGit(root, args2) {
|
|
|
95205
95673
|
function readIgnoreLines(root, profile) {
|
|
95206
95674
|
let lines = [];
|
|
95207
95675
|
try {
|
|
95208
|
-
lines =
|
|
95676
|
+
lines = readFileSync42(join47(root, ".errataignore"), "utf8").split("\n");
|
|
95209
95677
|
} catch {
|
|
95210
95678
|
}
|
|
95211
95679
|
return [...lines, ...profile.ignoreExtra ?? []].map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
@@ -95386,7 +95854,7 @@ async function walk10(root, input, client, opts, readBlob) {
|
|
|
95386
95854
|
const settle = (p) => p.then((res) => ({ res }), (err2) => ({ err: err2 }));
|
|
95387
95855
|
const prepared = /* @__PURE__ */ new Map();
|
|
95388
95856
|
const launched = /* @__PURE__ */ new Map();
|
|
95389
|
-
const
|
|
95857
|
+
const cap2 = opts.maxUnits;
|
|
95390
95858
|
const edgeParked = /* @__PURE__ */ new Set();
|
|
95391
95859
|
const parkedEarlier = new Set((profile.historyStage?.coverageGaps ?? []).filter((g) => g.reason === "edge-blocked" && !recoveryKeys.has(unitKey(g))).map(unitKey));
|
|
95392
95860
|
units.forEach((u, j) => {
|
|
@@ -95479,7 +95947,7 @@ async function walk10(root, input, client, opts, readBlob) {
|
|
|
95479
95947
|
if (!doorOrders || lookahead === 0) return;
|
|
95480
95948
|
let ahead = 0;
|
|
95481
95949
|
for (let j = k + 1; j < units.length && ahead < lookahead; j++) {
|
|
95482
|
-
if (
|
|
95950
|
+
if (cap2 !== void 0 && processed + (j - k) >= cap2) break;
|
|
95483
95951
|
if (units[j].skip || edgeParked.has(j)) continue;
|
|
95484
95952
|
ahead += 1;
|
|
95485
95953
|
await launch(j);
|
|
@@ -95487,7 +95955,7 @@ async function walk10(root, input, client, opts, readBlob) {
|
|
|
95487
95955
|
};
|
|
95488
95956
|
for (let k = 0; k < units.length; k++) {
|
|
95489
95957
|
const u = units[k];
|
|
95490
|
-
if (
|
|
95958
|
+
if (cap2 !== void 0 && processed >= cap2) break;
|
|
95491
95959
|
const label = `${u.sha.slice(0, 12)}${u.subIndex ? `/${u.subIndex}` : ""}`;
|
|
95492
95960
|
const recovering = recoveryKeys.has(unitKey(u));
|
|
95493
95961
|
const walkIncrement = recovering ? 0 : 1;
|
|
@@ -95785,8 +96253,8 @@ async function startHistoryStage(root, input, client, walk11 = {}) {
|
|
|
95785
96253
|
init_cloud_auth();
|
|
95786
96254
|
import { createHash as createHash20 } from "node:crypto";
|
|
95787
96255
|
import { execFileSync as execFileSync7 } from "node:child_process";
|
|
95788
|
-
import { existsSync as
|
|
95789
|
-
import { join as
|
|
96256
|
+
import { existsSync as existsSync34, writeFileSync as writeFileSync29 } from "node:fs";
|
|
96257
|
+
import { join as join48 } from "node:path";
|
|
95790
96258
|
|
|
95791
96259
|
// src/device-poll.ts
|
|
95792
96260
|
var THROTTLED_POLL_MIN_WAIT_MS = 11e3;
|
|
@@ -96245,9 +96713,9 @@ function applyLinkDecision(root, profile, config2, decision, now = Date.now) {
|
|
|
96245
96713
|
delete nextProfile.projectLinkHold;
|
|
96246
96714
|
let wroteIgnore = false;
|
|
96247
96715
|
if (decision.writeIgnoreStarter !== false) {
|
|
96248
|
-
const target =
|
|
96249
|
-
if (!
|
|
96250
|
-
|
|
96716
|
+
const target = join48(root, ".errataignore");
|
|
96717
|
+
if (!existsSync34(target)) {
|
|
96718
|
+
writeFileSync29(target, IGNORE_STARTER, "utf8");
|
|
96251
96719
|
wroteIgnore = true;
|
|
96252
96720
|
}
|
|
96253
96721
|
}
|
|
@@ -96260,13 +96728,13 @@ init_registry();
|
|
|
96260
96728
|
|
|
96261
96729
|
// src/adopt.ts
|
|
96262
96730
|
init_git_remote();
|
|
96263
|
-
import { existsSync as
|
|
96264
|
-
import { dirname as
|
|
96731
|
+
import { existsSync as existsSync35 } from "node:fs";
|
|
96732
|
+
import { dirname as dirname19, join as join49 } from "node:path";
|
|
96265
96733
|
function findGitRoot(absPath) {
|
|
96266
96734
|
let dir = absPath;
|
|
96267
96735
|
for (let depth = 0; depth < 64; depth++) {
|
|
96268
|
-
if (
|
|
96269
|
-
const parent =
|
|
96736
|
+
if (existsSync35(join49(dir, ".git"))) return dir;
|
|
96737
|
+
const parent = dirname19(dir);
|
|
96270
96738
|
if (parent === dir) return null;
|
|
96271
96739
|
dir = parent;
|
|
96272
96740
|
}
|
|
@@ -96908,7 +97376,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
96908
97376
|
};
|
|
96909
97377
|
const sharedDbPath = sharedStorePath();
|
|
96910
97378
|
ensureParent(sharedDbPath);
|
|
96911
|
-
if (sharedDbPath !== ":memory:") excludeFromIndexing(
|
|
97379
|
+
if (sharedDbPath !== ":memory:") excludeFromIndexing(dirname20(sharedDbPath));
|
|
96912
97380
|
await prepareStore(sharedDbPath, process.cwd(), "shared");
|
|
96913
97381
|
const sharedStore = openGraphStore({ path: sharedDbPath });
|
|
96914
97382
|
const bundledRun = import.meta.url.endsWith(".mjs");
|
|
@@ -97052,7 +97520,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
97052
97520
|
held.push(...quarantined);
|
|
97053
97521
|
let ignoreFile = "";
|
|
97054
97522
|
try {
|
|
97055
|
-
ignoreFile =
|
|
97523
|
+
ignoreFile = readFileSync43(join50(r.root, ".errataignore"), "utf8");
|
|
97056
97524
|
} catch {
|
|
97057
97525
|
}
|
|
97058
97526
|
const retryInputs = JSON.stringify([
|
|
@@ -97120,7 +97588,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
97120
97588
|
const id = entry.id;
|
|
97121
97589
|
const castaliaPath = workspacePaths(entry.path).castalia;
|
|
97122
97590
|
ensureParent(castaliaPath);
|
|
97123
|
-
excludeFromIndexing(
|
|
97591
|
+
excludeFromIndexing(dirname20(castaliaPath));
|
|
97124
97592
|
await prepareStore(castaliaPath, entry.path, id);
|
|
97125
97593
|
if (stopping) throw new Error("daemon stopping");
|
|
97126
97594
|
const wsIdentity = identityFor(entry);
|
|
@@ -97257,7 +97725,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
97257
97725
|
records.push(rec);
|
|
97258
97726
|
void ambientLinkAll();
|
|
97259
97727
|
try {
|
|
97260
|
-
|
|
97728
|
+
writeFileSync30(
|
|
97261
97729
|
rec.engine.paths.daemonLock,
|
|
97262
97730
|
daemonLockPayload({
|
|
97263
97731
|
pid: process.pid,
|
|
@@ -97633,10 +98101,10 @@ async function startMultiDaemon(opts = {}) {
|
|
|
97633
98101
|
};
|
|
97634
98102
|
const MISFILED_SWEEP_DELAY_MS = 2 * 6e4;
|
|
97635
98103
|
const sweepMisfiled = async (rec) => {
|
|
97636
|
-
const checkedPath =
|
|
98104
|
+
const checkedPath = join50(workspacePaths(rec.root).configDir, "rehome-checked.json");
|
|
97637
98105
|
let checked;
|
|
97638
98106
|
try {
|
|
97639
|
-
checked = new Set(JSON.parse(
|
|
98107
|
+
checked = new Set(JSON.parse(readFileSync43(checkedPath, "utf8")));
|
|
97640
98108
|
} catch {
|
|
97641
98109
|
checked = /* @__PURE__ */ new Set();
|
|
97642
98110
|
}
|
|
@@ -97652,7 +98120,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
97652
98120
|
if (to) await rehomeMisfiled(sid, rec, to, "its captures were raised in its files");
|
|
97653
98121
|
await new Promise((r) => setImmediate(r));
|
|
97654
98122
|
}
|
|
97655
|
-
if (changed)
|
|
98123
|
+
if (changed) writeFileSync30(checkedPath, JSON.stringify([...checked]), "utf8");
|
|
97656
98124
|
};
|
|
97657
98125
|
afterAttach = (rec) => {
|
|
97658
98126
|
const t = setTimeout(() => {
|
|
@@ -97755,7 +98223,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
97755
98223
|
lastActiveAt = Math.max(lastActiveAt, rec.engine.lastActivityAt());
|
|
97756
98224
|
} catch {
|
|
97757
98225
|
}
|
|
97758
|
-
const reason = retireDecision({ exists:
|
|
98226
|
+
const reason = retireDecision({ exists: existsSync36(rec.root), lastActiveAt, now });
|
|
97759
98227
|
if (reason) void retireWorkspace(rec, reason);
|
|
97760
98228
|
}
|
|
97761
98229
|
};
|
|
@@ -97828,7 +98296,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
97828
98296
|
baseUrl = `http://127.0.0.1:${port}`;
|
|
97829
98297
|
try {
|
|
97830
98298
|
ensureDir(globalDir());
|
|
97831
|
-
|
|
98299
|
+
writeFileSync30(
|
|
97832
98300
|
lockPath,
|
|
97833
98301
|
daemonLockPayload({ pid: process.pid, webUiUrl: baseUrl, processStartedAt: PROCESS_STARTED_AT, entry: SELF_ENTRY, version: DAEMON_VERSION }),
|
|
97834
98302
|
"utf8"
|
|
@@ -97837,7 +98305,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
97837
98305
|
}
|
|
97838
98306
|
for (const r of records) {
|
|
97839
98307
|
try {
|
|
97840
|
-
|
|
98308
|
+
writeFileSync30(
|
|
97841
98309
|
r.engine.paths.daemonLock,
|
|
97842
98310
|
daemonLockPayload({
|
|
97843
98311
|
pid: process.pid,
|
|
@@ -99008,6 +99476,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
99008
99476
|
|
|
99009
99477
|
// src/cli.ts
|
|
99010
99478
|
init_src5();
|
|
99479
|
+
init_src4();
|
|
99011
99480
|
init_profile2();
|
|
99012
99481
|
init_git_remote();
|
|
99013
99482
|
init_config();
|
|
@@ -99383,7 +99852,7 @@ import { spawnSync as spawnSync2 } from "node:child_process";
|
|
|
99383
99852
|
|
|
99384
99853
|
// src/codex-runtime.ts
|
|
99385
99854
|
import { readdirSync as readdirSync13, statSync as statSync13 } from "node:fs";
|
|
99386
|
-
import { join as
|
|
99855
|
+
import { join as join51 } from "node:path";
|
|
99387
99856
|
function resolveCodexExecutable(options = {}) {
|
|
99388
99857
|
const platform = options.platform ?? process.platform;
|
|
99389
99858
|
const env2 = options.env ?? process.env;
|
|
@@ -99398,13 +99867,13 @@ function resolveCodexExecutable(options = {}) {
|
|
|
99398
99867
|
};
|
|
99399
99868
|
for (const dir of (env2["PATH"] ?? env2["Path"] ?? "").split(";")) {
|
|
99400
99869
|
if (!dir.trim()) continue;
|
|
99401
|
-
const path3 =
|
|
99870
|
+
const path3 = join51(dir.trim().replace(/^"|"$/g, ""), "codex.exe");
|
|
99402
99871
|
if (fileTime(path3) !== null) return path3;
|
|
99403
99872
|
}
|
|
99404
99873
|
if (!env2["LOCALAPPDATA"]) return "codex";
|
|
99405
|
-
const root =
|
|
99874
|
+
const root = join51(env2["LOCALAPPDATA"], "OpenAI", "Codex", "bin");
|
|
99406
99875
|
try {
|
|
99407
|
-
const candidates = readdirSync13(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) =>
|
|
99876
|
+
const candidates = readdirSync13(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join51(root, entry.name, "codex.exe")).map((path3) => ({ path: path3, mtime: fileTime(path3) })).filter((candidate) => candidate.mtime !== null).sort((a, b) => b.mtime - a.mtime || a.path.localeCompare(b.path));
|
|
99408
99877
|
return candidates[0]?.path ?? "codex";
|
|
99409
99878
|
} catch {
|
|
99410
99879
|
return "codex";
|
|
@@ -99543,14 +100012,14 @@ async function diagnoseInstallation(cfg, dependencies) {
|
|
|
99543
100012
|
}
|
|
99544
100013
|
|
|
99545
100014
|
// src/credential-scan.ts
|
|
99546
|
-
import { readFileSync as
|
|
100015
|
+
import { readFileSync as readFileSync45, statSync as statSync14 } from "node:fs";
|
|
99547
100016
|
import { homedir as homedir8 } from "node:os";
|
|
99548
|
-
import { join as
|
|
100017
|
+
import { join as join53 } from "node:path";
|
|
99549
100018
|
|
|
99550
100019
|
// src/claude-statusline.ts
|
|
99551
|
-
import { existsSync as
|
|
100020
|
+
import { existsSync as existsSync37, mkdirSync as mkdirSync9, readFileSync as readFileSync44, writeFileSync as writeFileSync31 } from "node:fs";
|
|
99552
100021
|
import { homedir as homedir7 } from "node:os";
|
|
99553
|
-
import { dirname as
|
|
100022
|
+
import { dirname as dirname21, join as join52 } from "node:path";
|
|
99554
100023
|
var STATUSLINE_RELAY_SOURCE = String.raw`// errata-managed: regenerated by errata init / install-hooks claude
|
|
99555
100024
|
import { readFileSync } from 'node:fs';
|
|
99556
100025
|
|
|
@@ -99598,8 +100067,8 @@ function isSameInstall(value, relay) {
|
|
|
99598
100067
|
return command.includes(relay.replace(/\\/g, "/").toLowerCase());
|
|
99599
100068
|
}
|
|
99600
100069
|
function userClaudeSettingsPath() {
|
|
99601
|
-
const base = process.env["CLAUDE_CONFIG_DIR"] ??
|
|
99602
|
-
return
|
|
100070
|
+
const base = process.env["CLAUDE_CONFIG_DIR"] ?? join52(homedir7(), ".claude");
|
|
100071
|
+
return join52(base, "settings.json");
|
|
99603
100072
|
}
|
|
99604
100073
|
function ensureUserStatusLine(opts) {
|
|
99605
100074
|
const env2 = opts.env ?? process.env;
|
|
@@ -99607,23 +100076,23 @@ function ensureUserStatusLine(opts) {
|
|
|
99607
100076
|
if (off2 === "0" || off2 === "off" || off2 === "false" || off2 === "no") return "disabled";
|
|
99608
100077
|
const settingsPath = opts.userSettingsPath ?? userClaudeSettingsPath();
|
|
99609
100078
|
let settings = {};
|
|
99610
|
-
if (
|
|
100079
|
+
if (existsSync37(settingsPath)) {
|
|
99611
100080
|
try {
|
|
99612
|
-
const parsed = JSON.parse(
|
|
100081
|
+
const parsed = JSON.parse(readFileSync44(settingsPath, "utf8"));
|
|
99613
100082
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return "unreadable";
|
|
99614
100083
|
settings = parsed;
|
|
99615
100084
|
} catch {
|
|
99616
100085
|
return "unreadable";
|
|
99617
100086
|
}
|
|
99618
100087
|
}
|
|
99619
|
-
const relay =
|
|
100088
|
+
const relay = join52(opts.relayDir, STATUSLINE_RELAY_FILE);
|
|
99620
100089
|
const keep = (value) => value !== void 0 && (!isErrataStatusLine(value) || !isSameInstall(value, relay));
|
|
99621
100090
|
const ownMain = keep(settings["statusLine"]);
|
|
99622
100091
|
const ownRows = keep(settings["subagentStatusLine"]);
|
|
99623
100092
|
if (ownMain && ownRows) return "kept-own";
|
|
99624
100093
|
mkdirSync9(opts.relayDir, { recursive: true });
|
|
99625
|
-
if (!
|
|
99626
|
-
|
|
100094
|
+
if (!existsSync37(relay) || readFileSync44(relay, "utf8") !== STATUSLINE_RELAY_SOURCE) {
|
|
100095
|
+
writeFileSync31(relay, STATUSLINE_RELAY_SOURCE, "utf8");
|
|
99627
100096
|
}
|
|
99628
100097
|
const nodePath = opts.nodePath ?? process.execPath;
|
|
99629
100098
|
const next = {
|
|
@@ -99634,8 +100103,8 @@ function ensureUserStatusLine(opts) {
|
|
|
99634
100103
|
return ownMain ? "kept-own" : "unchanged";
|
|
99635
100104
|
}
|
|
99636
100105
|
Object.assign(settings, next);
|
|
99637
|
-
mkdirSync9(
|
|
99638
|
-
|
|
100106
|
+
mkdirSync9(dirname21(settingsPath), { recursive: true });
|
|
100107
|
+
writeFileSync31(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
99639
100108
|
return "installed";
|
|
99640
100109
|
}
|
|
99641
100110
|
function describeStatusLineOutcome(outcome) {
|
|
@@ -99676,36 +100145,36 @@ function findCredentialLines(text) {
|
|
|
99676
100145
|
function harnessConfigPaths(root) {
|
|
99677
100146
|
const env2 = process.env;
|
|
99678
100147
|
const home = homedir8();
|
|
99679
|
-
const codexHome = env2["CODEX_HOME"] ||
|
|
99680
|
-
const geminiHome =
|
|
100148
|
+
const codexHome = env2["CODEX_HOME"] || join53(home, ".codex");
|
|
100149
|
+
const geminiHome = join53(env2["GEMINI_CLI_HOME"] ?? home, ".gemini");
|
|
99681
100150
|
return [
|
|
99682
100151
|
// Claude Code: user settings, `claude mcp add` (local/user scope), project.
|
|
99683
100152
|
userClaudeSettingsPath(),
|
|
99684
|
-
|
|
99685
|
-
|
|
99686
|
-
|
|
99687
|
-
|
|
100153
|
+
join53(env2["CLAUDE_CONFIG_DIR"] ?? home, ".claude.json"),
|
|
100154
|
+
join53(root, ".claude", "settings.json"),
|
|
100155
|
+
join53(root, ".claude", "settings.local.json"),
|
|
100156
|
+
join53(root, ".mcp.json"),
|
|
99688
100157
|
// Codex
|
|
99689
|
-
|
|
99690
|
-
|
|
100158
|
+
join53(codexHome, "config.toml"),
|
|
100159
|
+
join53(root, ".codex", "config.toml"),
|
|
99691
100160
|
// Gemini CLI
|
|
99692
|
-
|
|
99693
|
-
|
|
100161
|
+
join53(geminiHome, "settings.json"),
|
|
100162
|
+
join53(root, ".gemini", "settings.json"),
|
|
99694
100163
|
// Cursor
|
|
99695
|
-
|
|
99696
|
-
|
|
100164
|
+
join53(home, ".cursor", "mcp.json"),
|
|
100165
|
+
join53(root, ".cursor", "mcp.json"),
|
|
99697
100166
|
// VS Code (user profile mcp.json + workspace)
|
|
99698
|
-
|
|
99699
|
-
|
|
100167
|
+
join53(vscodeUserDir(home, env2), "mcp.json"),
|
|
100168
|
+
join53(root, ".vscode", "mcp.json"),
|
|
99700
100169
|
// OpenCode (XDG on every platform; the daemon's installer writes the project one)
|
|
99701
|
-
|
|
99702
|
-
|
|
100170
|
+
join53(env2["XDG_CONFIG_HOME"] ?? join53(home, ".config"), "opencode", "opencode.json"),
|
|
100171
|
+
join53(root, "opencode.json")
|
|
99703
100172
|
];
|
|
99704
100173
|
}
|
|
99705
100174
|
function vscodeUserDir(home, env2) {
|
|
99706
|
-
if (process.platform === "win32") return
|
|
99707
|
-
if (process.platform === "darwin") return
|
|
99708
|
-
return
|
|
100175
|
+
if (process.platform === "win32") return join53(env2["APPDATA"] ?? join53(home, "AppData", "Roaming"), "Code", "User");
|
|
100176
|
+
if (process.platform === "darwin") return join53(home, "Library", "Application Support", "Code", "User");
|
|
100177
|
+
return join53(env2["XDG_CONFIG_HOME"] ?? join53(home, ".config"), "Code", "User");
|
|
99709
100178
|
}
|
|
99710
100179
|
function scanHarnessConfigs(paths, read2 = readBounded) {
|
|
99711
100180
|
const findings = [];
|
|
@@ -99722,7 +100191,7 @@ function readBounded(path3) {
|
|
|
99722
100191
|
try {
|
|
99723
100192
|
const stat4 = statSync14(path3);
|
|
99724
100193
|
if (!stat4.isFile() || stat4.size > MAX_SCAN_BYTES) return null;
|
|
99725
|
-
return
|
|
100194
|
+
return readFileSync45(path3, "utf8");
|
|
99726
100195
|
} catch {
|
|
99727
100196
|
return null;
|
|
99728
100197
|
}
|
|
@@ -99747,14 +100216,14 @@ function credentialHygieneCheck(scan2) {
|
|
|
99747
100216
|
|
|
99748
100217
|
// src/codex-doctor.ts
|
|
99749
100218
|
import { spawn as spawn4 } from "node:child_process";
|
|
99750
|
-
import { readFileSync as
|
|
99751
|
-
import { join as
|
|
100219
|
+
import { readFileSync as readFileSync47, statSync as statSync15 } from "node:fs";
|
|
100220
|
+
import { join as join55 } from "node:path";
|
|
99752
100221
|
import { createInterface } from "node:readline";
|
|
99753
100222
|
|
|
99754
100223
|
// src/codex-hooks.ts
|
|
99755
|
-
import { existsSync as
|
|
100224
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync10, readFileSync as readFileSync46, renameSync as renameSync9, unlinkSync as unlinkSync5, writeFileSync as writeFileSync32 } from "node:fs";
|
|
99756
100225
|
import { homedir as homedir9 } from "node:os";
|
|
99757
|
-
import { join as
|
|
100226
|
+
import { join as join54 } from "node:path";
|
|
99758
100227
|
|
|
99759
100228
|
// src/hook-commands.ts
|
|
99760
100229
|
function hookCurlCommand(port, path3 = "/api/hook") {
|
|
@@ -100010,34 +100479,34 @@ function buildCodexRelaySource(workspaceRoot) {
|
|
|
100010
100479
|
init_checkout_root();
|
|
100011
100480
|
var CODEX_HOOK_REVIEW_HELP = "Codex desktop: Settings > Hooks, select this project, expand each event and Trust the Errata hook. CLI users can use /hooks.";
|
|
100012
100481
|
function writeRelay(file2, source) {
|
|
100013
|
-
if (
|
|
100482
|
+
if (existsSync38(file2) && readFileSync46(file2, "utf8") === source) return;
|
|
100014
100483
|
const temp = `${file2}.${process.pid}.tmp`;
|
|
100015
100484
|
try {
|
|
100016
|
-
|
|
100017
|
-
|
|
100485
|
+
writeFileSync32(temp, source, { encoding: "utf8", mode: 384 });
|
|
100486
|
+
renameSync9(temp, file2);
|
|
100018
100487
|
} finally {
|
|
100019
|
-
if (
|
|
100488
|
+
if (existsSync38(temp)) unlinkSync5(temp);
|
|
100020
100489
|
}
|
|
100021
100490
|
}
|
|
100022
100491
|
function refreshCodexRelay(root) {
|
|
100023
|
-
const config2 =
|
|
100024
|
-
if (!
|
|
100025
|
-
const existing =
|
|
100492
|
+
const config2 = join54(root, ".codex", "config.toml");
|
|
100493
|
+
if (!existsSync38(config2)) return "absent";
|
|
100494
|
+
const existing = readFileSync46(config2, "utf8");
|
|
100026
100495
|
if (!existing.includes(CODEX_HOOKS_BEGIN) && !existing.includes(CODEX_HOOKS_END)) return "absent";
|
|
100027
100496
|
replaceCodexHooks(existing, "");
|
|
100028
|
-
const relay =
|
|
100029
|
-
const prior =
|
|
100497
|
+
const relay = join54(root, ".codex", "hooks", "errata-relay.mjs");
|
|
100498
|
+
const prior = existsSync38(relay) ? readFileSync46(relay, "utf8") : "";
|
|
100030
100499
|
if (prior && !prior.startsWith("// errata-managed: regenerated by errata install-hooks codex")) {
|
|
100031
100500
|
throw new Error("Codex relay is not Errata-managed; preserved it. Run errata install-hooks codex to explicitly replace it.");
|
|
100032
100501
|
}
|
|
100033
100502
|
const source = buildCodexRelaySource(checkoutRootOf(root));
|
|
100034
100503
|
if (prior === source) return "current";
|
|
100035
|
-
mkdirSync10(
|
|
100504
|
+
mkdirSync10(join54(root, ".codex", "hooks"), { recursive: true });
|
|
100036
100505
|
writeRelay(relay, source);
|
|
100037
100506
|
return "updated";
|
|
100038
100507
|
}
|
|
100039
|
-
function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] ||
|
|
100040
|
-
return
|
|
100508
|
+
function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] || join54(homedir9(), ".codex")) {
|
|
100509
|
+
return existsSync38(join54(root, ".codex")) || existsSync38(codexHome);
|
|
100041
100510
|
}
|
|
100042
100511
|
function replaceCodexHooks(existing, block) {
|
|
100043
100512
|
const begin = existing.indexOf(CODEX_HOOKS_BEGIN);
|
|
@@ -100053,14 +100522,14 @@ function replaceCodexHooks(existing, block) {
|
|
|
100053
100522
|
return existing.trimEnd() + (existing.trim() ? "\n\n" : "") + block;
|
|
100054
100523
|
}
|
|
100055
100524
|
function writeCodexHooks(root, port, nodePath = process.execPath) {
|
|
100056
|
-
const dir =
|
|
100057
|
-
const file2 =
|
|
100058
|
-
const relay =
|
|
100525
|
+
const dir = join54(root, ".codex");
|
|
100526
|
+
const file2 = join54(dir, "config.toml");
|
|
100527
|
+
const relay = join54(dir, "hooks", "errata-relay.mjs");
|
|
100059
100528
|
const block = buildCodexHooksToml(port, { nodePath, relayPath: relay });
|
|
100060
|
-
const final = replaceCodexHooks(
|
|
100061
|
-
mkdirSync10(
|
|
100529
|
+
const final = replaceCodexHooks(existsSync38(file2) ? readFileSync46(file2, "utf8") : "", block);
|
|
100530
|
+
mkdirSync10(join54(dir, "hooks"), { recursive: true });
|
|
100062
100531
|
writeRelay(relay, buildCodexRelaySource(checkoutRootOf(root)));
|
|
100063
|
-
if (!
|
|
100532
|
+
if (!existsSync38(file2) || readFileSync46(file2, "utf8") !== final) writeFileSync32(file2, final, "utf8");
|
|
100064
100533
|
return file2;
|
|
100065
100534
|
}
|
|
100066
100535
|
|
|
@@ -100069,7 +100538,7 @@ init_checkout_root();
|
|
|
100069
100538
|
function inspectCodexRelay(cwd) {
|
|
100070
100539
|
const root = nearestGitRoot(cwd) ?? cwd;
|
|
100071
100540
|
try {
|
|
100072
|
-
const source =
|
|
100541
|
+
const source = readFileSync47(join55(root, ".codex", "hooks", "errata-relay.mjs"), "utf8");
|
|
100073
100542
|
if (source === buildCodexRelaySource(checkoutRootOf(root))) {
|
|
100074
100543
|
return { id: "codex_relay", status: "pass", detail: "Installed Codex relay matches this Errata version" };
|
|
100075
100544
|
}
|
|
@@ -100080,8 +100549,8 @@ function inspectCodexRelay(cwd) {
|
|
|
100080
100549
|
function inspectCodexContext(cwd) {
|
|
100081
100550
|
const root = checkoutRootOf(nearestGitRoot(cwd) ?? cwd);
|
|
100082
100551
|
try {
|
|
100083
|
-
const file2 =
|
|
100084
|
-
if (statSync15(file2).size <= 128 * 1024 &&
|
|
100552
|
+
const file2 = join55(root, ".errata", "context.md");
|
|
100553
|
+
if (statSync15(file2).size <= 128 * 1024 && readFileSync47(file2, "utf8").trim()) {
|
|
100085
100554
|
return { id: "codex_context", status: "pass", detail: "Saved workspace context is readable by the relay; this does not prove live daemon freshness" };
|
|
100086
100555
|
}
|
|
100087
100556
|
} catch {
|
|
@@ -100220,9 +100689,9 @@ function effectiveMomentumThreshold(policy, liveNodes) {
|
|
|
100220
100689
|
return Math.max(policy.momentumThreshold, Math.ceil(liveNodes * policy.momentumRatio));
|
|
100221
100690
|
}
|
|
100222
100691
|
function nextMomentumThreshold(args2) {
|
|
100223
|
-
const { current, consumed, landmarkFlips, floor, cap } = args2;
|
|
100692
|
+
const { current, consumed, landmarkFlips, floor, cap: cap2 } = args2;
|
|
100224
100693
|
const next = landmarkFlips > 0 ? Math.min(current, Math.round(consumed / 2)) : Math.max(current, Math.round(consumed * 1.5));
|
|
100225
|
-
return Math.max(floor, Math.min(
|
|
100694
|
+
return Math.max(floor, Math.min(cap2, next));
|
|
100226
100695
|
}
|
|
100227
100696
|
var DEFAULT_CONSOLIDATION_POLICY = {
|
|
100228
100697
|
baseFloorMs: 6e4,
|
|
@@ -100259,10 +100728,10 @@ function consolidationGapMs(lastPassMs, policy) {
|
|
|
100259
100728
|
|
|
100260
100729
|
// src/codex-context-plugin.ts
|
|
100261
100730
|
import { createHash as createHash21 } from "node:crypto";
|
|
100262
|
-
import { cpSync as cpSync2, existsSync as
|
|
100731
|
+
import { cpSync as cpSync2, existsSync as existsSync39, mkdirSync as mkdirSync11, readFileSync as readFileSync48, renameSync as renameSync10, writeFileSync as writeFileSync33 } from "node:fs";
|
|
100263
100732
|
import { homedir as homedir10 } from "node:os";
|
|
100264
|
-
import { join as
|
|
100265
|
-
import { fileURLToPath as
|
|
100733
|
+
import { join as join56 } from "node:path";
|
|
100734
|
+
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
100266
100735
|
|
|
100267
100736
|
// ../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/error.js
|
|
100268
100737
|
function getLineColFromPtr(string4, ptr) {
|
|
@@ -100959,23 +101428,23 @@ var NAME = "errata-context";
|
|
|
100959
101428
|
var PREFIX2 = `./.errata/plugins/${NAME}/`;
|
|
100960
101429
|
var object2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
100961
101430
|
function readText(file2) {
|
|
100962
|
-
return
|
|
101431
|
+
return existsSync39(file2) ? readFileSync48(file2, "utf8") : "";
|
|
100963
101432
|
}
|
|
100964
101433
|
function writeChanged(file2, content) {
|
|
100965
101434
|
if (readText(file2) === content) return;
|
|
100966
101435
|
const temp = `${file2}.${process.pid}.tmp`;
|
|
100967
|
-
|
|
100968
|
-
|
|
101436
|
+
writeFileSync33(temp, content, "utf8");
|
|
101437
|
+
renameSync10(temp, file2);
|
|
100969
101438
|
}
|
|
100970
101439
|
function bundledContextPlugin() {
|
|
100971
|
-
const packaged =
|
|
100972
|
-
if (
|
|
100973
|
-
return
|
|
101440
|
+
const packaged = fileURLToPath4(new URL("./resources/context-plugin/", import.meta.url));
|
|
101441
|
+
if (existsSync39(join56(packaged, ".codex-plugin/plugin.json"))) return packaged;
|
|
101442
|
+
return fileURLToPath4(new URL("../dist/resources/context-plugin/", import.meta.url));
|
|
100974
101443
|
}
|
|
100975
101444
|
function refreshCodexContextPlugin(root) {
|
|
100976
|
-
const file2 =
|
|
100977
|
-
if (!
|
|
100978
|
-
const marketplace = JSON.parse(
|
|
101445
|
+
const file2 = join56(root, ".agents", "plugins", "marketplace.json");
|
|
101446
|
+
if (!existsSync39(file2)) return false;
|
|
101447
|
+
const marketplace = JSON.parse(readFileSync48(file2, "utf8"));
|
|
100979
101448
|
const entries = Array.isArray(marketplace.plugins) ? marketplace.plugins : [];
|
|
100980
101449
|
const entry = entries.map(object2).find((value) => value.name === NAME && String(object2(value.source).path).startsWith(PREFIX2));
|
|
100981
101450
|
if (!entry) return false;
|
|
@@ -100986,24 +101455,24 @@ function refreshCodexContextPlugin(root) {
|
|
|
100986
101455
|
function installCodexContextPlugin(root, options = {}) {
|
|
100987
101456
|
const bundle = options.bundle ?? bundledContextPlugin();
|
|
100988
101457
|
const manifest = JSON.parse(
|
|
100989
|
-
|
|
101458
|
+
readFileSync48(join56(bundle, ".codex-plugin/plugin.json"), "utf8")
|
|
100990
101459
|
);
|
|
100991
101460
|
if (manifest.name !== NAME || typeof manifest.version !== "string" || !/^[\w.-]+$/.test(manifest.version)) {
|
|
100992
101461
|
throw new Error("Invalid bundled Errata Context manifest.");
|
|
100993
101462
|
}
|
|
100994
|
-
const checksums =
|
|
101463
|
+
const checksums = readFileSync48(join56(bundle, "SHA256SUMS"), "utf8");
|
|
100995
101464
|
for (const line of checksums.trim().split("\n")) {
|
|
100996
101465
|
const match2 = /^([a-f0-9]{64}) ([\w./-]+)$/.exec(line);
|
|
100997
101466
|
if (!match2 || match2[2].startsWith("/") || match2[2].split("/").includes("..")) {
|
|
100998
101467
|
throw new Error("Invalid bundled Errata Context checksum manifest.");
|
|
100999
101468
|
}
|
|
101000
|
-
const actual = createHash21("sha256").update(
|
|
101469
|
+
const actual = createHash21("sha256").update(readFileSync48(join56(bundle, match2[2]))).digest("hex");
|
|
101001
101470
|
if (actual !== match2[1])
|
|
101002
101471
|
throw new Error(`Bundled Errata Context checksum mismatch: ${match2[2]}`);
|
|
101003
101472
|
}
|
|
101004
101473
|
const release = `${manifest.version}-${createHash21("sha256").update(checksums).digest("hex").slice(0, 12)}`;
|
|
101005
|
-
const plugin =
|
|
101006
|
-
const marketplaceFile =
|
|
101474
|
+
const plugin = join56(root, ".errata", "plugins", NAME, release);
|
|
101475
|
+
const marketplaceFile = join56(root, ".agents", "plugins", "marketplace.json");
|
|
101007
101476
|
const priorMarketplace = readText(marketplaceFile);
|
|
101008
101477
|
const marketplace = priorMarketplace ? JSON.parse(priorMarketplace) : {
|
|
101009
101478
|
name: "errata-local",
|
|
@@ -101024,12 +101493,12 @@ function installCodexContextPlugin(root, options = {}) {
|
|
|
101024
101493
|
);
|
|
101025
101494
|
}
|
|
101026
101495
|
const key = `${NAME}@${marketplace.name}`;
|
|
101027
|
-
const configFile =
|
|
101496
|
+
const configFile = join56(root, ".codex", "config.toml");
|
|
101028
101497
|
const config2 = readText(configFile);
|
|
101029
101498
|
const parsed = parse4(config2);
|
|
101030
101499
|
const plugins = object2(parsed.plugins);
|
|
101031
|
-
const codexHome = options.codexHome ?? process.env["CODEX_HOME"] ??
|
|
101032
|
-
const globalPlugins = object2(parse4(readText(
|
|
101500
|
+
const codexHome = options.codexHome ?? process.env["CODEX_HOME"] ?? join56(homedir10(), ".codex");
|
|
101501
|
+
const globalPlugins = object2(parse4(readText(join56(codexHome, "config.toml"))).plugins);
|
|
101033
101502
|
const disabledGlobally = Object.entries(globalPlugins).some(
|
|
101034
101503
|
([name2, value]) => (name2 === NAME || name2.startsWith(`${NAME}@`)) && object2(value).enabled === false
|
|
101035
101504
|
);
|
|
@@ -101053,13 +101522,13 @@ enabled = ${enabled}
|
|
|
101053
101522
|
mkdirSync11(plugin, { recursive: true });
|
|
101054
101523
|
cpSync2(bundle, plugin, { recursive: true });
|
|
101055
101524
|
writeChanged(
|
|
101056
|
-
|
|
101525
|
+
join56(plugin, ".mcp.json"),
|
|
101057
101526
|
JSON.stringify(
|
|
101058
101527
|
{
|
|
101059
101528
|
mcpServers: {
|
|
101060
101529
|
errata_context: {
|
|
101061
101530
|
command: options.nodePath ?? process.execPath,
|
|
101062
|
-
args: [
|
|
101531
|
+
args: [join56(plugin, "dist", "mcp-server.mjs")],
|
|
101063
101532
|
env: { ERRATA_WORKSPACE: root, ERRATA_CONTEXT_VERSION: manifest.version }
|
|
101064
101533
|
}
|
|
101065
101534
|
}
|
|
@@ -101068,8 +101537,8 @@ enabled = ${enabled}
|
|
|
101068
101537
|
2
|
|
101069
101538
|
) + "\n"
|
|
101070
101539
|
);
|
|
101071
|
-
mkdirSync11(
|
|
101072
|
-
mkdirSync11(
|
|
101540
|
+
mkdirSync11(join56(root, ".agents", "plugins"), { recursive: true });
|
|
101541
|
+
mkdirSync11(join56(root, ".codex"), { recursive: true });
|
|
101073
101542
|
writeChanged(marketplaceFile, JSON.stringify(marketplace, null, 2) + "\n");
|
|
101074
101543
|
writeChanged(configFile, nextConfig);
|
|
101075
101544
|
return { plugin, enabled, marketplace: marketplaceFile };
|
|
@@ -101077,16 +101546,16 @@ enabled = ${enabled}
|
|
|
101077
101546
|
|
|
101078
101547
|
// src/codex-hook-refresh.ts
|
|
101079
101548
|
init_checkout_root();
|
|
101080
|
-
import { existsSync as
|
|
101081
|
-
import { dirname as
|
|
101549
|
+
import { existsSync as existsSync40, readdirSync as readdirSync14, readFileSync as readFileSync49 } from "node:fs";
|
|
101550
|
+
import { dirname as dirname22, join as join57, resolve as resolve9 } from "node:path";
|
|
101082
101551
|
init_registry();
|
|
101083
101552
|
function codexHookRoots(roots) {
|
|
101084
101553
|
const found = new Set(roots.map((root) => resolve9(root)));
|
|
101085
101554
|
for (const root of [...found]) {
|
|
101086
101555
|
const main2 = mainCheckoutOfWorktree(root) ?? root;
|
|
101087
101556
|
found.add(main2);
|
|
101088
|
-
const dir =
|
|
101089
|
-
if (!
|
|
101557
|
+
const dir = join57(main2, ".git", "worktrees");
|
|
101558
|
+
if (!existsSync40(dir)) continue;
|
|
101090
101559
|
let names;
|
|
101091
101560
|
try {
|
|
101092
101561
|
names = readdirSync14(dir);
|
|
@@ -101095,7 +101564,7 @@ function codexHookRoots(roots) {
|
|
|
101095
101564
|
}
|
|
101096
101565
|
for (const name2 of names) {
|
|
101097
101566
|
try {
|
|
101098
|
-
const checkout =
|
|
101567
|
+
const checkout = dirname22(readFileSync49(join57(dir, name2, "gitdir"), "utf8").trim());
|
|
101099
101568
|
if (mainCheckoutOfWorktree(checkout) === main2) found.add(checkout);
|
|
101100
101569
|
} catch {
|
|
101101
101570
|
}
|
|
@@ -101118,14 +101587,14 @@ function refreshInstalledCodexRelays(roots = listWorkspaceEntries().map((entry)
|
|
|
101118
101587
|
|
|
101119
101588
|
// src/claude-mods.ts
|
|
101120
101589
|
import { createHash as createHash22 } from "node:crypto";
|
|
101121
|
-
import { cpSync as cpSync3, existsSync as
|
|
101122
|
-
import { delimiter as delimiter2, dirname as
|
|
101123
|
-
import { fileURLToPath as
|
|
101590
|
+
import { cpSync as cpSync3, existsSync as existsSync41, mkdirSync as mkdirSync12, readFileSync as readFileSync50, readdirSync as readdirSync15, rmSync as rmSync4, statSync as statSync16, writeFileSync as writeFileSync34 } from "node:fs";
|
|
101591
|
+
import { delimiter as delimiter2, dirname as dirname23, join as join58, relative as relative7, resolve as resolve10, sep as sep6 } from "node:path";
|
|
101592
|
+
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
101124
101593
|
var CLAUDE_PLUGIN_DIRS_ENV = "CLAUDE_CODE_PLUGIN_DIRS";
|
|
101125
101594
|
var HASH_FILE = ".errata-mod-hash";
|
|
101126
101595
|
function bundledClaudeModsDir() {
|
|
101127
101596
|
const rel = import.meta.url.endsWith(".mjs") ? "./resources/claude-mods/" : "../claude-mods/";
|
|
101128
|
-
return
|
|
101597
|
+
return fileURLToPath5(new URL(rel, import.meta.url));
|
|
101129
101598
|
}
|
|
101130
101599
|
function isEngineOwned(relPath) {
|
|
101131
101600
|
const p = relPath.split(sep6).join("/");
|
|
@@ -101134,7 +101603,7 @@ function isEngineOwned(relPath) {
|
|
|
101134
101603
|
function listFiles(root, dir = root) {
|
|
101135
101604
|
const out2 = [];
|
|
101136
101605
|
for (const name2 of readdirSync15(dir)) {
|
|
101137
|
-
const abs =
|
|
101606
|
+
const abs = join58(dir, name2);
|
|
101138
101607
|
if (isEngineOwned(relative7(root, abs))) continue;
|
|
101139
101608
|
if (statSync16(abs).isDirectory()) out2.push(...listFiles(root, abs));
|
|
101140
101609
|
else out2.push(abs);
|
|
@@ -101146,14 +101615,14 @@ function modHash(dir) {
|
|
|
101146
101615
|
for (const abs of listFiles(dir).sort()) {
|
|
101147
101616
|
h.update(relative7(dir, abs).split(sep6).join("/"));
|
|
101148
101617
|
h.update("\0");
|
|
101149
|
-
h.update(
|
|
101618
|
+
h.update(readFileSync50(abs));
|
|
101150
101619
|
h.update("\0");
|
|
101151
101620
|
}
|
|
101152
101621
|
return h.digest("hex");
|
|
101153
101622
|
}
|
|
101154
101623
|
function bundledMods(bundleDir) {
|
|
101155
|
-
if (!
|
|
101156
|
-
return readdirSync15(bundleDir).filter((name2) =>
|
|
101624
|
+
if (!existsSync41(bundleDir)) return [];
|
|
101625
|
+
return readdirSync15(bundleDir).filter((name2) => existsSync41(join58(bundleDir, name2, ".claude-plugin", "plugin.json")));
|
|
101157
101626
|
}
|
|
101158
101627
|
function sameDir(a, b) {
|
|
101159
101628
|
const norm = (p) => resolve10(p).replace(/[\\/]+$/, "").toLowerCase();
|
|
@@ -101168,9 +101637,9 @@ function off(env2) {
|
|
|
101168
101637
|
return v === "0" || v === "off" || v === "false" || v === "no";
|
|
101169
101638
|
}
|
|
101170
101639
|
function readSettings(path3) {
|
|
101171
|
-
if (!
|
|
101640
|
+
if (!existsSync41(path3)) return {};
|
|
101172
101641
|
try {
|
|
101173
|
-
const parsed = JSON.parse(
|
|
101642
|
+
const parsed = JSON.parse(readFileSync50(path3, "utf8"));
|
|
101174
101643
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
101175
101644
|
return parsed;
|
|
101176
101645
|
} catch {
|
|
@@ -101194,13 +101663,13 @@ function currentDirs(settings) {
|
|
|
101194
101663
|
return raw2.split(delimiter2).map((s) => s.trim()).filter(Boolean);
|
|
101195
101664
|
}
|
|
101196
101665
|
function writeSettings(path3, settings) {
|
|
101197
|
-
mkdirSync12(
|
|
101198
|
-
|
|
101666
|
+
mkdirSync12(dirname23(path3), { recursive: true });
|
|
101667
|
+
writeFileSync34(path3, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
101199
101668
|
}
|
|
101200
101669
|
function ensureClaudeMods(opts) {
|
|
101201
101670
|
const env2 = opts.env ?? process.env;
|
|
101202
101671
|
const settingsPath = opts.userSettingsPath ?? userClaudeSettingsPath();
|
|
101203
|
-
const modsRoot =
|
|
101672
|
+
const modsRoot = join58(opts.installRoot, "claude-mods");
|
|
101204
101673
|
if (off(env2)) {
|
|
101205
101674
|
const settings2 = readSettings(settingsPath);
|
|
101206
101675
|
if (!settings2) return { kind: "unreadable" };
|
|
@@ -101217,14 +101686,14 @@ function ensureClaudeMods(opts) {
|
|
|
101217
101686
|
let changed = false;
|
|
101218
101687
|
const installed = [];
|
|
101219
101688
|
for (const name2 of names) {
|
|
101220
|
-
const src =
|
|
101221
|
-
const dest =
|
|
101689
|
+
const src = join58(bundleDir, name2);
|
|
101690
|
+
const dest = join58(modsRoot, name2);
|
|
101222
101691
|
const hash2 = modHash(src);
|
|
101223
|
-
const hashFile =
|
|
101224
|
-
if (!
|
|
101692
|
+
const hashFile = join58(dest, HASH_FILE);
|
|
101693
|
+
if (!existsSync41(hashFile) || readFileSync50(hashFile, "utf8") !== hash2) {
|
|
101225
101694
|
rmSync4(dest, { recursive: true, force: true });
|
|
101226
101695
|
cpSync3(src, dest, { recursive: true, filter: (p) => !isEngineOwned(relative7(src, p)) });
|
|
101227
|
-
|
|
101696
|
+
writeFileSync34(hashFile, hash2, "utf8");
|
|
101228
101697
|
changed = true;
|
|
101229
101698
|
}
|
|
101230
101699
|
installed.push(dest);
|
|
@@ -101655,9 +102124,9 @@ function resolveHookPort(explicit) {
|
|
|
101655
102124
|
}
|
|
101656
102125
|
}
|
|
101657
102126
|
}
|
|
101658
|
-
const settingsPath =
|
|
102127
|
+
const settingsPath = join59(ROOT, ".claude", "settings.json");
|
|
101659
102128
|
try {
|
|
101660
|
-
if (
|
|
102129
|
+
if (existsSync42(settingsPath)) return installedHookPort(readFileSync51(settingsPath, "utf8")) ?? 7891;
|
|
101661
102130
|
} catch {
|
|
101662
102131
|
}
|
|
101663
102132
|
return 7891;
|
|
@@ -101682,14 +102151,14 @@ async function cmdInit() {
|
|
|
101682
102151
|
if (!skipHooks) {
|
|
101683
102152
|
console.log("");
|
|
101684
102153
|
console.log("installing harness hooks...");
|
|
101685
|
-
const { existsSync:
|
|
101686
|
-
const { join:
|
|
102154
|
+
const { existsSync: existsSync43 } = await import("node:fs");
|
|
102155
|
+
const { join: join60 } = await import("node:path");
|
|
101687
102156
|
try {
|
|
101688
102157
|
await installClaudeHooks(port);
|
|
101689
102158
|
} catch (err2) {
|
|
101690
102159
|
console.warn(` \u26A0\uFE0F Claude hook install failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
101691
102160
|
}
|
|
101692
|
-
if (
|
|
102161
|
+
if (existsSync43(join60(ROOT, ".cursor"))) {
|
|
101693
102162
|
try {
|
|
101694
102163
|
await installCursorMcpConfig();
|
|
101695
102164
|
} catch (err2) {
|
|
@@ -101905,12 +102374,12 @@ async function cmdStatus() {
|
|
|
101905
102374
|
console.log(` stack: ${profile.stack.join(", ") || "(none)"}`);
|
|
101906
102375
|
console.log(` languages: ${profile.languages.join(", ") || "(none)"}`);
|
|
101907
102376
|
}
|
|
101908
|
-
console.log(` graph db: ${
|
|
101909
|
-
console.log(` event log: ${
|
|
102377
|
+
console.log(` graph db: ${existsSync42(paths.castalia) ? "yes" : "no"} (${paths.castalia})`);
|
|
102378
|
+
console.log(` event log: ${existsSync42(paths.eventLog) ? "yes" : "no"} (${paths.eventLog})`);
|
|
101910
102379
|
for (const line of captureStatusLines(summarizePassLedger(paths.configDir).get("capture"))) {
|
|
101911
102380
|
console.log(` capture: ${line}`);
|
|
101912
102381
|
}
|
|
101913
|
-
if (
|
|
102382
|
+
if (existsSync42(paths.castalia)) {
|
|
101914
102383
|
try {
|
|
101915
102384
|
const { openGraphStore: openGraphStore2 } = await Promise.resolve().then(() => (init_src5(), src_exports2));
|
|
101916
102385
|
const store = openGraphStore2({ path: paths.castalia });
|
|
@@ -102911,11 +103380,11 @@ async function cmdInstallationProfile(args2) {
|
|
|
102911
103380
|
}
|
|
102912
103381
|
async function cmdReview() {
|
|
102913
103382
|
const paths = workspacePaths(ROOT);
|
|
102914
|
-
if (!
|
|
103383
|
+
if (!existsSync42(paths.reviewQueue)) {
|
|
102915
103384
|
console.log("(review queue empty)");
|
|
102916
103385
|
return;
|
|
102917
103386
|
}
|
|
102918
|
-
const queue = JSON.parse(
|
|
103387
|
+
const queue = JSON.parse(readFileSync51(paths.reviewQueue, "utf8"));
|
|
102919
103388
|
if (queue.length === 0) {
|
|
102920
103389
|
console.log("(review queue empty)");
|
|
102921
103390
|
return;
|
|
@@ -103517,9 +103986,8 @@ async function gatherRepo(store, ws) {
|
|
|
103517
103986
|
next: { verb: "burst", arg: p.id, hint: "full causal chain" }
|
|
103518
103987
|
});
|
|
103519
103988
|
}
|
|
103520
|
-
const
|
|
103521
|
-
const
|
|
103522
|
-
const embedded = spineSrc.map((n, i2) => ({ i: i2, emb: embeddingOf(n) })).filter((x) => x.emb != null);
|
|
103989
|
+
const versionOf = (n) => String(n.attrs["embeddingVersion"] ?? "hash-v1");
|
|
103990
|
+
const embedded = spineSrc.map((n, i2) => ({ i: i2, emb: embeddingOf(n), version: versionOf(n) })).filter((x) => x.emb != null);
|
|
103523
103991
|
const seenPair = new Set(spineEdges.map((e) => e.a < e.b ? `${e.a}-${e.b}` : `${e.b}-${e.a}`));
|
|
103524
103992
|
const addImplied = (a, b) => {
|
|
103525
103993
|
const key = a < b ? `${a}-${b}` : `${b}-${a}`;
|
|
@@ -103528,12 +103996,13 @@ async function gatherRepo(store, ws) {
|
|
|
103528
103996
|
spineEdges.push({ a, b, kind: "implied" });
|
|
103529
103997
|
};
|
|
103530
103998
|
for (let x = 0; x < embedded.length; x++) {
|
|
103999
|
+
const { relatedWeak, relatedStrong } = cosineBandsFor(embedded[x].version);
|
|
103531
104000
|
let best = -1;
|
|
103532
|
-
let bestSim =
|
|
104001
|
+
let bestSim = relatedWeak;
|
|
103533
104002
|
for (let y = 0; y < embedded.length; y++) {
|
|
103534
|
-
if (y === x) continue;
|
|
104003
|
+
if (y === x || embedded[y].version !== embedded[x].version) continue;
|
|
103535
104004
|
const sim = cosine5(embedded[x].emb, embedded[y].emb);
|
|
103536
|
-
if (sim >=
|
|
104005
|
+
if (sim >= relatedStrong) addImplied(embedded[x].i, embedded[y].i);
|
|
103537
104006
|
if (sim > bestSim) {
|
|
103538
104007
|
bestSim = sim;
|
|
103539
104008
|
best = embedded[y].i;
|
|
@@ -103615,7 +104084,7 @@ async function gatherRepo(store, ws) {
|
|
|
103615
104084
|
};
|
|
103616
104085
|
}
|
|
103617
104086
|
async function gatherReportData(generatedAt) {
|
|
103618
|
-
const { existsSync:
|
|
104087
|
+
const { existsSync: existsSync43 } = await import("node:fs");
|
|
103619
104088
|
const { openGraphStore: openGraphStore2 } = await Promise.resolve().then(() => (init_src5(), src_exports2));
|
|
103620
104089
|
const cfg = loadConfig();
|
|
103621
104090
|
const outbound = cfg.consent.sync ? "auto" : "off";
|
|
@@ -103623,7 +104092,7 @@ async function gatherReportData(generatedAt) {
|
|
|
103623
104092
|
for (const ws of listWorkspaces()) {
|
|
103624
104093
|
if (ws.missing) continue;
|
|
103625
104094
|
const dbPath = workspacePaths(ws.path).castalia;
|
|
103626
|
-
if (!
|
|
104095
|
+
if (!existsSync43(dbPath)) continue;
|
|
103627
104096
|
let store = null;
|
|
103628
104097
|
try {
|
|
103629
104098
|
store = openGraphStore2({ path: dbPath });
|
|
@@ -103654,7 +104123,7 @@ async function gatherReportData(generatedAt) {
|
|
|
103654
104123
|
};
|
|
103655
104124
|
}
|
|
103656
104125
|
async function cmdReport(args2) {
|
|
103657
|
-
const { mkdirSync: mkdirSync13, writeFileSync:
|
|
104126
|
+
const { mkdirSync: mkdirSync13, writeFileSync: writeFileSync36 } = await import("node:fs");
|
|
103658
104127
|
const { renderReport: renderReport2 } = await Promise.resolve().then(() => (init_report_render(), report_render_exports));
|
|
103659
104128
|
const includeFutureVerbs = args2.includes("--future-verbs");
|
|
103660
104129
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -103667,8 +104136,8 @@ async function cmdReport(args2) {
|
|
|
103667
104136
|
const outDir = workspacePaths(ROOT).configDir;
|
|
103668
104137
|
mkdirSync13(outDir, { recursive: true });
|
|
103669
104138
|
const files = renderReport2(data, { includeFutureVerbs });
|
|
103670
|
-
for (const f of files)
|
|
103671
|
-
const indexPath =
|
|
104139
|
+
for (const f of files) writeFileSync36(join59(outDir, f.name), f.html, "utf8");
|
|
104140
|
+
const indexPath = join59(outDir, "report.html");
|
|
103672
104141
|
console.log(`report \u2192 ${indexPath}`);
|
|
103673
104142
|
console.log(
|
|
103674
104143
|
` ${data.repos.length} repo(s) \xB7 ${files.length} file(s) \xB7 ${data.rollup.nodes.toLocaleString("en-US")} nodes`
|
|
@@ -103724,7 +104193,7 @@ function spawnDaemonDetached(options = {}) {
|
|
|
103724
104193
|
try {
|
|
103725
104194
|
const logPath = daemonLogPath();
|
|
103726
104195
|
try {
|
|
103727
|
-
if (statSync17(logPath).size > 5 * 1024 * 1024)
|
|
104196
|
+
if (statSync17(logPath).size > 5 * 1024 * 1024) renameSync11(logPath, `${logPath}.1`);
|
|
103728
104197
|
} catch {
|
|
103729
104198
|
}
|
|
103730
104199
|
out2 = openSync3(logPath, "a");
|
|
@@ -103797,24 +104266,24 @@ async function cmdInstallHooks(args2) {
|
|
|
103797
104266
|
}
|
|
103798
104267
|
}
|
|
103799
104268
|
async function installOpencodePlugin(port) {
|
|
103800
|
-
const { mkdirSync: mkdirSync13, existsSync:
|
|
103801
|
-
const { join:
|
|
103802
|
-
const dir =
|
|
103803
|
-
if (!
|
|
103804
|
-
const file2 =
|
|
103805
|
-
if (
|
|
103806
|
-
const head2 =
|
|
104269
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync43, readFileSync: readFileSync52, writeFileSync: writeFileSync36 } = await import("node:fs");
|
|
104270
|
+
const { join: join60 } = await import("node:path");
|
|
104271
|
+
const dir = join60(ROOT, ".opencode", "plugin");
|
|
104272
|
+
if (!existsSync43(dir)) mkdirSync13(dir, { recursive: true });
|
|
104273
|
+
const file2 = join60(dir, "inerrata.js");
|
|
104274
|
+
if (existsSync43(file2)) {
|
|
104275
|
+
const head2 = readFileSync52(file2, "utf8").split("\n")[0] ?? "";
|
|
103807
104276
|
if (head2.trim() !== OPENCODE_PLUGIN_MARKER) {
|
|
103808
104277
|
console.error(`refusing to overwrite ${file2}: not an errata-managed plugin (line 1 lacks the marker)`);
|
|
103809
104278
|
process.exit(2);
|
|
103810
104279
|
}
|
|
103811
104280
|
}
|
|
103812
|
-
|
|
103813
|
-
const cfgFile =
|
|
104281
|
+
writeFileSync36(file2, buildOpencodePluginSource(port, { version: DAEMON_VERSION }), "utf8");
|
|
104282
|
+
const cfgFile = join60(ROOT, "opencode.json");
|
|
103814
104283
|
let cfg = { $schema: "https://opencode.ai/config.json" };
|
|
103815
|
-
if (
|
|
104284
|
+
if (existsSync43(cfgFile)) {
|
|
103816
104285
|
try {
|
|
103817
|
-
cfg = JSON.parse(
|
|
104286
|
+
cfg = JSON.parse(readFileSync52(cfgFile, "utf8"));
|
|
103818
104287
|
} catch {
|
|
103819
104288
|
console.error(`refusing to touch invalid JSON at ${cfgFile} \u2014 fix it and re-run`);
|
|
103820
104289
|
process.exit(2);
|
|
@@ -103825,7 +104294,7 @@ async function installOpencodePlugin(port) {
|
|
|
103825
104294
|
if (!hadErrata) {
|
|
103826
104295
|
const inv = errataMcpInvocation();
|
|
103827
104296
|
cfg.mcp["errata"] = { type: "local", command: [inv.command, ...inv.args] };
|
|
103828
|
-
|
|
104297
|
+
writeFileSync36(cfgFile, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
103829
104298
|
}
|
|
103830
104299
|
console.log(`installed OpenCode plugin \u2192 ${file2}`);
|
|
103831
104300
|
if (hadErrata) console.log(` mcp.errata already present in ${cfgFile} \u2014 left untouched`);
|
|
@@ -103859,15 +104328,15 @@ function installClaudeMods() {
|
|
|
103859
104328
|
}
|
|
103860
104329
|
}
|
|
103861
104330
|
async function installClaudeHooks(port) {
|
|
103862
|
-
const { mkdirSync: mkdirSync13, existsSync:
|
|
103863
|
-
const { join:
|
|
103864
|
-
const dir =
|
|
103865
|
-
if (!
|
|
103866
|
-
const file2 =
|
|
104331
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync43, readFileSync: readFileSync52, writeFileSync: writeFileSync36 } = await import("node:fs");
|
|
104332
|
+
const { join: join60 } = await import("node:path");
|
|
104333
|
+
const dir = join60(ROOT, ".claude");
|
|
104334
|
+
if (!existsSync43(dir)) mkdirSync13(dir, { recursive: true });
|
|
104335
|
+
const file2 = join60(dir, "settings.json");
|
|
103867
104336
|
let settings = {};
|
|
103868
|
-
if (
|
|
104337
|
+
if (existsSync43(file2)) {
|
|
103869
104338
|
try {
|
|
103870
|
-
settings = JSON.parse(
|
|
104339
|
+
settings = JSON.parse(readFileSync52(file2, "utf8"));
|
|
103871
104340
|
} catch {
|
|
103872
104341
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
103873
104342
|
process.exit(2);
|
|
@@ -103875,12 +104344,12 @@ async function installClaudeHooks(port) {
|
|
|
103875
104344
|
}
|
|
103876
104345
|
applyClaudeErrataHooks(settings, port);
|
|
103877
104346
|
removeProjectStatusLine(settings);
|
|
103878
|
-
|
|
104347
|
+
writeFileSync36(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
103879
104348
|
console.log(`installed Claude Code hooks \u2192 ${file2}`);
|
|
103880
104349
|
console.log(` ${ensureStatusLine(port)}`);
|
|
103881
104350
|
console.log(` ${installClaudeMods().line}`);
|
|
103882
104351
|
await installClaudeMcpConfig();
|
|
103883
|
-
const claudeMd =
|
|
104352
|
+
const claudeMd = join60(ROOT, "CLAUDE.md");
|
|
103884
104353
|
const recall = writeManagedBlock(claudeMd, { body: RECALL_FIRST_BLOCK });
|
|
103885
104354
|
if (recall.kind === "collision") {
|
|
103886
104355
|
console.warn(
|
|
@@ -103892,15 +104361,15 @@ async function installClaudeHooks(port) {
|
|
|
103892
104361
|
console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
|
|
103893
104362
|
}
|
|
103894
104363
|
async function installClaudeMcpConfig() {
|
|
103895
|
-
const { mkdirSync: mkdirSync13, existsSync:
|
|
103896
|
-
const { join:
|
|
103897
|
-
const file2 =
|
|
103898
|
-
const dir =
|
|
103899
|
-
if (!
|
|
104364
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync43, readFileSync: readFileSync52, writeFileSync: writeFileSync36 } = await import("node:fs");
|
|
104365
|
+
const { join: join60, dirname: dirname24 } = await import("node:path");
|
|
104366
|
+
const file2 = join60(ROOT, ".mcp.json");
|
|
104367
|
+
const dir = dirname24(file2);
|
|
104368
|
+
if (!existsSync43(dir)) mkdirSync13(dir, { recursive: true });
|
|
103900
104369
|
let cfg = {};
|
|
103901
|
-
if (
|
|
104370
|
+
if (existsSync43(file2)) {
|
|
103902
104371
|
try {
|
|
103903
|
-
cfg = JSON.parse(
|
|
104372
|
+
cfg = JSON.parse(readFileSync52(file2, "utf8"));
|
|
103904
104373
|
} catch {
|
|
103905
104374
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
103906
104375
|
process.exit(2);
|
|
@@ -103908,21 +104377,21 @@ async function installClaudeMcpConfig() {
|
|
|
103908
104377
|
}
|
|
103909
104378
|
cfg.mcpServers ??= {};
|
|
103910
104379
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
103911
|
-
|
|
104380
|
+
writeFileSync36(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
103912
104381
|
console.log(`installed Claude Code MCP server config \u2192 ${file2}`);
|
|
103913
104382
|
console.log(` Claude Code will spawn \`errata mcp\` on workspace open.`);
|
|
103914
104383
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
|
|
103915
104384
|
}
|
|
103916
104385
|
async function installCursorMcpConfig() {
|
|
103917
|
-
const { mkdirSync: mkdirSync13, existsSync:
|
|
103918
|
-
const { join:
|
|
103919
|
-
const dir =
|
|
103920
|
-
if (!
|
|
103921
|
-
const file2 =
|
|
104386
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync43, readFileSync: readFileSync52, writeFileSync: writeFileSync36 } = await import("node:fs");
|
|
104387
|
+
const { join: join60 } = await import("node:path");
|
|
104388
|
+
const dir = join60(ROOT, ".cursor");
|
|
104389
|
+
if (!existsSync43(dir)) mkdirSync13(dir, { recursive: true });
|
|
104390
|
+
const file2 = join60(dir, "mcp.json");
|
|
103922
104391
|
let cfg = {};
|
|
103923
|
-
if (
|
|
104392
|
+
if (existsSync43(file2)) {
|
|
103924
104393
|
try {
|
|
103925
|
-
cfg = JSON.parse(
|
|
104394
|
+
cfg = JSON.parse(readFileSync52(file2, "utf8"));
|
|
103926
104395
|
} catch {
|
|
103927
104396
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
103928
104397
|
process.exit(2);
|
|
@@ -103930,7 +104399,7 @@ async function installCursorMcpConfig() {
|
|
|
103930
104399
|
}
|
|
103931
104400
|
cfg.mcpServers ??= {};
|
|
103932
104401
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
103933
|
-
|
|
104402
|
+
writeFileSync36(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
103934
104403
|
console.log(`installed Cursor MCP server config \u2192 ${file2}`);
|
|
103935
104404
|
console.log(` Cursor will spawn \`errata mcp\` on workspace open.`);
|
|
103936
104405
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses`);
|
|
@@ -103941,7 +104410,7 @@ async function installCodexHooks(port) {
|
|
|
103941
104410
|
const gitRoot = nearestGitRoot(process.cwd());
|
|
103942
104411
|
const hookRoot = gitRoot && mainCheckoutOfWorktree(gitRoot) ? gitRoot : ROOT;
|
|
103943
104412
|
const file2 = writeCodexHooks(hookRoot, port);
|
|
103944
|
-
const instructions = writeManagedBlock(
|
|
104413
|
+
const instructions = writeManagedBlock(join59(hookRoot, "AGENTS.md"), {
|
|
103945
104414
|
body: AGENTS_POINTER_BODY,
|
|
103946
104415
|
stable: true
|
|
103947
104416
|
});
|
|
@@ -103989,12 +104458,12 @@ function refreshExistingClaudeHooks() {
|
|
|
103989
104458
|
let ok = true;
|
|
103990
104459
|
const roots = [...listWorkspaceEntries().map((entry) => entry.path), process.cwd()];
|
|
103991
104460
|
for (const root of codexHookRoots(roots)) {
|
|
103992
|
-
const file2 =
|
|
104461
|
+
const file2 = join59(root, ".claude", "settings.json");
|
|
103993
104462
|
try {
|
|
103994
|
-
if (!
|
|
103995
|
-
const next = refreshClaudeHookSettings(
|
|
104463
|
+
if (!existsSync42(file2) || isReplayCheckout(root)) continue;
|
|
104464
|
+
const next = refreshClaudeHookSettings(readFileSync51(file2, "utf8"));
|
|
103996
104465
|
if (next === null) continue;
|
|
103997
|
-
|
|
104466
|
+
writeFileSync35(file2, next, "utf8");
|
|
103998
104467
|
console.log(`updated existing Claude Code hooks \u2192 ${file2}`);
|
|
103999
104468
|
} catch (error48) {
|
|
104000
104469
|
ok = false;
|
|
@@ -104406,9 +104875,9 @@ async function cmdDash(args2) {
|
|
|
104406
104875
|
await yieldToLoop2();
|
|
104407
104876
|
try {
|
|
104408
104877
|
const items = selectDurableMemory(handle2.sharedStore, r.engine.profile, {
|
|
104409
|
-
atCommit: readGitRefState(
|
|
104878
|
+
atCommit: readGitRefState(join59(r.root, ".git")).sha ?? void 0
|
|
104410
104879
|
});
|
|
104411
|
-
const res = bleedRules(
|
|
104880
|
+
const res = bleedRules(join59(r.root, ".claude", "rules"), items);
|
|
104412
104881
|
if (res.written || res.pruned) {
|
|
104413
104882
|
console.log(
|
|
104414
104883
|
`[rules:${r.entry.name}] ${res.written} collective principle(s) \u2192 .claude/rules` + (res.pruned ? `, ${res.pruned} pruned` : "")
|