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/index.js
CHANGED
|
@@ -10428,10 +10428,34 @@ function expandSource(kbRoot, entry) {
|
|
|
10428
10428
|
const re = globToRegExp(abs.split(path16.sep).join("/"));
|
|
10429
10429
|
return walkFiles(root).filter((f) => re.test(f.split(path16.sep).join("/"))).sort();
|
|
10430
10430
|
}
|
|
10431
|
-
function
|
|
10432
|
-
const
|
|
10433
|
-
|
|
10434
|
-
|
|
10431
|
+
function refCandidates(kbRoot, sources, ref) {
|
|
10432
|
+
const asIs = path16.resolve(kbRoot, expandHome(ref));
|
|
10433
|
+
if (path16.isAbsolute(expandHome(ref)))
|
|
10434
|
+
return [asIs];
|
|
10435
|
+
const bases = /* @__PURE__ */ new Set([kbRoot]);
|
|
10436
|
+
for (const s of sources) {
|
|
10437
|
+
let d = path16.resolve(kbRoot, expandHome(s.path.split(/[*?[{]/)[0]));
|
|
10438
|
+
for (let i = 0; i < 6 && d !== path16.dirname(d); i++) {
|
|
10439
|
+
d = path16.dirname(d);
|
|
10440
|
+
bases.add(d);
|
|
10441
|
+
}
|
|
10442
|
+
}
|
|
10443
|
+
return [.../* @__PURE__ */ new Set([asIs, ...[...bases].map((b) => path16.join(b, ref))])];
|
|
10444
|
+
}
|
|
10445
|
+
function refPath(kbRoot, sources, ref) {
|
|
10446
|
+
const cands = refCandidates(kbRoot, sources, ref);
|
|
10447
|
+
return cands.find(isFile) ?? cands.find((f) => sources.some((e) => entryCovers(kbRoot, e, f))) ?? cands[0];
|
|
10448
|
+
}
|
|
10449
|
+
function refCanon(kbRoot, sources) {
|
|
10450
|
+
const memo = /* @__PURE__ */ new Map();
|
|
10451
|
+
return (ref) => {
|
|
10452
|
+
let c = memo.get(ref);
|
|
10453
|
+
if (c === void 0) {
|
|
10454
|
+
c = refFor(kbRoot, refPath(kbRoot, sources, ref));
|
|
10455
|
+
memo.set(ref, c);
|
|
10456
|
+
}
|
|
10457
|
+
return c;
|
|
10458
|
+
};
|
|
10435
10459
|
}
|
|
10436
10460
|
function detectChange(kbRoot, file) {
|
|
10437
10461
|
const ref = refFor(kbRoot, file);
|
|
@@ -10529,7 +10553,7 @@ async function planIngest(kbRoot, opts) {
|
|
|
10529
10553
|
}
|
|
10530
10554
|
return plan;
|
|
10531
10555
|
}
|
|
10532
|
-
var execFileAsync, CONVERTED_DIR, DEFAULT_MAX_SECTIONS_PER_PASS, CHARS_PER_TOKEN, PASS_THROUGH, SECTION_TARGET_CHARS, markitdownConverter, expandHome,
|
|
10556
|
+
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;
|
|
10533
10557
|
var init_ingest = __esm({
|
|
10534
10558
|
"packages/core/dist/knowledge/ingest.js"() {
|
|
10535
10559
|
execFileAsync = promisify2(execFile2);
|
|
@@ -10543,11 +10567,17 @@ var init_ingest = __esm({
|
|
|
10543
10567
|
return stdout;
|
|
10544
10568
|
};
|
|
10545
10569
|
expandHome = (p) => p === "~" || p.startsWith("~/") ? path16.join(os7.homedir(), p.slice(1)) : p;
|
|
10546
|
-
fileForRef = (kbRoot, ref) => path16.resolve(kbRoot, expandHome(ref));
|
|
10547
10570
|
cacheKey = (ref) => `${ref.replace(/[^A-Za-z0-9._-]+/g, "_")}.${crypto3.createHash("sha1").update(ref).digest("hex").slice(0, 6)}`;
|
|
10548
10571
|
convertedFile = (kbRoot, ref) => path16.join(kbRoot, CONVERTED_DIR, `${cacheKey(ref)}.md`);
|
|
10549
10572
|
stampFile = (kbRoot, ref) => path16.join(kbRoot, CONVERTED_DIR, `${cacheKey(ref)}.sha`);
|
|
10550
|
-
|
|
10573
|
+
isFile = (f) => fs15.existsSync(f) && fs15.statSync(f).isFile();
|
|
10574
|
+
resolveSourceRef = (kbRoot, sources, ref) => refCandidates(kbRoot, sources, ref).find(isFile);
|
|
10575
|
+
entryCovers = (kbRoot, entry, file) => {
|
|
10576
|
+
const abs = path16.resolve(kbRoot, expandHome(entry.path));
|
|
10577
|
+
return /[*?]/.test(entry.path) ? globToRegExp(abs.split(path16.sep).join("/")).test(file.split(path16.sep).join("/")) : abs === file;
|
|
10578
|
+
};
|
|
10579
|
+
sourceCovers = (kbRoot, sources, entry, ref) => entryCovers(kbRoot, entry, refPath(kbRoot, sources, ref));
|
|
10580
|
+
isGatedRef = (kbRoot, sources, ref) => sources.some((e) => e.review === "required" && sourceCovers(kbRoot, sources, e, ref));
|
|
10551
10581
|
sha256 = (file) => crypto3.createHash("sha256").update(fs15.readFileSync(file)).digest("hex");
|
|
10552
10582
|
}
|
|
10553
10583
|
});
|
|
@@ -10630,7 +10660,6 @@ var init_verify = __esm({
|
|
|
10630
10660
|
|
|
10631
10661
|
// packages/core/dist/knowledge/store.js
|
|
10632
10662
|
import fs16 from "fs";
|
|
10633
|
-
import os8 from "os";
|
|
10634
10663
|
import path17 from "path";
|
|
10635
10664
|
import matter2 from "gray-matter";
|
|
10636
10665
|
function duplicateIdProblem(id, ignored, used) {
|
|
@@ -10691,18 +10720,6 @@ function loadRulesDir(dir, layer, opts = {}) {
|
|
|
10691
10720
|
}
|
|
10692
10721
|
return { rules, errors };
|
|
10693
10722
|
}
|
|
10694
|
-
function resolveSourceRef(ref, kbRoot, sources) {
|
|
10695
|
-
const bases = /* @__PURE__ */ new Set([kbRoot]);
|
|
10696
|
-
for (const s of sources) {
|
|
10697
|
-
let d = path17.resolve(kbRoot, expandHome2(s.path.split(/[*?[{]/)[0]));
|
|
10698
|
-
for (let i = 0; i < 6 && d !== path17.dirname(d); i++) {
|
|
10699
|
-
d = path17.dirname(d);
|
|
10700
|
-
bases.add(d);
|
|
10701
|
-
}
|
|
10702
|
-
}
|
|
10703
|
-
const cands = [path17.resolve(kbRoot, expandHome2(ref)), ...[...bases].map((b) => path17.join(b, ref))];
|
|
10704
|
-
return cands.find((c) => fs16.existsSync(c) && fs16.statSync(c).isFile());
|
|
10705
|
-
}
|
|
10706
10723
|
function validateKb(opts) {
|
|
10707
10724
|
const { rules, errors } = loadRulesDir(opts.rulesDir, "kb", { includeProposed: true });
|
|
10708
10725
|
const checks = [];
|
|
@@ -10722,17 +10739,18 @@ function validateKb(opts) {
|
|
|
10722
10739
|
else
|
|
10723
10740
|
checks.push({ level: "ok", message: "no duplicate ids" });
|
|
10724
10741
|
const cache = /* @__PURE__ */ new Map();
|
|
10742
|
+
const canon = refCanon(opts.kbRoot, opts.sources);
|
|
10725
10743
|
let verified = 0, unresolved = 0, notIngested = 0;
|
|
10726
10744
|
for (const r of rules) {
|
|
10727
10745
|
r.sources.forEach((src, i) => {
|
|
10728
|
-
const file = resolveSourceRef(
|
|
10746
|
+
const file = resolveSourceRef(opts.kbRoot, opts.sources, src.ref);
|
|
10729
10747
|
if (!file) {
|
|
10730
10748
|
unresolved++;
|
|
10731
10749
|
return;
|
|
10732
10750
|
}
|
|
10733
10751
|
const key = `${src.ref}\0${file}`;
|
|
10734
10752
|
if (!cache.has(key)) {
|
|
10735
|
-
const conv = readState2(opts.kbRoot, src.ref) ? convertedFile(opts.kbRoot, src.ref) : null;
|
|
10753
|
+
const conv = readState2(opts.kbRoot, canon(src.ref)) ? convertedFile(opts.kbRoot, canon(src.ref)) : null;
|
|
10736
10754
|
const cached = !!conv && fs16.existsSync(conv);
|
|
10737
10755
|
cache.set(key, {
|
|
10738
10756
|
hay: normalizedViews(fs16.readFileSync(cached ? conv : file, "utf8")),
|
|
@@ -10744,7 +10762,7 @@ function validateKb(opts) {
|
|
|
10744
10762
|
if (span) {
|
|
10745
10763
|
verified++;
|
|
10746
10764
|
const active = r.status === "active" && !path17.relative(opts.rulesDir, r.file).split(path17.sep).includes(PROPOSED_DIR);
|
|
10747
|
-
const err = active ? (opts.errata ?? []).find((e) => e.ref === src.ref && ((o) => !!o && spansOverlap(o, span))(findQuote(hay, e.quote))) : void 0;
|
|
10765
|
+
const err = active ? (opts.errata ?? []).find((e) => canon(e.ref) === canon(src.ref) && ((o) => !!o && spansOverlap(o, span))(findQuote(hay, e.quote))) : void 0;
|
|
10748
10766
|
if (err)
|
|
10749
10767
|
checks.push({ level: "warn", message: `${r.id}: grounded in erratum ${err.id} (${err.reason}); re-check or retire it (${r.file})` });
|
|
10750
10768
|
} else if (convertible)
|
|
@@ -10767,7 +10785,7 @@ function validateKb(opts) {
|
|
|
10767
10785
|
}
|
|
10768
10786
|
return { checks, ok: !checks.some((c) => c.level === "fail") };
|
|
10769
10787
|
}
|
|
10770
|
-
var NO_JS_FRONTMATTER
|
|
10788
|
+
var NO_JS_FRONTMATTER;
|
|
10771
10789
|
var init_store2 = __esm({
|
|
10772
10790
|
"packages/core/dist/knowledge/store.js"() {
|
|
10773
10791
|
init_dist();
|
|
@@ -10779,7 +10797,6 @@ var init_store2 = __esm({
|
|
|
10779
10797
|
throw new Error("only YAML front matter is allowed");
|
|
10780
10798
|
} } }
|
|
10781
10799
|
};
|
|
10782
|
-
expandHome2 = (p) => p === "~" || p.startsWith("~/") ? path17.join(os8.homedir(), p.slice(1)) : p;
|
|
10783
10800
|
}
|
|
10784
10801
|
});
|
|
10785
10802
|
|
|
@@ -14002,7 +14019,7 @@ function removeSource(kbRoot, rulesDir, entryPath, opts = {}) {
|
|
|
14002
14019
|
const res = { dryRun: !!opts.dryRun, entryRemoved: true, stripped: [], stale: [] };
|
|
14003
14020
|
const writes = [];
|
|
14004
14021
|
for (const rule2 of loadRulesDir(rulesDir, "kb").rules) {
|
|
14005
|
-
const kept = rule2.sources.filter((s) => !sourceCovers(kbRoot, entry, s.ref));
|
|
14022
|
+
const kept = rule2.sources.filter((s) => !sourceCovers(kbRoot, sources, entry, s.ref));
|
|
14006
14023
|
if (kept.length === rule2.sources.length)
|
|
14007
14024
|
continue;
|
|
14008
14025
|
res.stripped.push(rule2.id);
|
|
@@ -14123,7 +14140,7 @@ var init_match = __esm({
|
|
|
14123
14140
|
|
|
14124
14141
|
// packages/core/dist/knowledge/audit.js
|
|
14125
14142
|
import fs20 from "fs";
|
|
14126
|
-
import
|
|
14143
|
+
import os8 from "os";
|
|
14127
14144
|
import path21 from "path";
|
|
14128
14145
|
function appendAudit(events, sink = {}) {
|
|
14129
14146
|
if (!events.length)
|
|
@@ -14153,8 +14170,8 @@ var AUDIT_QUERY_CHARS, defaultAuditDir, auditMachineId;
|
|
|
14153
14170
|
var init_audit = __esm({
|
|
14154
14171
|
"packages/core/dist/knowledge/audit.js"() {
|
|
14155
14172
|
AUDIT_QUERY_CHARS = 200;
|
|
14156
|
-
defaultAuditDir = () => process.env.SQUADRANT_AUDIT_DIR || path21.join(
|
|
14157
|
-
auditMachineId = () =>
|
|
14173
|
+
defaultAuditDir = () => process.env.SQUADRANT_AUDIT_DIR || path21.join(os8.homedir(), ".local", "state", "squadrant", "audit");
|
|
14174
|
+
auditMachineId = () => os8.hostname().replace(/[^A-Za-z0-9_-]/g, "_") || "host";
|
|
14158
14175
|
}
|
|
14159
14176
|
});
|
|
14160
14177
|
|
|
@@ -14580,18 +14597,20 @@ function loadErrata(kbRoot) {
|
|
|
14580
14597
|
});
|
|
14581
14598
|
return { errata, errors };
|
|
14582
14599
|
}
|
|
14583
|
-
function orphanedErrata(kbRoot, errata, refs) {
|
|
14584
|
-
const
|
|
14600
|
+
function orphanedErrata(kbRoot, sources, errata, refs) {
|
|
14601
|
+
const canon = refCanon(kbRoot, sources);
|
|
14602
|
+
const only = refs ? new Set([...refs].map(canon)) : void 0;
|
|
14585
14603
|
const hays = /* @__PURE__ */ new Map();
|
|
14586
14604
|
const out = [];
|
|
14587
14605
|
for (const e of errata) {
|
|
14588
|
-
|
|
14606
|
+
const ref = canon(e.ref);
|
|
14607
|
+
if (only && !only.has(ref))
|
|
14589
14608
|
continue;
|
|
14590
|
-
if (!hays.has(
|
|
14591
|
-
const conv = readState2(kbRoot,
|
|
14592
|
-
hays.set(
|
|
14609
|
+
if (!hays.has(ref)) {
|
|
14610
|
+
const conv = readState2(kbRoot, ref) ? convertedFile(kbRoot, ref) : null;
|
|
14611
|
+
hays.set(ref, conv && fs23.existsSync(conv) ? normalizedViews(fs23.readFileSync(conv, "utf8")) : null);
|
|
14593
14612
|
}
|
|
14594
|
-
const hay = hays.get(
|
|
14613
|
+
const hay = hays.get(ref);
|
|
14595
14614
|
if (hay && !findQuote(hay, e.quote))
|
|
14596
14615
|
out.push({ id: e.id, ref: e.ref });
|
|
14597
14616
|
}
|
|
@@ -14608,9 +14627,31 @@ var init_errata = __esm({
|
|
|
14608
14627
|
|
|
14609
14628
|
// packages/core/dist/knowledge/anchor.js
|
|
14610
14629
|
import fs24 from "fs";
|
|
14630
|
+
import { execFileSync as execFileSync7 } from "child_process";
|
|
14611
14631
|
import path25 from "path";
|
|
14612
|
-
function
|
|
14632
|
+
function gitFiles(root) {
|
|
14633
|
+
try {
|
|
14634
|
+
const out = execFileSync7("git", ["ls-files", "-co", "--exclude-standard", "-z"], { cwd: root, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], maxBuffer: 64 * 1024 * 1024 });
|
|
14635
|
+
return out.split("\0").filter(Boolean).sort();
|
|
14636
|
+
} catch {
|
|
14637
|
+
return null;
|
|
14638
|
+
}
|
|
14639
|
+
}
|
|
14640
|
+
function* repoFiles(root, maxFiles) {
|
|
14613
14641
|
let count = 0;
|
|
14642
|
+
const listed = gitFiles(root);
|
|
14643
|
+
if (listed) {
|
|
14644
|
+
for (const rel of listed) {
|
|
14645
|
+
if (!CODE_EXT.has(path25.extname(rel)) || rel.split("/").slice(0, -1).some((d) => SKIP_DIRS.has(d)))
|
|
14646
|
+
continue;
|
|
14647
|
+
if (++count > maxFiles) {
|
|
14648
|
+
console.warn(`anchor: ${root} has more than ${maxFiles} code files; anchors cover only the first ${maxFiles}`);
|
|
14649
|
+
return;
|
|
14650
|
+
}
|
|
14651
|
+
yield path25.join(root, rel);
|
|
14652
|
+
}
|
|
14653
|
+
return;
|
|
14654
|
+
}
|
|
14614
14655
|
const stack = [root];
|
|
14615
14656
|
while (stack.length) {
|
|
14616
14657
|
const dir = stack.pop();
|
|
@@ -14625,48 +14666,60 @@ function* repoFiles(root) {
|
|
|
14625
14666
|
if (!SKIP_DIRS.has(ent.name))
|
|
14626
14667
|
stack.push(path25.join(dir, ent.name));
|
|
14627
14668
|
} else if (ent.isFile() && CODE_EXT.has(path25.extname(ent.name))) {
|
|
14628
|
-
if (++count >
|
|
14669
|
+
if (++count > maxFiles) {
|
|
14670
|
+
console.warn(`anchor: ${root} has more than ${maxFiles} code files; anchors cover only the first ${maxFiles}`);
|
|
14629
14671
|
return;
|
|
14672
|
+
}
|
|
14630
14673
|
yield path25.join(dir, ent.name);
|
|
14631
14674
|
}
|
|
14632
14675
|
}
|
|
14633
14676
|
}
|
|
14634
14677
|
}
|
|
14635
|
-
function
|
|
14636
|
-
const
|
|
14637
|
-
|
|
14638
|
-
return null;
|
|
14639
|
-
const hits = [];
|
|
14640
|
-
for (const file of repoFiles(repoRoot)) {
|
|
14641
|
-
let text;
|
|
14678
|
+
function scanRepo(root, maxFiles) {
|
|
14679
|
+
const out = [];
|
|
14680
|
+
for (const file of repoFiles(root, maxFiles)) {
|
|
14642
14681
|
try {
|
|
14643
14682
|
if (fs24.statSync(file).size > MAX_FILE_BYTES)
|
|
14644
14683
|
continue;
|
|
14645
|
-
text = fs24.readFileSync(file, "utf8");
|
|
14684
|
+
const text = fs24.readFileSync(file, "utf8");
|
|
14685
|
+
const rel = path25.relative(root, file).split(path25.sep).join("/");
|
|
14686
|
+
out.push({ rel, text, hay: `${path25.relative(root, file)}
|
|
14687
|
+
${text}`.toLowerCase() });
|
|
14646
14688
|
} catch {
|
|
14647
14689
|
continue;
|
|
14648
14690
|
}
|
|
14649
|
-
|
|
14650
|
-
|
|
14691
|
+
}
|
|
14692
|
+
return out;
|
|
14693
|
+
}
|
|
14694
|
+
function computeAnchor(repoRoot, triggers, cache, maxFiles = MAX_FILES) {
|
|
14695
|
+
const terms2 = anchorTerms(triggers);
|
|
14696
|
+
if (!terms2.length || !fs24.existsSync(repoRoot))
|
|
14697
|
+
return null;
|
|
14698
|
+
let files = cache?.get(repoRoot);
|
|
14699
|
+
if (!files) {
|
|
14700
|
+
files = scanRepo(repoRoot, maxFiles);
|
|
14701
|
+
cache?.set(repoRoot, files);
|
|
14702
|
+
}
|
|
14703
|
+
const hits = [];
|
|
14704
|
+
for (const { rel, text, hay } of files) {
|
|
14651
14705
|
const score = terms2.filter((t) => hay.includes(t)).length;
|
|
14652
14706
|
if (!score)
|
|
14653
14707
|
continue;
|
|
14654
|
-
|
|
14655
|
-
hits.push({ rel: path25.relative(repoRoot, file).split(path25.sep).join("/"), score, symbols: symbols2 });
|
|
14708
|
+
hits.push({ rel, score, text });
|
|
14656
14709
|
}
|
|
14657
14710
|
if (!hits.length)
|
|
14658
14711
|
return null;
|
|
14659
14712
|
hits.sort((a, b) => b.score - a.score || (a.rel < b.rel ? -1 : 1));
|
|
14660
14713
|
const top = hits.slice(0, MAX_PATHS);
|
|
14661
|
-
const symbols = [...new Set(top.flatMap((h) => h.
|
|
14714
|
+
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);
|
|
14662
14715
|
return { paths: top.map((h) => h.rel).sort(), ...symbols.length ? { symbols } : {} };
|
|
14663
14716
|
}
|
|
14664
14717
|
var SKIP_DIRS, CODE_EXT, MAX_FILES, MAX_FILE_BYTES, MAX_PATHS, MAX_SYMBOLS, SYMBOL_RE, anchorTerms;
|
|
14665
14718
|
var init_anchor = __esm({
|
|
14666
14719
|
"packages/core/dist/knowledge/anchor.js"() {
|
|
14667
|
-
SKIP_DIRS = /* @__PURE__ */ new Set([".git", "node_modules", "dist", "build", "coverage", ".next", ".worktrees", ".planning", ".converted"]);
|
|
14720
|
+
SKIP_DIRS = /* @__PURE__ */ new Set([".git", "node_modules", "dist", "build", "coverage", ".next", ".worktrees", ".planning", ".converted", ".venv", "venv", "__pycache__"]);
|
|
14668
14721
|
CODE_EXT = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".py", ".go", ".rs", ".java", ".kt", ".swift", ".rb", ".php", ".cs", ".sol", ".sql", ".md"]);
|
|
14669
|
-
MAX_FILES =
|
|
14722
|
+
MAX_FILES = 2e4;
|
|
14670
14723
|
MAX_FILE_BYTES = 256 * 1024;
|
|
14671
14724
|
MAX_PATHS = 5;
|
|
14672
14725
|
MAX_SYMBOLS = 10;
|
|
@@ -14710,8 +14763,8 @@ function validateCandidate(c) {
|
|
|
14710
14763
|
}
|
|
14711
14764
|
return p;
|
|
14712
14765
|
}
|
|
14713
|
-
function upsertSource(fm, src) {
|
|
14714
|
-
const i = fm.sources.findIndex((s) => s.ref === src.ref);
|
|
14766
|
+
function upsertSource(fm, src, canon) {
|
|
14767
|
+
const i = fm.sources.findIndex((s) => canon(s.ref) === canon(src.ref));
|
|
14715
14768
|
if (i < 0) {
|
|
14716
14769
|
fm.sources.push(src);
|
|
14717
14770
|
return true;
|
|
@@ -14735,7 +14788,8 @@ function applyCandidates(input, opts) {
|
|
|
14735
14788
|
const norm = /* @__PURE__ */ new Map();
|
|
14736
14789
|
const totals = /* @__PURE__ */ new Map();
|
|
14737
14790
|
const touched = /* @__PURE__ */ new Set();
|
|
14738
|
-
const
|
|
14791
|
+
const canon = refCanon(kbRoot, opts.sources ?? []);
|
|
14792
|
+
const complete = new Set((input.complete ?? []).map(canon));
|
|
14739
14793
|
for (const cand of input.candidates) {
|
|
14740
14794
|
const problems = validateCandidate(cand);
|
|
14741
14795
|
if (problems.length) {
|
|
@@ -14763,7 +14817,7 @@ function applyCandidates(input, opts) {
|
|
|
14763
14817
|
ev2("item.rejected", cand.id, { reason: "ungrounded" });
|
|
14764
14818
|
continue;
|
|
14765
14819
|
}
|
|
14766
|
-
const hit = (opts.errata ?? []).find((e) => e.ref === cand.source && ((o) => !!o && spansOverlap(o, offset))(findQuote(hay, e.quote)));
|
|
14820
|
+
const hit = (opts.errata ?? []).find((e) => canon(e.ref) === canon(cand.source) && ((o) => !!o && spansOverlap(o, offset))(findQuote(hay, e.quote)));
|
|
14767
14821
|
if (hit) {
|
|
14768
14822
|
tot.total--;
|
|
14769
14823
|
res.rejected.push({ id: cand.id, source: cand.source, reason: `errata:${hit.id}` });
|
|
@@ -14773,7 +14827,7 @@ function applyCandidates(input, opts) {
|
|
|
14773
14827
|
let id = cand.id;
|
|
14774
14828
|
for (const [wid, w] of work) {
|
|
14775
14829
|
const span = (s) => s.sha === st.sha ? s.offset : findQuote(hay, s.quote) ?? s.offset;
|
|
14776
|
-
if (w.fm.sources.some((s) => s.ref === cand.source && s.offset && ((o) => !!o && spansOverlap(o, offset))(span(s)))) {
|
|
14830
|
+
if (w.fm.sources.some((s) => canon(s.ref) === canon(cand.source) && s.offset && ((o) => !!o && spansOverlap(o, offset))(span(s)))) {
|
|
14777
14831
|
id = wid;
|
|
14778
14832
|
break;
|
|
14779
14833
|
}
|
|
@@ -14788,7 +14842,7 @@ function applyCandidates(input, opts) {
|
|
|
14788
14842
|
|
|
14789
14843
|
${cand.rationale.trim()}` : "");
|
|
14790
14844
|
if (target && contradicted.length === 0 && sameMeaning(target, cand)) {
|
|
14791
|
-
let changed = upsertSource(target.fm, src);
|
|
14845
|
+
let changed = upsertSource(target.fm, src, canon);
|
|
14792
14846
|
if (target.fm.status === "stale") {
|
|
14793
14847
|
target.fm.status = "active";
|
|
14794
14848
|
changed = true;
|
|
@@ -14839,7 +14893,7 @@ ${cand.rationale.trim()}` : "");
|
|
|
14839
14893
|
if (!other.startsWith(`${id}@`) || !other.endsWith(".md") || path26.join(dir, other) === file)
|
|
14840
14894
|
continue;
|
|
14841
14895
|
const old = matter4(fs25.readFileSync(path26.join(dir, other), "utf8"));
|
|
14842
|
-
if (!old.data.sources?.some((s) => s.ref === cand.source))
|
|
14896
|
+
if (!old.data.sources?.some((s) => canon(s.ref) === canon(cand.source)))
|
|
14843
14897
|
continue;
|
|
14844
14898
|
fs25.writeFileSync(path26.join(dir, other.replace(/\.md$/, ".superseded")), matter4.stringify(old.content, { ...old.data, supersededBy: path26.basename(file) }));
|
|
14845
14899
|
fs25.rmSync(path26.join(dir, other));
|
|
@@ -14853,18 +14907,19 @@ ${cand.rationale.trim()}` : "");
|
|
|
14853
14907
|
for (const [id, w] of work) {
|
|
14854
14908
|
if (touched.has(id) || w.fm.status !== "active" || w.isNew)
|
|
14855
14909
|
continue;
|
|
14856
|
-
if (w.fm.sources.length && w.fm.sources.every((s) => complete.has(s.ref))) {
|
|
14910
|
+
if (w.fm.sources.length && w.fm.sources.every((s) => complete.has(canon(s.ref)))) {
|
|
14857
14911
|
w.fm.status = "stale";
|
|
14858
14912
|
w.dirty = true;
|
|
14859
14913
|
res.stale.push(id);
|
|
14860
14914
|
}
|
|
14861
14915
|
}
|
|
14916
|
+
const anchorCache = /* @__PURE__ */ new Map();
|
|
14862
14917
|
for (const w of work.values()) {
|
|
14863
14918
|
if (!w.dirty || !opts.projects?.length)
|
|
14864
14919
|
continue;
|
|
14865
14920
|
const anchors = { ...w.fm.anchors ?? {} };
|
|
14866
14921
|
for (const p of opts.projects) {
|
|
14867
|
-
const a = computeAnchor(p.root, w.fm.triggers);
|
|
14922
|
+
const a = computeAnchor(p.root, w.fm.triggers, anchorCache);
|
|
14868
14923
|
if (a)
|
|
14869
14924
|
anchors[p.name] = a;
|
|
14870
14925
|
}
|
|
@@ -14879,7 +14934,7 @@ ${cand.rationale.trim()}` : "");
|
|
|
14879
14934
|
if (!fs25.existsSync(w.file) || fs25.readFileSync(w.file, "utf8") !== text)
|
|
14880
14935
|
fs25.writeFileSync(w.file, text);
|
|
14881
14936
|
}
|
|
14882
|
-
res.orphanedErrata = orphanedErrata(kbRoot, opts.errata ?? [], totals.keys());
|
|
14937
|
+
res.orphanedErrata = orphanedErrata(kbRoot, opts.sources ?? [], opts.errata ?? [], totals.keys());
|
|
14883
14938
|
for (const [ref, t] of totals)
|
|
14884
14939
|
if (needsDocling(t.dropped, t.total))
|
|
14885
14940
|
res.doclingFlags.push({ ref, ...t });
|
|
@@ -15078,7 +15133,7 @@ var init_schedule = __esm({
|
|
|
15078
15133
|
|
|
15079
15134
|
// packages/core/dist/knowledge/review.js
|
|
15080
15135
|
import crypto4 from "crypto";
|
|
15081
|
-
import { execFileSync as
|
|
15136
|
+
import { execFileSync as execFileSync8 } from "child_process";
|
|
15082
15137
|
import fs27 from "fs";
|
|
15083
15138
|
import path28 from "path";
|
|
15084
15139
|
import matter5 from "gray-matter";
|
|
@@ -15108,11 +15163,7 @@ function priorityOfRef(c, ref) {
|
|
|
15108
15163
|
if (ref.startsWith("agent:"))
|
|
15109
15164
|
return "agent";
|
|
15110
15165
|
const root = kbDir(c.cfg, c.kb);
|
|
15111
|
-
|
|
15112
|
-
for (const f of expandSource(root, e))
|
|
15113
|
-
if (refFor(root, f) === ref)
|
|
15114
|
-
return e.priority;
|
|
15115
|
-
return "project";
|
|
15166
|
+
return c.sources.find((e) => sourceCovers(root, c.sources, e, ref))?.priority ?? "project";
|
|
15116
15167
|
}
|
|
15117
15168
|
function priorityOfRule(c, r) {
|
|
15118
15169
|
return r.sources.map((s) => priorityOfRef(c, s.ref)).sort((a, b) => PRIORITY_RANK[b] - PRIORITY_RANK[a])[0] ?? "project";
|
|
@@ -15149,7 +15200,7 @@ function reindex(c) {
|
|
|
15149
15200
|
function anchorsFor(c, fm) {
|
|
15150
15201
|
const anchors = { ...fm.anchors ?? {} };
|
|
15151
15202
|
for (const p of c.projects ?? []) {
|
|
15152
|
-
const a = computeAnchor(p.root, fm.triggers);
|
|
15203
|
+
const a = computeAnchor(p.root, fm.triggers, c.anchorCache);
|
|
15153
15204
|
if (a)
|
|
15154
15205
|
anchors[p.name] = a;
|
|
15155
15206
|
}
|
|
@@ -15192,8 +15243,9 @@ function mergeInto(c, p, targetId, live, events) {
|
|
|
15192
15243
|
if (!t)
|
|
15193
15244
|
return false;
|
|
15194
15245
|
const tf = readFm(t.file);
|
|
15246
|
+
const canon = refCanon(kbDir(c.cfg, c.kb), c.sources);
|
|
15195
15247
|
for (const s of p.rule.sources)
|
|
15196
|
-
if (!tf.fm.sources.some((x) => x.ref === s.ref))
|
|
15248
|
+
if (!tf.fm.sources.some((x) => canon(x.ref) === canon(s.ref)))
|
|
15197
15249
|
tf.fm.sources.push(s);
|
|
15198
15250
|
fs27.writeFileSync(t.file, fileText(tf.fm, tf.body));
|
|
15199
15251
|
fs27.rmSync(p.rule.file);
|
|
@@ -15206,7 +15258,7 @@ function evaluateCodeConflict(c, rule2, cc) {
|
|
|
15206
15258
|
const root = proj?.root;
|
|
15207
15259
|
const code = root ? g.lastCommit(root, cc.files) : null;
|
|
15208
15260
|
const kbRoot = kbDir(c.cfg, c.kb);
|
|
15209
|
-
const docDates = rule2.sources.map((s) => g.docDate(
|
|
15261
|
+
const docDates = rule2.sources.map((s) => g.docDate(refPath(kbRoot, c.sources, s.ref))).filter((d2) => !!d2).sort();
|
|
15210
15262
|
const docDate = docDates[docDates.length - 1];
|
|
15211
15263
|
const docRev = docRevOf(rule2);
|
|
15212
15264
|
const evidence = { docRev, codeRev: code?.rev ?? "unknown", files: cc.files, project: cc.project };
|
|
@@ -15228,6 +15280,7 @@ function evaluateCodeConflict(c, rule2, cc) {
|
|
|
15228
15280
|
};
|
|
15229
15281
|
}
|
|
15230
15282
|
function applyDecisions(file, c) {
|
|
15283
|
+
c = { ...c, anchorCache: /* @__PURE__ */ new Map() };
|
|
15231
15284
|
const now = nowOf(c);
|
|
15232
15285
|
const kbRoot = kbDir(c.cfg, c.kb);
|
|
15233
15286
|
const threshold = reconcileConfig(c.cfg, c.kb).autoApproveConfidence;
|
|
@@ -15381,8 +15434,9 @@ function applyPair(pd, c, res, threshold, events, kbRoot, now) {
|
|
|
15381
15434
|
return;
|
|
15382
15435
|
}
|
|
15383
15436
|
const kf = readFm(keep.file);
|
|
15437
|
+
const canon = refCanon(kbRoot, c.sources);
|
|
15384
15438
|
for (const s of drop.sources)
|
|
15385
|
-
if (!kf.fm.sources.some((x) => x.ref === s.ref))
|
|
15439
|
+
if (!kf.fm.sources.some((x) => canon(x.ref) === canon(s.ref)))
|
|
15386
15440
|
kf.fm.sources.push(s);
|
|
15387
15441
|
kf.fm.supersedes = [.../* @__PURE__ */ new Set([...kf.fm.supersedes ?? [], drop.id])];
|
|
15388
15442
|
fs27.writeFileSync(keep.file, fileText(kf.fm, kf.body));
|
|
@@ -15528,7 +15582,7 @@ var init_review = __esm({
|
|
|
15528
15582
|
escalationsFile = (kbRoot) => path28.join(kbRoot, "escalations.json");
|
|
15529
15583
|
verdictsFile = (kbRoot) => path28.join(kbRoot, "verdicts.jsonl");
|
|
15530
15584
|
needsYouCount = (kbRoot) => readEscalations(kbRoot).filter((e) => e.needsYou).length;
|
|
15531
|
-
git = (root, args) =>
|
|
15585
|
+
git = (root, args) => execFileSync8("git", ["-C", root, ...args], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
15532
15586
|
realGit = {
|
|
15533
15587
|
lastCommit(root, files) {
|
|
15534
15588
|
try {
|
|
@@ -15967,7 +16021,7 @@ function renderReport(cfg, kb, o) {
|
|
|
15967
16021
|
if (info.length)
|
|
15968
16022
|
L.push("", `## For information (${info.length})`, "", ...info.map((e) => `- **${e.key}**: ${e.explanation}`));
|
|
15969
16023
|
const { errata, errors: errataErrors } = loadErrata(kbDir(cfg, kb));
|
|
15970
|
-
const orphans = orphanedErrata(kbDir(cfg, kb), errata);
|
|
16024
|
+
const orphans = orphanedErrata(kbDir(cfg, kb), loadSources(kbDir(cfg, kb)).sources, errata);
|
|
15971
16025
|
if (orphans.length || errataErrors.length) {
|
|
15972
16026
|
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}`));
|
|
15973
16027
|
}
|
|
@@ -15989,6 +16043,7 @@ var init_report = __esm({
|
|
|
15989
16043
|
init_errata();
|
|
15990
16044
|
init_layers();
|
|
15991
16045
|
init_paths();
|
|
16046
|
+
init_sources();
|
|
15992
16047
|
init_review();
|
|
15993
16048
|
init_scores();
|
|
15994
16049
|
}
|
|
@@ -16324,7 +16379,6 @@ __export(dist_exports2, {
|
|
|
16324
16379
|
extractToolPayload: () => extractToolPayload,
|
|
16325
16380
|
extractUserIntentFromTranscript: () => extractUserIntentFromTranscript,
|
|
16326
16381
|
fallsBackToPane: () => fallsBackToPane,
|
|
16327
|
-
fileForRef: () => fileForRef,
|
|
16328
16382
|
findCrewPane: () => findCrewPane,
|
|
16329
16383
|
findLegacyKbs: () => findLegacyKbs,
|
|
16330
16384
|
findLegacyOverlays: () => findLegacyOverlays,
|
|
@@ -16466,7 +16520,10 @@ __export(dist_exports2, {
|
|
|
16466
16520
|
recoverStall: () => recoverStall,
|
|
16467
16521
|
reduce: () => reduce,
|
|
16468
16522
|
reduceLifecycle: () => reduceLifecycle,
|
|
16523
|
+
refCandidates: () => refCandidates,
|
|
16524
|
+
refCanon: () => refCanon,
|
|
16469
16525
|
refFor: () => refFor,
|
|
16526
|
+
refPath: () => refPath,
|
|
16470
16527
|
releaseDaemonLock: () => releaseDaemonLock,
|
|
16471
16528
|
removeRunningMarker: () => removeRunningMarker,
|
|
16472
16529
|
removeSource: () => removeSource,
|
|
@@ -16499,6 +16556,7 @@ __export(dist_exports2, {
|
|
|
16499
16556
|
resolveSetupGroup: () => resolveSetupGroup,
|
|
16500
16557
|
resolveSetupToken: () => resolveSetupToken,
|
|
16501
16558
|
resolveSetupUserId: () => resolveSetupUserId,
|
|
16559
|
+
resolveSourceRef: () => resolveSourceRef,
|
|
16502
16560
|
restartDaemonIfRunning: () => restartDaemonIfRunning,
|
|
16503
16561
|
rotateIfNeeded: () => rotateIfNeeded,
|
|
16504
16562
|
ruleAuditScope: () => ruleAuditScope,
|
|
@@ -17235,7 +17293,7 @@ var init_drivers = __esm({
|
|
|
17235
17293
|
// packages/agents/dist/projection/cursor.js
|
|
17236
17294
|
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
17237
17295
|
import path33 from "path";
|
|
17238
|
-
import
|
|
17296
|
+
import os9 from "os";
|
|
17239
17297
|
function renderMdc(source) {
|
|
17240
17298
|
const skillSections = source.skills.map((s) => `## Skill: ${s.name}
|
|
17241
17299
|
|
|
@@ -17283,7 +17341,7 @@ function createCursorEmitter() {
|
|
|
17283
17341
|
if (scope === "user") {
|
|
17284
17342
|
return [
|
|
17285
17343
|
{
|
|
17286
|
-
path: path33.join(
|
|
17344
|
+
path: path33.join(os9.homedir(), ".cursor/rules/squadrant-global.mdc"),
|
|
17287
17345
|
shared: false,
|
|
17288
17346
|
format: "mdc"
|
|
17289
17347
|
}
|
|
@@ -17362,7 +17420,7 @@ var init_marker = __esm({
|
|
|
17362
17420
|
// packages/agents/dist/projection/codex.js
|
|
17363
17421
|
import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
17364
17422
|
import path34 from "path";
|
|
17365
|
-
import
|
|
17423
|
+
import os10 from "os";
|
|
17366
17424
|
function renderMarkdown(source) {
|
|
17367
17425
|
const skillSections = source.skills.map((s) => `## Skill: ${s.name}
|
|
17368
17426
|
|
|
@@ -17386,7 +17444,7 @@ function createCodexEmitter() {
|
|
|
17386
17444
|
destinations(scope, projectRoot) {
|
|
17387
17445
|
if (scope === "user") {
|
|
17388
17446
|
return [{
|
|
17389
|
-
path: path34.join(
|
|
17447
|
+
path: path34.join(os10.homedir(), ".codex/AGENTS.md"),
|
|
17390
17448
|
shared: true,
|
|
17391
17449
|
format: "markdown"
|
|
17392
17450
|
}];
|
|
@@ -17434,7 +17492,7 @@ var init_codex2 = __esm({
|
|
|
17434
17492
|
// packages/agents/dist/projection/gemini.js
|
|
17435
17493
|
import { mkdir as mkdir3, readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
|
|
17436
17494
|
import path35 from "path";
|
|
17437
|
-
import
|
|
17495
|
+
import os11 from "os";
|
|
17438
17496
|
function renderMarkdown2(source) {
|
|
17439
17497
|
const skillSections = source.skills.map((s) => `## Skill: ${s.name}
|
|
17440
17498
|
|
|
@@ -17458,7 +17516,7 @@ function createGeminiEmitter() {
|
|
|
17458
17516
|
destinations(scope, projectRoot) {
|
|
17459
17517
|
if (scope === "user") {
|
|
17460
17518
|
return [{
|
|
17461
|
-
path: path35.join(
|
|
17519
|
+
path: path35.join(os11.homedir(), ".gemini/GEMINI.md"),
|
|
17462
17520
|
shared: true,
|
|
17463
17521
|
format: "markdown"
|
|
17464
17522
|
}];
|
|
@@ -17506,7 +17564,7 @@ var init_gemini2 = __esm({
|
|
|
17506
17564
|
// packages/agents/dist/projection/opencode.js
|
|
17507
17565
|
import { mkdir as mkdir4, readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
|
|
17508
17566
|
import path36 from "path";
|
|
17509
|
-
import
|
|
17567
|
+
import os12 from "os";
|
|
17510
17568
|
function renderMarkdown3(source) {
|
|
17511
17569
|
const skillSections = source.skills.map((s) => `## Skill: ${s.name}
|
|
17512
17570
|
|
|
@@ -17530,7 +17588,7 @@ function createOpencodeEmitter() {
|
|
|
17530
17588
|
destinations(scope, projectRoot) {
|
|
17531
17589
|
if (scope === "user") {
|
|
17532
17590
|
return [{
|
|
17533
|
-
path: path36.join(
|
|
17591
|
+
path: path36.join(os12.homedir(), ".config", "opencode", "AGENTS.md"),
|
|
17534
17592
|
shared: true,
|
|
17535
17593
|
format: "markdown"
|
|
17536
17594
|
}];
|
|
@@ -17577,10 +17635,10 @@ var init_opencode2 = __esm({
|
|
|
17577
17635
|
|
|
17578
17636
|
// packages/agents/dist/projection/opencode-skills.js
|
|
17579
17637
|
import fs33 from "fs";
|
|
17580
|
-
import
|
|
17638
|
+
import os13 from "os";
|
|
17581
17639
|
import path37 from "path";
|
|
17582
17640
|
function defaultOpencodeSkillsRoot(env = process.env) {
|
|
17583
|
-
const configHome = env.XDG_CONFIG_HOME || path37.join(
|
|
17641
|
+
const configHome = env.XDG_CONFIG_HOME || path37.join(os13.homedir(), ".config");
|
|
17584
17642
|
return path37.join(configHome, "opencode", "skills");
|
|
17585
17643
|
}
|
|
17586
17644
|
function parseSkillName(raw) {
|
|
@@ -17675,7 +17733,7 @@ var init_opencode_skills = __esm({
|
|
|
17675
17733
|
// packages/agents/dist/projection/claude.js
|
|
17676
17734
|
import { mkdir as mkdir5, readFile as readFile5, writeFile as writeFile5 } from "fs/promises";
|
|
17677
17735
|
import path38 from "path";
|
|
17678
|
-
import
|
|
17736
|
+
import os14 from "os";
|
|
17679
17737
|
function renderMarkdown4(source) {
|
|
17680
17738
|
const skillSections = source.skills.map((s) => `## Skill: ${s.name}
|
|
17681
17739
|
|
|
@@ -17699,7 +17757,7 @@ function createClaudeEmitter() {
|
|
|
17699
17757
|
destinations(scope, projectRoot) {
|
|
17700
17758
|
if (scope === "user") {
|
|
17701
17759
|
return [{
|
|
17702
|
-
path: path38.join(
|
|
17760
|
+
path: path38.join(os14.homedir(), ".claude/CLAUDE.md"),
|
|
17703
17761
|
shared: true,
|
|
17704
17762
|
format: "markdown"
|
|
17705
17763
|
}];
|
|
@@ -19654,13 +19712,13 @@ var init_receipt_listener = __esm({
|
|
|
19654
19712
|
|
|
19655
19713
|
// packages/agents/dist/claude/api-key-approval.js
|
|
19656
19714
|
import fs34 from "fs";
|
|
19657
|
-
import
|
|
19715
|
+
import os15 from "os";
|
|
19658
19716
|
import path39 from "path";
|
|
19659
19717
|
function ensureClaudeApiKeyApproved(apiKey, opts = {}) {
|
|
19660
19718
|
const suffix = apiKey.slice(-20);
|
|
19661
19719
|
if (!suffix)
|
|
19662
19720
|
return { changed: false, reason: "empty api key" };
|
|
19663
|
-
const file = opts.claudeJsonPath ?? path39.join(
|
|
19721
|
+
const file = opts.claudeJsonPath ?? path39.join(os15.homedir(), ".claude.json");
|
|
19664
19722
|
const log = opts.log ?? (() => {
|
|
19665
19723
|
});
|
|
19666
19724
|
if (!fs34.existsSync(file)) {
|
|
@@ -19887,7 +19945,7 @@ var init_fact_adapter = __esm({
|
|
|
19887
19945
|
|
|
19888
19946
|
// packages/agents/dist/rules-hooks/install.js
|
|
19889
19947
|
import fs35 from "fs";
|
|
19890
|
-
import
|
|
19948
|
+
import os16 from "os";
|
|
19891
19949
|
import path40 from "path";
|
|
19892
19950
|
function readJson(file) {
|
|
19893
19951
|
try {
|
|
@@ -19925,12 +19983,12 @@ function writeIfChanged(file, next, dryRun) {
|
|
|
19925
19983
|
}
|
|
19926
19984
|
function installCodexRulesHooks(opts = {}) {
|
|
19927
19985
|
const env = opts.env ?? process.env;
|
|
19928
|
-
const file = opts.target ?? path40.join(env.CODEX_HOME ?? path40.join(
|
|
19986
|
+
const file = opts.target ?? path40.join(env.CODEX_HOME ?? path40.join(os16.homedir(), ".codex"), "hooks.json");
|
|
19929
19987
|
const merged = mergeHooks(readJson(file), "codex", CODEX_HOOKS, opts.cli ?? "squadrant", 5);
|
|
19930
19988
|
return writeIfChanged(file, JSON.stringify(merged, null, 2) + "\n", opts.dryRun);
|
|
19931
19989
|
}
|
|
19932
19990
|
function installGeminiRulesHooks(opts = {}) {
|
|
19933
|
-
const file = opts.target ?? path40.join(
|
|
19991
|
+
const file = opts.target ?? path40.join(os16.homedir(), ".gemini", "settings.json");
|
|
19934
19992
|
const merged = mergeHooks(readJson(file), "gemini", GEMINI_HOOKS, opts.cli ?? "squadrant", 5e3);
|
|
19935
19993
|
return writeIfChanged(file, JSON.stringify(merged, null, 2) + "\n", opts.dryRun);
|
|
19936
19994
|
}
|
|
@@ -19971,7 +20029,7 @@ export const SquadrantRules = async ({ directory }) => {
|
|
|
19971
20029
|
}
|
|
19972
20030
|
function installOpencodeRulesHooks(opts = {}) {
|
|
19973
20031
|
const env = opts.env ?? process.env;
|
|
19974
|
-
const file = opts.target ?? path40.join(env.XDG_CONFIG_HOME || path40.join(
|
|
20032
|
+
const file = opts.target ?? path40.join(env.XDG_CONFIG_HOME || path40.join(os16.homedir(), ".config"), "opencode", "plugin", "squadrant-rules.js");
|
|
19975
20033
|
try {
|
|
19976
20034
|
if (!fs35.readFileSync(file, "utf8").startsWith(OPENCODE_PLUGIN_MARKER))
|
|
19977
20035
|
return { path: file, changed: false, skipped: "foreign-file" };
|
|
@@ -20102,12 +20160,12 @@ var init_dist3 = __esm({
|
|
|
20102
20160
|
});
|
|
20103
20161
|
|
|
20104
20162
|
// packages/workspaces/dist/runtimes/cmux.js
|
|
20105
|
-
import { execFile as execFile3, execFileSync as
|
|
20163
|
+
import { execFile as execFile3, execFileSync as execFileSync9 } from "child_process";
|
|
20106
20164
|
function isInsideCmux() {
|
|
20107
20165
|
return !!process.env.CMUX_WORKSPACE_ID;
|
|
20108
20166
|
}
|
|
20109
20167
|
function cmuxLocal(args) {
|
|
20110
|
-
return
|
|
20168
|
+
return execFileSync9(resolveCmuxBin(), args, {
|
|
20111
20169
|
encoding: "utf-8",
|
|
20112
20170
|
stdio: ["ignore", "pipe", "pipe"],
|
|
20113
20171
|
timeout: CMUX_TIMEOUT
|
|
@@ -20873,14 +20931,14 @@ var init_runtimes = __esm({
|
|
|
20873
20931
|
});
|
|
20874
20932
|
|
|
20875
20933
|
// packages/workspaces/dist/notifiers/cmux.js
|
|
20876
|
-
import { execFile as execFileCb, execFileSync as
|
|
20934
|
+
import { execFile as execFileCb, execFileSync as execFileSync10 } from "child_process";
|
|
20877
20935
|
import { promisify as promisify3 } from "util";
|
|
20878
20936
|
function createCmuxNotifier(_scope) {
|
|
20879
20937
|
return {
|
|
20880
20938
|
name: "cmux",
|
|
20881
20939
|
async probe() {
|
|
20882
20940
|
try {
|
|
20883
|
-
|
|
20941
|
+
execFileSync10(resolveCmuxBin(), ["capabilities"], { encoding: "utf-8", stdio: "pipe", timeout: CMUX_TIMEOUT });
|
|
20884
20942
|
return { installed: true, reachable: true };
|
|
20885
20943
|
} catch (err) {
|
|
20886
20944
|
const code = err.code;
|
|
@@ -21206,9 +21264,9 @@ var init_events_bridge = __esm({
|
|
|
21206
21264
|
});
|
|
21207
21265
|
|
|
21208
21266
|
// packages/workspaces/dist/cmux-daemon/store-fingerprint.js
|
|
21209
|
-
import { execFileSync as
|
|
21267
|
+
import { execFileSync as execFileSync11 } from "child_process";
|
|
21210
21268
|
function defaultExecPs(pid) {
|
|
21211
|
-
return
|
|
21269
|
+
return execFileSync11("ps", ["-o", "command=", "-p", String(pid)], {
|
|
21212
21270
|
encoding: "utf-8",
|
|
21213
21271
|
stdio: ["ignore", "pipe", "ignore"]
|
|
21214
21272
|
});
|
|
@@ -22935,7 +22993,7 @@ init_dist();
|
|
|
22935
22993
|
import { Command as Command2 } from "commander";
|
|
22936
22994
|
import fs38 from "fs";
|
|
22937
22995
|
import path43 from "path";
|
|
22938
|
-
import
|
|
22996
|
+
import os17 from "os";
|
|
22939
22997
|
import readline from "readline";
|
|
22940
22998
|
import chalk4 from "chalk";
|
|
22941
22999
|
|
|
@@ -23242,7 +23300,7 @@ function warnIfNoAnthropic(preset, auth) {
|
|
|
23242
23300
|
var initCommand = new Command2("init").description("Guided first-time setup: provider, hub vault, agents, plugins, projects (re-run-safe)").option("--hub <path>", "Hub vault path", "~/squadrant-hub").option("--preset <id>", "provider preset: a|b|c (non-interactive; d accepted as a deprecated alias for c)").action(async (opts) => {
|
|
23243
23301
|
const hubPath = resolveHome(opts.hub);
|
|
23244
23302
|
const pkgRoot = findPackageRoot();
|
|
23245
|
-
const configDir = path43.join(
|
|
23303
|
+
const configDir = path43.join(os17.homedir(), ".config", "squadrant");
|
|
23246
23304
|
const isTTY = process.stdin.isTTY === true;
|
|
23247
23305
|
console.log(chalk4.bold("\nSquadrant Init\n"));
|
|
23248
23306
|
let explicitPreset;
|
|
@@ -23347,7 +23405,7 @@ var initCommand = new Command2("init").description("Guided first-time setup: pro
|
|
|
23347
23405
|
ensureRuntimeSynced({ sourceRoot: pkgRoot, runtimeRoot: configDir });
|
|
23348
23406
|
console.log(chalk4.green(` \u2714 Runtime assets synced to ${configDir}`));
|
|
23349
23407
|
stepHeader(2, 5, "Agent + projection setup");
|
|
23350
|
-
const settingsPath = path43.join(
|
|
23408
|
+
const settingsPath = path43.join(os17.homedir(), ".claude", "settings.json");
|
|
23351
23409
|
try {
|
|
23352
23410
|
let settings = {};
|
|
23353
23411
|
if (fs38.existsSync(settingsPath)) {
|
|
@@ -23653,9 +23711,9 @@ init_dist();
|
|
|
23653
23711
|
import { Command as Command5 } from "commander";
|
|
23654
23712
|
import { execSync as execSync9 } from "child_process";
|
|
23655
23713
|
import path45 from "path";
|
|
23656
|
-
import
|
|
23714
|
+
import os18 from "os";
|
|
23657
23715
|
import chalk7 from "chalk";
|
|
23658
|
-
var TEMPLATES_DIR2 = path45.join(
|
|
23716
|
+
var TEMPLATES_DIR2 = path45.join(os18.homedir(), ".config", "squadrant", "templates");
|
|
23659
23717
|
var TASK_PROMPTS = {
|
|
23660
23718
|
briefing: "Run your daily briefing using the squadrant:command-ops skill. Read all spoke handoffs, yesterday's logs, current status; produce a concise cross-project briefing; save to {hubVault}/daily-logs/YYYY-MM-DD.md; then exit.",
|
|
23661
23719
|
"learnings-review": "Run a learnings review using the squadrant:command-ops skill. Scan {spokeVault}/learnings across all projects, identify cross-project patterns, propose captured-skill or fix actions, and exit when done.",
|
|
@@ -23729,7 +23787,7 @@ init_dist3();
|
|
|
23729
23787
|
import { Command as Command9 } from "commander";
|
|
23730
23788
|
import { createConnection as createConnection4 } from "net";
|
|
23731
23789
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
23732
|
-
import { execFileSync as
|
|
23790
|
+
import { execFileSync as execFileSync12, spawnSync } from "child_process";
|
|
23733
23791
|
import { homedir as homedir15 } from "os";
|
|
23734
23792
|
import { join as join27 } from "path";
|
|
23735
23793
|
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync13 } from "fs";
|
|
@@ -24258,10 +24316,10 @@ function resolveApproveTarget(tasks, crew) {
|
|
|
24258
24316
|
return matches.reduce((a, b) => (b.createdAt ?? 0) > (a.createdAt ?? 0) ? b : a);
|
|
24259
24317
|
}
|
|
24260
24318
|
function defaultPushBranch(cwd, branch) {
|
|
24261
|
-
|
|
24319
|
+
execFileSync12("git", ["-C", cwd, "push", "-u", "origin", branch], { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
|
|
24262
24320
|
}
|
|
24263
24321
|
function defaultCreatePr(cwd, o) {
|
|
24264
|
-
return
|
|
24322
|
+
return execFileSync12(
|
|
24265
24323
|
"gh",
|
|
24266
24324
|
["pr", "create", "--base", o.base, "--head", o.branch, "--title", o.title, "--body", o.body],
|
|
24267
24325
|
{ cwd, encoding: "utf-8" }
|
|
@@ -24269,7 +24327,7 @@ function defaultCreatePr(cwd, o) {
|
|
|
24269
24327
|
}
|
|
24270
24328
|
function defaultGetCommitSubject(cwd) {
|
|
24271
24329
|
try {
|
|
24272
|
-
return
|
|
24330
|
+
return execFileSync12("git", ["-C", cwd, "log", "-1", "--format=%s"], {
|
|
24273
24331
|
encoding: "utf-8",
|
|
24274
24332
|
stdio: ["ignore", "pipe", "pipe"]
|
|
24275
24333
|
}).trim();
|
|
@@ -24951,7 +25009,7 @@ init_dist();
|
|
|
24951
25009
|
init_dist4();
|
|
24952
25010
|
import { Command as Command11 } from "commander";
|
|
24953
25011
|
import chalk12 from "chalk";
|
|
24954
|
-
import { execFileSync as
|
|
25012
|
+
import { execFileSync as execFileSync13 } from "child_process";
|
|
24955
25013
|
import readline2 from "readline";
|
|
24956
25014
|
function resolveDiffTarget(tasks, crew, projectPath) {
|
|
24957
25015
|
const matches = tasks.filter((t) => t.name === crew);
|
|
@@ -25022,14 +25080,14 @@ function promptLine2(question) {
|
|
|
25022
25080
|
}
|
|
25023
25081
|
function getPrDiff(projectPath, pr) {
|
|
25024
25082
|
try {
|
|
25025
|
-
return
|
|
25083
|
+
return execFileSync13("gh", ["pr", "diff", pr], { cwd: projectPath, encoding: "utf-8" });
|
|
25026
25084
|
} catch (e) {
|
|
25027
25085
|
throw new Error(`Could not fetch PR #${pr} diff (gh pr diff failed): ${e.message}`);
|
|
25028
25086
|
}
|
|
25029
25087
|
}
|
|
25030
25088
|
function getRefsDiff(projectPath, base, head) {
|
|
25031
25089
|
try {
|
|
25032
|
-
return
|
|
25090
|
+
return execFileSync13("git", ["-C", projectPath, "diff", `${base}...${head}`], { encoding: "utf-8" });
|
|
25033
25091
|
} catch (e) {
|
|
25034
25092
|
throw new Error(`Could not diff ${base}...${head}: ${e.message}`);
|
|
25035
25093
|
}
|
|
@@ -25050,7 +25108,7 @@ async function openCrewDiff(project, proj, crew, opts, runtime, workspaceId) {
|
|
|
25050
25108
|
let opened = 0;
|
|
25051
25109
|
for (const source of sources) {
|
|
25052
25110
|
const statArgs = source === "staged" ? ["diff", "--stat", "--cached"] : ["diff", "--stat"];
|
|
25053
|
-
const stat2 =
|
|
25111
|
+
const stat2 = execFileSync13("git", ["-C", target.cwd, ...statArgs], { encoding: "utf-8" }).trim();
|
|
25054
25112
|
if (!stat2) continue;
|
|
25055
25113
|
await runtime.showDiff({
|
|
25056
25114
|
workspaceId,
|
|
@@ -25071,7 +25129,7 @@ async function openCrewDiff(project, proj, crew, opts, runtime, workspaceId) {
|
|
|
25071
25129
|
}
|
|
25072
25130
|
return;
|
|
25073
25131
|
}
|
|
25074
|
-
const diffStat =
|
|
25132
|
+
const diffStat = execFileSync13(
|
|
25075
25133
|
"git",
|
|
25076
25134
|
["-C", target.cwd, "diff", "--stat", `${base}...HEAD`],
|
|
25077
25135
|
{ encoding: "utf-8" }
|
|
@@ -25120,7 +25178,7 @@ async function runDiff(project, crewArg, opts) {
|
|
|
25120
25178
|
const base = resolveWorktreeBase(proj.path);
|
|
25121
25179
|
const stats = buildCrewDiffStats(tasks, proj.path, base, (cwd, b) => {
|
|
25122
25180
|
try {
|
|
25123
|
-
return
|
|
25181
|
+
return execFileSync13("git", ["-C", cwd, "diff", "--stat", `${b}...HEAD`], { encoding: "utf-8" });
|
|
25124
25182
|
} catch {
|
|
25125
25183
|
return "";
|
|
25126
25184
|
}
|
|
@@ -25149,9 +25207,9 @@ init_dist2();
|
|
|
25149
25207
|
import { Command as Command12 } from "commander";
|
|
25150
25208
|
import fs41 from "fs";
|
|
25151
25209
|
import path46 from "path";
|
|
25152
|
-
import
|
|
25210
|
+
import os19 from "os";
|
|
25153
25211
|
import chalk13 from "chalk";
|
|
25154
|
-
var TEMPLATES_DIR3 = path46.join(
|
|
25212
|
+
var TEMPLATES_DIR3 = path46.join(os19.homedir(), ".config", "squadrant", "templates");
|
|
25155
25213
|
async function runSideSpawn2(input) {
|
|
25156
25214
|
const config = loadConfig();
|
|
25157
25215
|
const proj = config.projects[input.project];
|
|
@@ -26795,10 +26853,10 @@ init_dist3();
|
|
|
26795
26853
|
init_dist4();
|
|
26796
26854
|
init_dist2();
|
|
26797
26855
|
import { Command as Command14 } from "commander";
|
|
26798
|
-
import { execSync as execSync11, execFileSync as
|
|
26856
|
+
import { execSync as execSync11, execFileSync as execFileSync14 } from "child_process";
|
|
26799
26857
|
import fs43 from "fs";
|
|
26800
26858
|
import path48 from "path";
|
|
26801
|
-
import
|
|
26859
|
+
import os20 from "os";
|
|
26802
26860
|
import chalk16 from "chalk";
|
|
26803
26861
|
|
|
26804
26862
|
// packages/cli/src/commands/launch-interactive.ts
|
|
@@ -26890,8 +26948,8 @@ function resolveLaunchBackend(o) {
|
|
|
26890
26948
|
// packages/cli/src/commands/launch.ts
|
|
26891
26949
|
init_dist2();
|
|
26892
26950
|
var CMUX_APP = "/Applications/cmux.app";
|
|
26893
|
-
var TEMPLATES_DIR4 = path48.join(
|
|
26894
|
-
var SESSIONS_PATH2 = path48.join(
|
|
26951
|
+
var TEMPLATES_DIR4 = path48.join(os20.homedir(), ".config", "squadrant", "templates");
|
|
26952
|
+
var SESSIONS_PATH2 = path48.join(os20.homedir(), ".config", "squadrant", "sessions.json");
|
|
26895
26953
|
function shouldWireCaptainChannel(agentName, config) {
|
|
26896
26954
|
return agentName === "claude" && resolveCaptainChannelMode(config.defaults) !== "off";
|
|
26897
26955
|
}
|
|
@@ -26913,7 +26971,7 @@ function pickResumeSessionId(record, agentName, fresh = false) {
|
|
|
26913
26971
|
}
|
|
26914
26972
|
function isOpencodeCaptainDir(dir) {
|
|
26915
26973
|
try {
|
|
26916
|
-
|
|
26974
|
+
execFileSync14("git", ["-C", dir, "rev-parse", "--verify", "HEAD"], { stdio: "ignore" });
|
|
26917
26975
|
return true;
|
|
26918
26976
|
} catch {
|
|
26919
26977
|
return false;
|
|
@@ -26988,7 +27046,7 @@ var launchCommand = new Command14("launch").description(
|
|
|
26988
27046
|
initialPrompt = "Run your startup checklist: use the squadrant:command-ops skill, complete your daily briefing, then report ready.";
|
|
26989
27047
|
}
|
|
26990
27048
|
const runtime = projectName ? runtimes.forProject(projectName, config) : runtimes.global(config);
|
|
26991
|
-
const stateRoot = path48.join(
|
|
27049
|
+
const stateRoot = path48.join(os20.homedir(), ".config", "squadrant", "state");
|
|
26992
27050
|
const isOpencodeCaptain = role === "captain" && agentName === "opencode" && !!projectName;
|
|
26993
27051
|
if (isOpencodeCaptain && !isOpencodeCaptainDir(cwd)) {
|
|
26994
27052
|
console.error(chalk16.red(`
|
|
@@ -27345,7 +27403,7 @@ Shutting down captain workspace for '${project}'...
|
|
|
27345
27403
|
init_dist();
|
|
27346
27404
|
import { Command as Command16 } from "commander";
|
|
27347
27405
|
import fs44 from "fs";
|
|
27348
|
-
import
|
|
27406
|
+
import os21 from "os";
|
|
27349
27407
|
import path49 from "path";
|
|
27350
27408
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
27351
27409
|
import { execSync as execSync12 } from "child_process";
|
|
@@ -27399,7 +27457,7 @@ function buildIssueUrl(metrics, squadrantVersion) {
|
|
|
27399
27457
|
}
|
|
27400
27458
|
var feedbackCommand = new Command16("feedback").description("Open a pre-filled GitHub issue for feedback or bug reports").action(() => {
|
|
27401
27459
|
const config = loadConfig();
|
|
27402
|
-
const metricsPath = config.metrics?.path || path49.join(
|
|
27460
|
+
const metricsPath = config.metrics?.path || path49.join(os21.homedir(), ".config", "squadrant", "metrics.json");
|
|
27403
27461
|
const metrics = readMetrics(metricsPath);
|
|
27404
27462
|
const version = readStamp(config) ?? readPkgVersion();
|
|
27405
27463
|
const issueUrl = buildIssueUrl(metrics, version);
|
|
@@ -28182,7 +28240,7 @@ function readPkgVersion2() {
|
|
|
28182
28240
|
|
|
28183
28241
|
// packages/cli/src/commands/heal.ts
|
|
28184
28242
|
init_dist();
|
|
28185
|
-
import { execFileSync as
|
|
28243
|
+
import { execFileSync as execFileSync15 } from "child_process";
|
|
28186
28244
|
import { join as join32 } from "path";
|
|
28187
28245
|
import { homedir as homedir17 } from "os";
|
|
28188
28246
|
import { Command as Command24 } from "commander";
|
|
@@ -28391,7 +28449,7 @@ async function runHealCaptain(projects, deps) {
|
|
|
28391
28449
|
}
|
|
28392
28450
|
function kickstartDaemonForHealCaptain() {
|
|
28393
28451
|
const uid = process.getuid?.() ?? 0;
|
|
28394
|
-
|
|
28452
|
+
execFileSync15("launchctl", ["kickstart", "-k", `gui/${uid}/${LABEL}`], { stdio: "ignore" });
|
|
28395
28453
|
}
|
|
28396
28454
|
var healCommand = new Command24("heal").description("Targeted, idempotent remediation for squadrant components (daemon, health)").addHelpText("after", "\nDeferred: 'squadrant heal crew <id>' (re-attach) \u2014 see issue #100.").addCommand(
|
|
28397
28455
|
new Command24("status").description("Dry-run: print unhealthy components and the exact heal command for each").option("-p, --project <project>", "scope to one project").option("--json", "output machine-readable JSON (exit 0=healthy, 1=error, 2=unhealthy)").action(async (opts) => {
|
|
@@ -28730,11 +28788,11 @@ var effortCommand = new Command29("effort").description("Get or set the crew tok
|
|
|
28730
28788
|
init_dist();
|
|
28731
28789
|
import fs48 from "fs";
|
|
28732
28790
|
import path52 from "path";
|
|
28733
|
-
import
|
|
28791
|
+
import os22 from "os";
|
|
28734
28792
|
import readline3 from "readline";
|
|
28735
28793
|
import { Command as Command30 } from "commander";
|
|
28736
28794
|
import chalk31 from "chalk";
|
|
28737
|
-
var CLAUDE_PROJECTS_DIR = path52.join(
|
|
28795
|
+
var CLAUDE_PROJECTS_DIR = path52.join(os22.homedir(), ".claude", "projects");
|
|
28738
28796
|
function parseTranscriptLine(rawLine) {
|
|
28739
28797
|
const line2 = rawLine.trim();
|
|
28740
28798
|
if (!line2) return { timestamp: null, usage: null };
|
|
@@ -30003,11 +30061,11 @@ var workCommand = new Command34("work").description("Track your own in-flight wo
|
|
|
30003
30061
|
init_dist();
|
|
30004
30062
|
import { Command as Command35 } from "commander";
|
|
30005
30063
|
import path57 from "path";
|
|
30006
|
-
import
|
|
30064
|
+
import os23 from "os";
|
|
30007
30065
|
|
|
30008
30066
|
// packages/cli/src/lib/handoff-live-repo.ts
|
|
30009
30067
|
init_dist();
|
|
30010
|
-
import { execFileSync as
|
|
30068
|
+
import { execFileSync as execFileSync16 } from "child_process";
|
|
30011
30069
|
import fs50 from "fs";
|
|
30012
30070
|
import path55 from "path";
|
|
30013
30071
|
|
|
@@ -30086,7 +30144,7 @@ var OPEN_PR_LIMIT = 20;
|
|
|
30086
30144
|
var RELEASE_BRANCH = "main";
|
|
30087
30145
|
var defaultCommandRunner = {
|
|
30088
30146
|
run(cmd, args, cwd) {
|
|
30089
|
-
return
|
|
30147
|
+
return execFileSync16(cmd, args, { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
|
|
30090
30148
|
}
|
|
30091
30149
|
};
|
|
30092
30150
|
function tryRun2(runner, cmd, args, cwd) {
|
|
@@ -30415,7 +30473,7 @@ function readNewestArchivedHandoff(spokeVault, now) {
|
|
|
30415
30473
|
}
|
|
30416
30474
|
|
|
30417
30475
|
// packages/cli/src/commands/handoff.ts
|
|
30418
|
-
var CLAUDE_MEM_DB_PATH = path57.join(
|
|
30476
|
+
var CLAUDE_MEM_DB_PATH = path57.join(os23.homedir(), ".claude-mem", "claude-mem.db");
|
|
30419
30477
|
async function defaultFetchTasks(project) {
|
|
30420
30478
|
return await squadrantdCall({ kind: "list", project });
|
|
30421
30479
|
}
|
|
@@ -30575,7 +30633,7 @@ var sessionsCommand = new Command36("sessions").description("List live agent ses
|
|
|
30575
30633
|
init_dist();
|
|
30576
30634
|
init_dist2();
|
|
30577
30635
|
init_dist3();
|
|
30578
|
-
import
|
|
30636
|
+
import os24 from "os";
|
|
30579
30637
|
import path58 from "path";
|
|
30580
30638
|
import { Command as Command37 } from "commander";
|
|
30581
30639
|
import chalk36 from "chalk";
|
|
@@ -30694,7 +30752,7 @@ function buildWhoamiDeps(opts = {}) {
|
|
|
30694
30752
|
const projects = Object.fromEntries(
|
|
30695
30753
|
Object.entries(config.projects).map(([n, p]) => [n, resolveHome(p.path)])
|
|
30696
30754
|
);
|
|
30697
|
-
const root = stateRoot ?? path58.join(
|
|
30755
|
+
const root = stateRoot ?? path58.join(os24.homedir(), ".config", "squadrant", "state");
|
|
30698
30756
|
const store = createStore(root);
|
|
30699
30757
|
const merged = {
|
|
30700
30758
|
env: process.env,
|
|
@@ -30747,7 +30805,7 @@ var whoamiCommand = new Command37("whoami").description("Show the agent session
|
|
|
30747
30805
|
init_dist();
|
|
30748
30806
|
init_dist2();
|
|
30749
30807
|
import fs54 from "fs";
|
|
30750
|
-
import
|
|
30808
|
+
import os25 from "os";
|
|
30751
30809
|
import path59 from "path";
|
|
30752
30810
|
import readline4 from "readline/promises";
|
|
30753
30811
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
@@ -31103,7 +31161,7 @@ knowledgeCommand.command("review <kb>").description("Escalations for the operato
|
|
|
31103
31161
|
for (const x of r.skipped) console.log(chalk38.red(` \u2718 ${x.item}: ${x.reason}`));
|
|
31104
31162
|
return;
|
|
31105
31163
|
}
|
|
31106
|
-
const by =
|
|
31164
|
+
const by = os25.userInfo().username;
|
|
31107
31165
|
const resolution = () => o.keepDoc ? { kind: "verdict", verdict: "keep-doc" } : o.supersedeWithCode ? { kind: "verdict", verdict: "supersede-with-code" } : o.approve ? { kind: "approve" } : o.reject ? { kind: "reject" } : null;
|
|
31108
31166
|
if (o.resolve) {
|
|
31109
31167
|
const r = resolution();
|