squadrant 0.28.0 → 0.28.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +195 -137
- package/dist/index.js.map +1 -1
- package/dist/squadrantd.js +148 -90
- package/dist/squadrantd.js.map +1 -1
- package/package.json +1 -1
package/dist/squadrantd.js
CHANGED
|
@@ -9494,10 +9494,34 @@ function expandSource(kbRoot, entry) {
|
|
|
9494
9494
|
const re = globToRegExp(abs.split(path16.sep).join("/"));
|
|
9495
9495
|
return walkFiles(root).filter((f) => re.test(f.split(path16.sep).join("/"))).sort();
|
|
9496
9496
|
}
|
|
9497
|
-
function
|
|
9498
|
-
const
|
|
9499
|
-
|
|
9500
|
-
|
|
9497
|
+
function refCandidates(kbRoot, sources, ref) {
|
|
9498
|
+
const asIs = path16.resolve(kbRoot, expandHome(ref));
|
|
9499
|
+
if (path16.isAbsolute(expandHome(ref)))
|
|
9500
|
+
return [asIs];
|
|
9501
|
+
const bases = /* @__PURE__ */ new Set([kbRoot]);
|
|
9502
|
+
for (const s of sources) {
|
|
9503
|
+
let d = path16.resolve(kbRoot, expandHome(s.path.split(/[*?[{]/)[0]));
|
|
9504
|
+
for (let i = 0; i < 6 && d !== path16.dirname(d); i++) {
|
|
9505
|
+
d = path16.dirname(d);
|
|
9506
|
+
bases.add(d);
|
|
9507
|
+
}
|
|
9508
|
+
}
|
|
9509
|
+
return [.../* @__PURE__ */ new Set([asIs, ...[...bases].map((b) => path16.join(b, ref))])];
|
|
9510
|
+
}
|
|
9511
|
+
function refPath(kbRoot, sources, ref) {
|
|
9512
|
+
const cands = refCandidates(kbRoot, sources, ref);
|
|
9513
|
+
return cands.find(isFile) ?? cands.find((f) => sources.some((e) => entryCovers(kbRoot, e, f))) ?? cands[0];
|
|
9514
|
+
}
|
|
9515
|
+
function refCanon(kbRoot, sources) {
|
|
9516
|
+
const memo = /* @__PURE__ */ new Map();
|
|
9517
|
+
return (ref) => {
|
|
9518
|
+
let c = memo.get(ref);
|
|
9519
|
+
if (c === void 0) {
|
|
9520
|
+
c = refFor(kbRoot, refPath(kbRoot, sources, ref));
|
|
9521
|
+
memo.set(ref, c);
|
|
9522
|
+
}
|
|
9523
|
+
return c;
|
|
9524
|
+
};
|
|
9501
9525
|
}
|
|
9502
9526
|
function detectChange(kbRoot, file) {
|
|
9503
9527
|
const ref = refFor(kbRoot, file);
|
|
@@ -9595,7 +9619,7 @@ async function planIngest(kbRoot, opts) {
|
|
|
9595
9619
|
}
|
|
9596
9620
|
return plan;
|
|
9597
9621
|
}
|
|
9598
|
-
var execFileAsync, CONVERTED_DIR, DEFAULT_MAX_SECTIONS_PER_PASS, CHARS_PER_TOKEN, PASS_THROUGH, SECTION_TARGET_CHARS, markitdownConverter, expandHome,
|
|
9622
|
+
var execFileAsync, CONVERTED_DIR, DEFAULT_MAX_SECTIONS_PER_PASS, CHARS_PER_TOKEN, PASS_THROUGH, SECTION_TARGET_CHARS, markitdownConverter, expandHome, cacheKey, convertedFile, stampFile, isFile, resolveSourceRef, entryCovers, sourceCovers, isGatedRef, sha256;
|
|
9599
9623
|
var init_ingest = __esm({
|
|
9600
9624
|
"packages/core/dist/knowledge/ingest.js"() {
|
|
9601
9625
|
execFileAsync = promisify2(execFile2);
|
|
@@ -9609,11 +9633,17 @@ var init_ingest = __esm({
|
|
|
9609
9633
|
return stdout;
|
|
9610
9634
|
};
|
|
9611
9635
|
expandHome = (p) => p === "~" || p.startsWith("~/") ? path16.join(os7.homedir(), p.slice(1)) : p;
|
|
9612
|
-
fileForRef = (kbRoot, ref) => path16.resolve(kbRoot, expandHome(ref));
|
|
9613
9636
|
cacheKey = (ref) => `${ref.replace(/[^A-Za-z0-9._-]+/g, "_")}.${crypto3.createHash("sha1").update(ref).digest("hex").slice(0, 6)}`;
|
|
9614
9637
|
convertedFile = (kbRoot, ref) => path16.join(kbRoot, CONVERTED_DIR, `${cacheKey(ref)}.md`);
|
|
9615
9638
|
stampFile = (kbRoot, ref) => path16.join(kbRoot, CONVERTED_DIR, `${cacheKey(ref)}.sha`);
|
|
9616
|
-
|
|
9639
|
+
isFile = (f) => fs15.existsSync(f) && fs15.statSync(f).isFile();
|
|
9640
|
+
resolveSourceRef = (kbRoot, sources, ref) => refCandidates(kbRoot, sources, ref).find(isFile);
|
|
9641
|
+
entryCovers = (kbRoot, entry, file) => {
|
|
9642
|
+
const abs = path16.resolve(kbRoot, expandHome(entry.path));
|
|
9643
|
+
return /[*?]/.test(entry.path) ? globToRegExp(abs.split(path16.sep).join("/")).test(file.split(path16.sep).join("/")) : abs === file;
|
|
9644
|
+
};
|
|
9645
|
+
sourceCovers = (kbRoot, sources, entry, ref) => entryCovers(kbRoot, entry, refPath(kbRoot, sources, ref));
|
|
9646
|
+
isGatedRef = (kbRoot, sources, ref) => sources.some((e) => e.review === "required" && sourceCovers(kbRoot, sources, e, ref));
|
|
9617
9647
|
sha256 = (file) => crypto3.createHash("sha256").update(fs15.readFileSync(file)).digest("hex");
|
|
9618
9648
|
}
|
|
9619
9649
|
});
|
|
@@ -9696,7 +9726,6 @@ var init_verify = __esm({
|
|
|
9696
9726
|
|
|
9697
9727
|
// packages/core/dist/knowledge/store.js
|
|
9698
9728
|
import fs16 from "fs";
|
|
9699
|
-
import os8 from "os";
|
|
9700
9729
|
import path17 from "path";
|
|
9701
9730
|
import matter2 from "gray-matter";
|
|
9702
9731
|
function duplicateIdProblem(id, ignored, used) {
|
|
@@ -9757,18 +9786,6 @@ function loadRulesDir(dir, layer, opts = {}) {
|
|
|
9757
9786
|
}
|
|
9758
9787
|
return { rules, errors };
|
|
9759
9788
|
}
|
|
9760
|
-
function resolveSourceRef(ref, kbRoot, sources) {
|
|
9761
|
-
const bases = /* @__PURE__ */ new Set([kbRoot]);
|
|
9762
|
-
for (const s of sources) {
|
|
9763
|
-
let d = path17.resolve(kbRoot, expandHome2(s.path.split(/[*?[{]/)[0]));
|
|
9764
|
-
for (let i = 0; i < 6 && d !== path17.dirname(d); i++) {
|
|
9765
|
-
d = path17.dirname(d);
|
|
9766
|
-
bases.add(d);
|
|
9767
|
-
}
|
|
9768
|
-
}
|
|
9769
|
-
const cands = [path17.resolve(kbRoot, expandHome2(ref)), ...[...bases].map((b) => path17.join(b, ref))];
|
|
9770
|
-
return cands.find((c) => fs16.existsSync(c) && fs16.statSync(c).isFile());
|
|
9771
|
-
}
|
|
9772
9789
|
function validateKb(opts) {
|
|
9773
9790
|
const { rules, errors } = loadRulesDir(opts.rulesDir, "kb", { includeProposed: true });
|
|
9774
9791
|
const checks = [];
|
|
@@ -9788,17 +9805,18 @@ function validateKb(opts) {
|
|
|
9788
9805
|
else
|
|
9789
9806
|
checks.push({ level: "ok", message: "no duplicate ids" });
|
|
9790
9807
|
const cache = /* @__PURE__ */ new Map();
|
|
9808
|
+
const canon = refCanon(opts.kbRoot, opts.sources);
|
|
9791
9809
|
let verified = 0, unresolved = 0, notIngested = 0;
|
|
9792
9810
|
for (const r of rules) {
|
|
9793
9811
|
r.sources.forEach((src, i) => {
|
|
9794
|
-
const file = resolveSourceRef(
|
|
9812
|
+
const file = resolveSourceRef(opts.kbRoot, opts.sources, src.ref);
|
|
9795
9813
|
if (!file) {
|
|
9796
9814
|
unresolved++;
|
|
9797
9815
|
return;
|
|
9798
9816
|
}
|
|
9799
9817
|
const key = `${src.ref}\0${file}`;
|
|
9800
9818
|
if (!cache.has(key)) {
|
|
9801
|
-
const conv = readState2(opts.kbRoot, src.ref) ? convertedFile(opts.kbRoot, src.ref) : null;
|
|
9819
|
+
const conv = readState2(opts.kbRoot, canon(src.ref)) ? convertedFile(opts.kbRoot, canon(src.ref)) : null;
|
|
9802
9820
|
const cached = !!conv && fs16.existsSync(conv);
|
|
9803
9821
|
cache.set(key, {
|
|
9804
9822
|
hay: normalizedViews(fs16.readFileSync(cached ? conv : file, "utf8")),
|
|
@@ -9810,7 +9828,7 @@ function validateKb(opts) {
|
|
|
9810
9828
|
if (span) {
|
|
9811
9829
|
verified++;
|
|
9812
9830
|
const active = r.status === "active" && !path17.relative(opts.rulesDir, r.file).split(path17.sep).includes(PROPOSED_DIR);
|
|
9813
|
-
const err = active ? (opts.errata ?? []).find((e) => e.ref === src.ref && ((o) => !!o && spansOverlap(o, span))(findQuote(hay, e.quote))) : void 0;
|
|
9831
|
+
const err = active ? (opts.errata ?? []).find((e) => canon(e.ref) === canon(src.ref) && ((o) => !!o && spansOverlap(o, span))(findQuote(hay, e.quote))) : void 0;
|
|
9814
9832
|
if (err)
|
|
9815
9833
|
checks.push({ level: "warn", message: `${r.id}: grounded in erratum ${err.id} (${err.reason}); re-check or retire it (${r.file})` });
|
|
9816
9834
|
} else if (convertible)
|
|
@@ -9833,7 +9851,7 @@ function validateKb(opts) {
|
|
|
9833
9851
|
}
|
|
9834
9852
|
return { checks, ok: !checks.some((c) => c.level === "fail") };
|
|
9835
9853
|
}
|
|
9836
|
-
var NO_JS_FRONTMATTER
|
|
9854
|
+
var NO_JS_FRONTMATTER;
|
|
9837
9855
|
var init_store2 = __esm({
|
|
9838
9856
|
"packages/core/dist/knowledge/store.js"() {
|
|
9839
9857
|
init_dist();
|
|
@@ -9845,7 +9863,6 @@ var init_store2 = __esm({
|
|
|
9845
9863
|
throw new Error("only YAML front matter is allowed");
|
|
9846
9864
|
} } }
|
|
9847
9865
|
};
|
|
9848
|
-
expandHome2 = (p) => p === "~" || p.startsWith("~/") ? path17.join(os8.homedir(), p.slice(1)) : p;
|
|
9849
9866
|
}
|
|
9850
9867
|
});
|
|
9851
9868
|
|
|
@@ -13068,7 +13085,7 @@ function removeSource(kbRoot, rulesDir, entryPath, opts = {}) {
|
|
|
13068
13085
|
const res = { dryRun: !!opts.dryRun, entryRemoved: true, stripped: [], stale: [] };
|
|
13069
13086
|
const writes = [];
|
|
13070
13087
|
for (const rule of loadRulesDir(rulesDir, "kb").rules) {
|
|
13071
|
-
const kept = rule.sources.filter((s) => !sourceCovers(kbRoot, entry, s.ref));
|
|
13088
|
+
const kept = rule.sources.filter((s) => !sourceCovers(kbRoot, sources, entry, s.ref));
|
|
13072
13089
|
if (kept.length === rule.sources.length)
|
|
13073
13090
|
continue;
|
|
13074
13091
|
res.stripped.push(rule.id);
|
|
@@ -13189,7 +13206,7 @@ var init_match = __esm({
|
|
|
13189
13206
|
|
|
13190
13207
|
// packages/core/dist/knowledge/audit.js
|
|
13191
13208
|
import fs20 from "fs";
|
|
13192
|
-
import
|
|
13209
|
+
import os8 from "os";
|
|
13193
13210
|
import path21 from "path";
|
|
13194
13211
|
function appendAudit(events, sink = {}) {
|
|
13195
13212
|
if (!events.length)
|
|
@@ -13219,8 +13236,8 @@ var AUDIT_QUERY_CHARS, defaultAuditDir, auditMachineId;
|
|
|
13219
13236
|
var init_audit = __esm({
|
|
13220
13237
|
"packages/core/dist/knowledge/audit.js"() {
|
|
13221
13238
|
AUDIT_QUERY_CHARS = 200;
|
|
13222
|
-
defaultAuditDir = () => process.env.SQUADRANT_AUDIT_DIR || path21.join(
|
|
13223
|
-
auditMachineId = () =>
|
|
13239
|
+
defaultAuditDir = () => process.env.SQUADRANT_AUDIT_DIR || path21.join(os8.homedir(), ".local", "state", "squadrant", "audit");
|
|
13240
|
+
auditMachineId = () => os8.hostname().replace(/[^A-Za-z0-9_-]/g, "_") || "host";
|
|
13224
13241
|
}
|
|
13225
13242
|
});
|
|
13226
13243
|
|
|
@@ -13646,18 +13663,20 @@ function loadErrata(kbRoot) {
|
|
|
13646
13663
|
});
|
|
13647
13664
|
return { errata, errors };
|
|
13648
13665
|
}
|
|
13649
|
-
function orphanedErrata(kbRoot, errata, refs) {
|
|
13650
|
-
const
|
|
13666
|
+
function orphanedErrata(kbRoot, sources, errata, refs) {
|
|
13667
|
+
const canon = refCanon(kbRoot, sources);
|
|
13668
|
+
const only = refs ? new Set([...refs].map(canon)) : void 0;
|
|
13651
13669
|
const hays = /* @__PURE__ */ new Map();
|
|
13652
13670
|
const out = [];
|
|
13653
13671
|
for (const e of errata) {
|
|
13654
|
-
|
|
13672
|
+
const ref = canon(e.ref);
|
|
13673
|
+
if (only && !only.has(ref))
|
|
13655
13674
|
continue;
|
|
13656
|
-
if (!hays.has(
|
|
13657
|
-
const conv = readState2(kbRoot,
|
|
13658
|
-
hays.set(
|
|
13675
|
+
if (!hays.has(ref)) {
|
|
13676
|
+
const conv = readState2(kbRoot, ref) ? convertedFile(kbRoot, ref) : null;
|
|
13677
|
+
hays.set(ref, conv && fs23.existsSync(conv) ? normalizedViews(fs23.readFileSync(conv, "utf8")) : null);
|
|
13659
13678
|
}
|
|
13660
|
-
const hay = hays.get(
|
|
13679
|
+
const hay = hays.get(ref);
|
|
13661
13680
|
if (hay && !findQuote(hay, e.quote))
|
|
13662
13681
|
out.push({ id: e.id, ref: e.ref });
|
|
13663
13682
|
}
|
|
@@ -13674,9 +13693,31 @@ var init_errata = __esm({
|
|
|
13674
13693
|
|
|
13675
13694
|
// packages/core/dist/knowledge/anchor.js
|
|
13676
13695
|
import fs24 from "fs";
|
|
13696
|
+
import { execFileSync as execFileSync7 } from "child_process";
|
|
13677
13697
|
import path25 from "path";
|
|
13678
|
-
function
|
|
13698
|
+
function gitFiles(root) {
|
|
13699
|
+
try {
|
|
13700
|
+
const out = execFileSync7("git", ["ls-files", "-co", "--exclude-standard", "-z"], { cwd: root, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], maxBuffer: 64 * 1024 * 1024 });
|
|
13701
|
+
return out.split("\0").filter(Boolean).sort();
|
|
13702
|
+
} catch {
|
|
13703
|
+
return null;
|
|
13704
|
+
}
|
|
13705
|
+
}
|
|
13706
|
+
function* repoFiles(root, maxFiles) {
|
|
13679
13707
|
let count = 0;
|
|
13708
|
+
const listed = gitFiles(root);
|
|
13709
|
+
if (listed) {
|
|
13710
|
+
for (const rel of listed) {
|
|
13711
|
+
if (!CODE_EXT.has(path25.extname(rel)) || rel.split("/").slice(0, -1).some((d) => SKIP_DIRS.has(d)))
|
|
13712
|
+
continue;
|
|
13713
|
+
if (++count > maxFiles) {
|
|
13714
|
+
console.warn(`anchor: ${root} has more than ${maxFiles} code files; anchors cover only the first ${maxFiles}`);
|
|
13715
|
+
return;
|
|
13716
|
+
}
|
|
13717
|
+
yield path25.join(root, rel);
|
|
13718
|
+
}
|
|
13719
|
+
return;
|
|
13720
|
+
}
|
|
13680
13721
|
const stack = [root];
|
|
13681
13722
|
while (stack.length) {
|
|
13682
13723
|
const dir = stack.pop();
|
|
@@ -13691,48 +13732,60 @@ function* repoFiles(root) {
|
|
|
13691
13732
|
if (!SKIP_DIRS.has(ent.name))
|
|
13692
13733
|
stack.push(path25.join(dir, ent.name));
|
|
13693
13734
|
} else if (ent.isFile() && CODE_EXT.has(path25.extname(ent.name))) {
|
|
13694
|
-
if (++count >
|
|
13735
|
+
if (++count > maxFiles) {
|
|
13736
|
+
console.warn(`anchor: ${root} has more than ${maxFiles} code files; anchors cover only the first ${maxFiles}`);
|
|
13695
13737
|
return;
|
|
13738
|
+
}
|
|
13696
13739
|
yield path25.join(dir, ent.name);
|
|
13697
13740
|
}
|
|
13698
13741
|
}
|
|
13699
13742
|
}
|
|
13700
13743
|
}
|
|
13701
|
-
function
|
|
13702
|
-
const
|
|
13703
|
-
|
|
13704
|
-
return null;
|
|
13705
|
-
const hits = [];
|
|
13706
|
-
for (const file of repoFiles(repoRoot)) {
|
|
13707
|
-
let text;
|
|
13744
|
+
function scanRepo(root, maxFiles) {
|
|
13745
|
+
const out = [];
|
|
13746
|
+
for (const file of repoFiles(root, maxFiles)) {
|
|
13708
13747
|
try {
|
|
13709
13748
|
if (fs24.statSync(file).size > MAX_FILE_BYTES)
|
|
13710
13749
|
continue;
|
|
13711
|
-
text = fs24.readFileSync(file, "utf8");
|
|
13750
|
+
const text = fs24.readFileSync(file, "utf8");
|
|
13751
|
+
const rel = path25.relative(root, file).split(path25.sep).join("/");
|
|
13752
|
+
out.push({ rel, text, hay: `${path25.relative(root, file)}
|
|
13753
|
+
${text}`.toLowerCase() });
|
|
13712
13754
|
} catch {
|
|
13713
13755
|
continue;
|
|
13714
13756
|
}
|
|
13715
|
-
|
|
13716
|
-
|
|
13757
|
+
}
|
|
13758
|
+
return out;
|
|
13759
|
+
}
|
|
13760
|
+
function computeAnchor(repoRoot, triggers, cache, maxFiles = MAX_FILES) {
|
|
13761
|
+
const terms2 = anchorTerms(triggers);
|
|
13762
|
+
if (!terms2.length || !fs24.existsSync(repoRoot))
|
|
13763
|
+
return null;
|
|
13764
|
+
let files = cache?.get(repoRoot);
|
|
13765
|
+
if (!files) {
|
|
13766
|
+
files = scanRepo(repoRoot, maxFiles);
|
|
13767
|
+
cache?.set(repoRoot, files);
|
|
13768
|
+
}
|
|
13769
|
+
const hits = [];
|
|
13770
|
+
for (const { rel, text, hay } of files) {
|
|
13717
13771
|
const score = terms2.filter((t) => hay.includes(t)).length;
|
|
13718
13772
|
if (!score)
|
|
13719
13773
|
continue;
|
|
13720
|
-
|
|
13721
|
-
hits.push({ rel: path25.relative(repoRoot, file).split(path25.sep).join("/"), score, symbols: symbols2 });
|
|
13774
|
+
hits.push({ rel, score, text });
|
|
13722
13775
|
}
|
|
13723
13776
|
if (!hits.length)
|
|
13724
13777
|
return null;
|
|
13725
13778
|
hits.sort((a, b) => b.score - a.score || (a.rel < b.rel ? -1 : 1));
|
|
13726
13779
|
const top = hits.slice(0, MAX_PATHS);
|
|
13727
|
-
const symbols = [...new Set(top.flatMap((h) => h.
|
|
13780
|
+
const symbols = [...new Set(top.flatMap((h) => [...h.text.matchAll(SYMBOL_RE)].map((m) => m[1]).filter((s) => terms2.some((t) => s.toLowerCase().includes(t)))))].sort().slice(0, MAX_SYMBOLS);
|
|
13728
13781
|
return { paths: top.map((h) => h.rel).sort(), ...symbols.length ? { symbols } : {} };
|
|
13729
13782
|
}
|
|
13730
13783
|
var SKIP_DIRS, CODE_EXT, MAX_FILES, MAX_FILE_BYTES, MAX_PATHS, MAX_SYMBOLS, SYMBOL_RE, anchorTerms;
|
|
13731
13784
|
var init_anchor = __esm({
|
|
13732
13785
|
"packages/core/dist/knowledge/anchor.js"() {
|
|
13733
|
-
SKIP_DIRS = /* @__PURE__ */ new Set([".git", "node_modules", "dist", "build", "coverage", ".next", ".worktrees", ".planning", ".converted"]);
|
|
13786
|
+
SKIP_DIRS = /* @__PURE__ */ new Set([".git", "node_modules", "dist", "build", "coverage", ".next", ".worktrees", ".planning", ".converted", ".venv", "venv", "__pycache__"]);
|
|
13734
13787
|
CODE_EXT = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".py", ".go", ".rs", ".java", ".kt", ".swift", ".rb", ".php", ".cs", ".sol", ".sql", ".md"]);
|
|
13735
|
-
MAX_FILES =
|
|
13788
|
+
MAX_FILES = 2e4;
|
|
13736
13789
|
MAX_FILE_BYTES = 256 * 1024;
|
|
13737
13790
|
MAX_PATHS = 5;
|
|
13738
13791
|
MAX_SYMBOLS = 10;
|
|
@@ -13776,8 +13829,8 @@ function validateCandidate(c) {
|
|
|
13776
13829
|
}
|
|
13777
13830
|
return p;
|
|
13778
13831
|
}
|
|
13779
|
-
function upsertSource(fm, src) {
|
|
13780
|
-
const i = fm.sources.findIndex((s) => s.ref === src.ref);
|
|
13832
|
+
function upsertSource(fm, src, canon) {
|
|
13833
|
+
const i = fm.sources.findIndex((s) => canon(s.ref) === canon(src.ref));
|
|
13781
13834
|
if (i < 0) {
|
|
13782
13835
|
fm.sources.push(src);
|
|
13783
13836
|
return true;
|
|
@@ -13801,7 +13854,8 @@ function applyCandidates(input, opts) {
|
|
|
13801
13854
|
const norm = /* @__PURE__ */ new Map();
|
|
13802
13855
|
const totals = /* @__PURE__ */ new Map();
|
|
13803
13856
|
const touched = /* @__PURE__ */ new Set();
|
|
13804
|
-
const
|
|
13857
|
+
const canon = refCanon(kbRoot, opts.sources ?? []);
|
|
13858
|
+
const complete = new Set((input.complete ?? []).map(canon));
|
|
13805
13859
|
for (const cand of input.candidates) {
|
|
13806
13860
|
const problems = validateCandidate(cand);
|
|
13807
13861
|
if (problems.length) {
|
|
@@ -13829,7 +13883,7 @@ function applyCandidates(input, opts) {
|
|
|
13829
13883
|
ev2("item.rejected", cand.id, { reason: "ungrounded" });
|
|
13830
13884
|
continue;
|
|
13831
13885
|
}
|
|
13832
|
-
const hit = (opts.errata ?? []).find((e) => e.ref === cand.source && ((o) => !!o && spansOverlap(o, offset))(findQuote(hay, e.quote)));
|
|
13886
|
+
const hit = (opts.errata ?? []).find((e) => canon(e.ref) === canon(cand.source) && ((o) => !!o && spansOverlap(o, offset))(findQuote(hay, e.quote)));
|
|
13833
13887
|
if (hit) {
|
|
13834
13888
|
tot.total--;
|
|
13835
13889
|
res.rejected.push({ id: cand.id, source: cand.source, reason: `errata:${hit.id}` });
|
|
@@ -13839,7 +13893,7 @@ function applyCandidates(input, opts) {
|
|
|
13839
13893
|
let id = cand.id;
|
|
13840
13894
|
for (const [wid, w] of work) {
|
|
13841
13895
|
const span = (s) => s.sha === st.sha ? s.offset : findQuote(hay, s.quote) ?? s.offset;
|
|
13842
|
-
if (w.fm.sources.some((s) => s.ref === cand.source && s.offset && ((o) => !!o && spansOverlap(o, offset))(span(s)))) {
|
|
13896
|
+
if (w.fm.sources.some((s) => canon(s.ref) === canon(cand.source) && s.offset && ((o) => !!o && spansOverlap(o, offset))(span(s)))) {
|
|
13843
13897
|
id = wid;
|
|
13844
13898
|
break;
|
|
13845
13899
|
}
|
|
@@ -13854,7 +13908,7 @@ function applyCandidates(input, opts) {
|
|
|
13854
13908
|
|
|
13855
13909
|
${cand.rationale.trim()}` : "");
|
|
13856
13910
|
if (target && contradicted.length === 0 && sameMeaning(target, cand)) {
|
|
13857
|
-
let changed = upsertSource(target.fm, src);
|
|
13911
|
+
let changed = upsertSource(target.fm, src, canon);
|
|
13858
13912
|
if (target.fm.status === "stale") {
|
|
13859
13913
|
target.fm.status = "active";
|
|
13860
13914
|
changed = true;
|
|
@@ -13905,7 +13959,7 @@ ${cand.rationale.trim()}` : "");
|
|
|
13905
13959
|
if (!other.startsWith(`${id}@`) || !other.endsWith(".md") || path26.join(dir, other) === file)
|
|
13906
13960
|
continue;
|
|
13907
13961
|
const old = matter4(fs25.readFileSync(path26.join(dir, other), "utf8"));
|
|
13908
|
-
if (!old.data.sources?.some((s) => s.ref === cand.source))
|
|
13962
|
+
if (!old.data.sources?.some((s) => canon(s.ref) === canon(cand.source)))
|
|
13909
13963
|
continue;
|
|
13910
13964
|
fs25.writeFileSync(path26.join(dir, other.replace(/\.md$/, ".superseded")), matter4.stringify(old.content, { ...old.data, supersededBy: path26.basename(file) }));
|
|
13911
13965
|
fs25.rmSync(path26.join(dir, other));
|
|
@@ -13919,18 +13973,19 @@ ${cand.rationale.trim()}` : "");
|
|
|
13919
13973
|
for (const [id, w] of work) {
|
|
13920
13974
|
if (touched.has(id) || w.fm.status !== "active" || w.isNew)
|
|
13921
13975
|
continue;
|
|
13922
|
-
if (w.fm.sources.length && w.fm.sources.every((s) => complete.has(s.ref))) {
|
|
13976
|
+
if (w.fm.sources.length && w.fm.sources.every((s) => complete.has(canon(s.ref)))) {
|
|
13923
13977
|
w.fm.status = "stale";
|
|
13924
13978
|
w.dirty = true;
|
|
13925
13979
|
res.stale.push(id);
|
|
13926
13980
|
}
|
|
13927
13981
|
}
|
|
13982
|
+
const anchorCache = /* @__PURE__ */ new Map();
|
|
13928
13983
|
for (const w of work.values()) {
|
|
13929
13984
|
if (!w.dirty || !opts.projects?.length)
|
|
13930
13985
|
continue;
|
|
13931
13986
|
const anchors = { ...w.fm.anchors ?? {} };
|
|
13932
13987
|
for (const p of opts.projects) {
|
|
13933
|
-
const a = computeAnchor(p.root, w.fm.triggers);
|
|
13988
|
+
const a = computeAnchor(p.root, w.fm.triggers, anchorCache);
|
|
13934
13989
|
if (a)
|
|
13935
13990
|
anchors[p.name] = a;
|
|
13936
13991
|
}
|
|
@@ -13945,7 +14000,7 @@ ${cand.rationale.trim()}` : "");
|
|
|
13945
14000
|
if (!fs25.existsSync(w.file) || fs25.readFileSync(w.file, "utf8") !== text)
|
|
13946
14001
|
fs25.writeFileSync(w.file, text);
|
|
13947
14002
|
}
|
|
13948
|
-
res.orphanedErrata = orphanedErrata(kbRoot, opts.errata ?? [], totals.keys());
|
|
14003
|
+
res.orphanedErrata = orphanedErrata(kbRoot, opts.sources ?? [], opts.errata ?? [], totals.keys());
|
|
13949
14004
|
for (const [ref, t] of totals)
|
|
13950
14005
|
if (needsDocling(t.dropped, t.total))
|
|
13951
14006
|
res.doclingFlags.push({ ref, ...t });
|
|
@@ -14144,7 +14199,7 @@ var init_schedule = __esm({
|
|
|
14144
14199
|
|
|
14145
14200
|
// packages/core/dist/knowledge/review.js
|
|
14146
14201
|
import crypto4 from "crypto";
|
|
14147
|
-
import { execFileSync as
|
|
14202
|
+
import { execFileSync as execFileSync8 } from "child_process";
|
|
14148
14203
|
import fs27 from "fs";
|
|
14149
14204
|
import path28 from "path";
|
|
14150
14205
|
import matter5 from "gray-matter";
|
|
@@ -14174,11 +14229,7 @@ function priorityOfRef(c, ref) {
|
|
|
14174
14229
|
if (ref.startsWith("agent:"))
|
|
14175
14230
|
return "agent";
|
|
14176
14231
|
const root = kbDir(c.cfg, c.kb);
|
|
14177
|
-
|
|
14178
|
-
for (const f of expandSource(root, e))
|
|
14179
|
-
if (refFor(root, f) === ref)
|
|
14180
|
-
return e.priority;
|
|
14181
|
-
return "project";
|
|
14232
|
+
return c.sources.find((e) => sourceCovers(root, c.sources, e, ref))?.priority ?? "project";
|
|
14182
14233
|
}
|
|
14183
14234
|
function priorityOfRule(c, r) {
|
|
14184
14235
|
return r.sources.map((s) => priorityOfRef(c, s.ref)).sort((a, b) => PRIORITY_RANK[b] - PRIORITY_RANK[a])[0] ?? "project";
|
|
@@ -14215,7 +14266,7 @@ function reindex(c) {
|
|
|
14215
14266
|
function anchorsFor(c, fm) {
|
|
14216
14267
|
const anchors = { ...fm.anchors ?? {} };
|
|
14217
14268
|
for (const p of c.projects ?? []) {
|
|
14218
|
-
const a = computeAnchor(p.root, fm.triggers);
|
|
14269
|
+
const a = computeAnchor(p.root, fm.triggers, c.anchorCache);
|
|
14219
14270
|
if (a)
|
|
14220
14271
|
anchors[p.name] = a;
|
|
14221
14272
|
}
|
|
@@ -14258,8 +14309,9 @@ function mergeInto(c, p, targetId, live, events) {
|
|
|
14258
14309
|
if (!t)
|
|
14259
14310
|
return false;
|
|
14260
14311
|
const tf = readFm(t.file);
|
|
14312
|
+
const canon = refCanon(kbDir(c.cfg, c.kb), c.sources);
|
|
14261
14313
|
for (const s of p.rule.sources)
|
|
14262
|
-
if (!tf.fm.sources.some((x) => x.ref === s.ref))
|
|
14314
|
+
if (!tf.fm.sources.some((x) => canon(x.ref) === canon(s.ref)))
|
|
14263
14315
|
tf.fm.sources.push(s);
|
|
14264
14316
|
fs27.writeFileSync(t.file, fileText(tf.fm, tf.body));
|
|
14265
14317
|
fs27.rmSync(p.rule.file);
|
|
@@ -14272,7 +14324,7 @@ function evaluateCodeConflict(c, rule, cc) {
|
|
|
14272
14324
|
const root = proj?.root;
|
|
14273
14325
|
const code = root ? g.lastCommit(root, cc.files) : null;
|
|
14274
14326
|
const kbRoot = kbDir(c.cfg, c.kb);
|
|
14275
|
-
const docDates = rule.sources.map((s) => g.docDate(
|
|
14327
|
+
const docDates = rule.sources.map((s) => g.docDate(refPath(kbRoot, c.sources, s.ref))).filter((d2) => !!d2).sort();
|
|
14276
14328
|
const docDate = docDates[docDates.length - 1];
|
|
14277
14329
|
const docRev = docRevOf(rule);
|
|
14278
14330
|
const evidence = { docRev, codeRev: code?.rev ?? "unknown", files: cc.files, project: cc.project };
|
|
@@ -14294,6 +14346,7 @@ function evaluateCodeConflict(c, rule, cc) {
|
|
|
14294
14346
|
};
|
|
14295
14347
|
}
|
|
14296
14348
|
function applyDecisions(file, c) {
|
|
14349
|
+
c = { ...c, anchorCache: /* @__PURE__ */ new Map() };
|
|
14297
14350
|
const now = nowOf(c);
|
|
14298
14351
|
const kbRoot = kbDir(c.cfg, c.kb);
|
|
14299
14352
|
const threshold = reconcileConfig(c.cfg, c.kb).autoApproveConfidence;
|
|
@@ -14447,8 +14500,9 @@ function applyPair(pd, c, res, threshold, events, kbRoot, now) {
|
|
|
14447
14500
|
return;
|
|
14448
14501
|
}
|
|
14449
14502
|
const kf = readFm(keep.file);
|
|
14503
|
+
const canon = refCanon(kbRoot, c.sources);
|
|
14450
14504
|
for (const s of drop.sources)
|
|
14451
|
-
if (!kf.fm.sources.some((x) => x.ref === s.ref))
|
|
14505
|
+
if (!kf.fm.sources.some((x) => canon(x.ref) === canon(s.ref)))
|
|
14452
14506
|
kf.fm.sources.push(s);
|
|
14453
14507
|
kf.fm.supersedes = [.../* @__PURE__ */ new Set([...kf.fm.supersedes ?? [], drop.id])];
|
|
14454
14508
|
fs27.writeFileSync(keep.file, fileText(kf.fm, kf.body));
|
|
@@ -14594,7 +14648,7 @@ var init_review = __esm({
|
|
|
14594
14648
|
escalationsFile = (kbRoot) => path28.join(kbRoot, "escalations.json");
|
|
14595
14649
|
verdictsFile = (kbRoot) => path28.join(kbRoot, "verdicts.jsonl");
|
|
14596
14650
|
needsYouCount = (kbRoot) => readEscalations(kbRoot).filter((e) => e.needsYou).length;
|
|
14597
|
-
git = (root, args) =>
|
|
14651
|
+
git = (root, args) => execFileSync8("git", ["-C", root, ...args], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
14598
14652
|
realGit = {
|
|
14599
14653
|
lastCommit(root, files) {
|
|
14600
14654
|
try {
|
|
@@ -15033,7 +15087,7 @@ function renderReport(cfg, kb, o) {
|
|
|
15033
15087
|
if (info.length)
|
|
15034
15088
|
L.push("", `## For information (${info.length})`, "", ...info.map((e) => `- **${e.key}**: ${e.explanation}`));
|
|
15035
15089
|
const { errata, errors: errataErrors } = loadErrata(kbDir(cfg, kb));
|
|
15036
|
-
const orphans = orphanedErrata(kbDir(cfg, kb), errata);
|
|
15090
|
+
const orphans = orphanedErrata(kbDir(cfg, kb), loadSources(kbDir(cfg, kb)).sources, errata);
|
|
15037
15091
|
if (orphans.length || errataErrors.length) {
|
|
15038
15092
|
L.push("", `## Errata to re-check (${orphans.length + errataErrors.length})`, "", ...orphans.map((e) => `- **${e.id}** (${e.ref}): quote no longer found in the source; the raw file changed. Re-check it in errata.yaml.`), ...errataErrors.map((e) => `- errata.yaml: ${e}`));
|
|
15039
15093
|
}
|
|
@@ -15055,6 +15109,7 @@ var init_report = __esm({
|
|
|
15055
15109
|
init_errata();
|
|
15056
15110
|
init_layers();
|
|
15057
15111
|
init_paths();
|
|
15112
|
+
init_sources();
|
|
15058
15113
|
init_review();
|
|
15059
15114
|
init_scores();
|
|
15060
15115
|
}
|
|
@@ -15390,7 +15445,6 @@ __export(dist_exports, {
|
|
|
15390
15445
|
extractToolPayload: () => extractToolPayload,
|
|
15391
15446
|
extractUserIntentFromTranscript: () => extractUserIntentFromTranscript,
|
|
15392
15447
|
fallsBackToPane: () => fallsBackToPane,
|
|
15393
|
-
fileForRef: () => fileForRef,
|
|
15394
15448
|
findCrewPane: () => findCrewPane,
|
|
15395
15449
|
findLegacyKbs: () => findLegacyKbs,
|
|
15396
15450
|
findLegacyOverlays: () => findLegacyOverlays,
|
|
@@ -15532,7 +15586,10 @@ __export(dist_exports, {
|
|
|
15532
15586
|
recoverStall: () => recoverStall,
|
|
15533
15587
|
reduce: () => reduce,
|
|
15534
15588
|
reduceLifecycle: () => reduceLifecycle,
|
|
15589
|
+
refCandidates: () => refCandidates,
|
|
15590
|
+
refCanon: () => refCanon,
|
|
15535
15591
|
refFor: () => refFor,
|
|
15592
|
+
refPath: () => refPath,
|
|
15536
15593
|
releaseDaemonLock: () => releaseDaemonLock,
|
|
15537
15594
|
removeRunningMarker: () => removeRunningMarker,
|
|
15538
15595
|
removeSource: () => removeSource,
|
|
@@ -15565,6 +15622,7 @@ __export(dist_exports, {
|
|
|
15565
15622
|
resolveSetupGroup: () => resolveSetupGroup,
|
|
15566
15623
|
resolveSetupToken: () => resolveSetupToken,
|
|
15567
15624
|
resolveSetupUserId: () => resolveSetupUserId,
|
|
15625
|
+
resolveSourceRef: () => resolveSourceRef,
|
|
15568
15626
|
restartDaemonIfRunning: () => restartDaemonIfRunning,
|
|
15569
15627
|
rotateIfNeeded: () => rotateIfNeeded,
|
|
15570
15628
|
ruleAuditScope: () => ruleAuditScope,
|
|
@@ -15832,31 +15890,31 @@ import path32 from "path";
|
|
|
15832
15890
|
// packages/agents/dist/projection/cursor.js
|
|
15833
15891
|
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
15834
15892
|
import path33 from "path";
|
|
15835
|
-
import
|
|
15893
|
+
import os9 from "os";
|
|
15836
15894
|
|
|
15837
15895
|
// packages/agents/dist/projection/codex.js
|
|
15838
15896
|
import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
15839
15897
|
import path34 from "path";
|
|
15840
|
-
import
|
|
15898
|
+
import os10 from "os";
|
|
15841
15899
|
|
|
15842
15900
|
// packages/agents/dist/projection/gemini.js
|
|
15843
15901
|
import { mkdir as mkdir3, readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
|
|
15844
15902
|
import path35 from "path";
|
|
15845
|
-
import
|
|
15903
|
+
import os11 from "os";
|
|
15846
15904
|
|
|
15847
15905
|
// packages/agents/dist/projection/opencode.js
|
|
15848
15906
|
import { mkdir as mkdir4, readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
|
|
15849
15907
|
import path36 from "path";
|
|
15850
|
-
import
|
|
15908
|
+
import os12 from "os";
|
|
15851
15909
|
|
|
15852
15910
|
// packages/agents/dist/projection/opencode-skills.js
|
|
15853
15911
|
import fs33 from "fs";
|
|
15854
|
-
import
|
|
15912
|
+
import os13 from "os";
|
|
15855
15913
|
import path37 from "path";
|
|
15856
15914
|
var OPENCODE_SKILL_MARKER = ".squadrant-managed";
|
|
15857
15915
|
var MARKER_BODY = "squadrant\n";
|
|
15858
15916
|
function defaultOpencodeSkillsRoot(env = process.env) {
|
|
15859
|
-
const configHome = env.XDG_CONFIG_HOME || path37.join(
|
|
15917
|
+
const configHome = env.XDG_CONFIG_HOME || path37.join(os13.homedir(), ".config");
|
|
15860
15918
|
return path37.join(configHome, "opencode", "skills");
|
|
15861
15919
|
}
|
|
15862
15920
|
var SAFE_NAME = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
@@ -15944,7 +16002,7 @@ function syncShippedOpencodeSkills(opts) {
|
|
|
15944
16002
|
// packages/agents/dist/projection/claude.js
|
|
15945
16003
|
import { mkdir as mkdir5, readFile as readFile5, writeFile as writeFile5 } from "fs/promises";
|
|
15946
16004
|
import path38 from "path";
|
|
15947
|
-
import
|
|
16005
|
+
import os14 from "os";
|
|
15948
16006
|
|
|
15949
16007
|
// packages/agents/dist/codex/app-server-client.js
|
|
15950
16008
|
import { EventEmitter } from "events";
|
|
@@ -17289,7 +17347,7 @@ var ClaudeReceiptListener = class {
|
|
|
17289
17347
|
|
|
17290
17348
|
// packages/agents/dist/claude/api-key-approval.js
|
|
17291
17349
|
import fs34 from "fs";
|
|
17292
|
-
import
|
|
17350
|
+
import os15 from "os";
|
|
17293
17351
|
import path39 from "path";
|
|
17294
17352
|
|
|
17295
17353
|
// packages/agents/dist/opencode/http-channel.js
|
|
@@ -17460,7 +17518,7 @@ function createOpencodeFactAdapter(deps) {
|
|
|
17460
17518
|
|
|
17461
17519
|
// packages/agents/dist/rules-hooks/install.js
|
|
17462
17520
|
import fs35 from "fs";
|
|
17463
|
-
import
|
|
17521
|
+
import os16 from "os";
|
|
17464
17522
|
import path40 from "path";
|
|
17465
17523
|
|
|
17466
17524
|
// packages/workspaces/dist/runtimes/cmux.js
|
|
@@ -17469,7 +17527,7 @@ init_dist();
|
|
|
17469
17527
|
init_dist();
|
|
17470
17528
|
init_dist2();
|
|
17471
17529
|
init_dist2();
|
|
17472
|
-
import { execFile as execFile3, execFileSync as
|
|
17530
|
+
import { execFile as execFile3, execFileSync as execFileSync9 } from "child_process";
|
|
17473
17531
|
var CMUX_TIMEOUT = 15e3;
|
|
17474
17532
|
var CmuxTimeoutError = class extends Error {
|
|
17475
17533
|
constructor(cmd) {
|
|
@@ -18143,7 +18201,7 @@ var RuntimeRegistry = class {
|
|
|
18143
18201
|
|
|
18144
18202
|
// packages/workspaces/dist/notifiers/cmux.js
|
|
18145
18203
|
init_dist();
|
|
18146
|
-
import { execFile as execFileCb, execFileSync as
|
|
18204
|
+
import { execFile as execFileCb, execFileSync as execFileSync10 } from "child_process";
|
|
18147
18205
|
import { promisify as promisify3 } from "util";
|
|
18148
18206
|
var execFile4 = promisify3(execFileCb);
|
|
18149
18207
|
function createCmuxNotifier(_scope) {
|
|
@@ -18151,7 +18209,7 @@ function createCmuxNotifier(_scope) {
|
|
|
18151
18209
|
name: "cmux",
|
|
18152
18210
|
async probe() {
|
|
18153
18211
|
try {
|
|
18154
|
-
|
|
18212
|
+
execFileSync10(resolveCmuxBin(), ["capabilities"], { encoding: "utf-8", stdio: "pipe", timeout: CMUX_TIMEOUT });
|
|
18155
18213
|
return { installed: true, reachable: true };
|
|
18156
18214
|
} catch (err) {
|
|
18157
18215
|
const code = err.code;
|
|
@@ -18361,9 +18419,9 @@ import { homedir as homedir11 } from "os";
|
|
|
18361
18419
|
// packages/workspaces/dist/cmux-daemon/store-fingerprint.js
|
|
18362
18420
|
init_dist();
|
|
18363
18421
|
init_dist2();
|
|
18364
|
-
import { execFileSync as
|
|
18422
|
+
import { execFileSync as execFileSync11 } from "child_process";
|
|
18365
18423
|
function defaultExecPs(pid) {
|
|
18366
|
-
return
|
|
18424
|
+
return execFileSync11("ps", ["-o", "command=", "-p", String(pid)], {
|
|
18367
18425
|
encoding: "utf-8",
|
|
18368
18426
|
stdio: ["ignore", "pipe", "ignore"]
|
|
18369
18427
|
});
|