@inerrata-corporation/errata 2.0.22-dev.4020 → 2.0.22-dev.4054

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/pass-worker.mjs CHANGED
@@ -959,10 +959,10 @@ function mergeDefs(...defs) {
959
959
  function cloneDef(schema) {
960
960
  return mergeDefs(schema._zod.def);
961
961
  }
962
- function getElementAtPath(obj, path) {
963
- if (!path)
962
+ function getElementAtPath(obj, path2) {
963
+ if (!path2)
964
964
  return obj;
965
- return path.reduce((acc, key) => acc?.[key], obj);
965
+ return path2.reduce((acc, key) => acc?.[key], obj);
966
966
  }
967
967
  function promiseAllObject(promisesObj) {
968
968
  const keys = Object.keys(promisesObj);
@@ -1274,11 +1274,11 @@ function aborted(x, startIndex = 0) {
1274
1274
  }
1275
1275
  return false;
1276
1276
  }
1277
- function prefixIssues(path, issues) {
1277
+ function prefixIssues(path2, issues) {
1278
1278
  return issues.map((iss) => {
1279
1279
  var _a2;
1280
1280
  (_a2 = iss).path ?? (_a2.path = []);
1281
- iss.path.unshift(path);
1281
+ iss.path.unshift(path2);
1282
1282
  return iss;
1283
1283
  });
1284
1284
  }
@@ -1520,7 +1520,7 @@ function formatError(error48, mapper = (issue2) => issue2.message) {
1520
1520
  }
1521
1521
  function treeifyError(error48, mapper = (issue2) => issue2.message) {
1522
1522
  const result = { errors: [] };
1523
- const processError = (error49, path = []) => {
1523
+ const processError = (error49, path2 = []) => {
1524
1524
  var _a2, _b;
1525
1525
  for (const issue2 of error49.issues) {
1526
1526
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -1530,7 +1530,7 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
1530
1530
  } else if (issue2.code === "invalid_element") {
1531
1531
  processError({ issues: issue2.issues }, issue2.path);
1532
1532
  } else {
1533
- const fullpath = [...path, ...issue2.path];
1533
+ const fullpath = [...path2, ...issue2.path];
1534
1534
  if (fullpath.length === 0) {
1535
1535
  result.errors.push(mapper(issue2));
1536
1536
  continue;
@@ -1562,8 +1562,8 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
1562
1562
  }
1563
1563
  function toDotPath(_path) {
1564
1564
  const segs = [];
1565
- const path = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1566
- for (const seg of path) {
1565
+ const path2 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1566
+ for (const seg of path2) {
1567
1567
  if (typeof seg === "number")
1568
1568
  segs.push(`[${seg}]`);
1569
1569
  else if (typeof seg === "symbol")
@@ -14257,13 +14257,13 @@ function resolveRef(ref, ctx) {
14257
14257
  if (!ref.startsWith("#")) {
14258
14258
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
14259
14259
  }
14260
- const path = ref.slice(1).split("/").filter(Boolean);
14261
- if (path.length === 0) {
14260
+ const path2 = ref.slice(1).split("/").filter(Boolean);
14261
+ if (path2.length === 0) {
14262
14262
  return ctx.rootSchema;
14263
14263
  }
14264
14264
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
14265
- if (path[0] === defsKey) {
14266
- const key = path[1];
14265
+ if (path2[0] === defsKey) {
14266
+ const key = path2[1];
14267
14267
  if (!key || !ctx.defs[key]) {
14268
14268
  throw new Error(`Reference not found: ${ref}`);
14269
14269
  }
@@ -15535,8 +15535,8 @@ function npmPurl(name2, version3) {
15535
15535
  function component(name2, version3) {
15536
15536
  return { purl: npmPurl(name2, version3), name: name2, version: version3, ecosystem: "npm" };
15537
15537
  }
15538
- function isNpmImporterPath(path) {
15539
- return path === "" || !path.includes("node_modules/");
15538
+ function isNpmImporterPath(path2) {
15539
+ return path2 === "" || !path2.includes("node_modules/");
15540
15540
  }
15541
15541
  function parsePackageLockJson(jsonText) {
15542
15542
  let doc;
@@ -15549,22 +15549,22 @@ function parsePackageLockJson(jsonText) {
15549
15549
  const components = [];
15550
15550
  const hoisted = /* @__PURE__ */ new Map();
15551
15551
  const byPath = /* @__PURE__ */ new Map();
15552
- for (const [path, meta3] of Object.entries(packages)) {
15553
- if (path === "" || meta3.link === true) continue;
15554
- const ix = path.lastIndexOf("node_modules/");
15552
+ for (const [path2, meta3] of Object.entries(packages)) {
15553
+ if (path2 === "" || meta3.link === true) continue;
15554
+ const ix = path2.lastIndexOf("node_modules/");
15555
15555
  if (ix === -1) continue;
15556
- const name2 = path.slice(ix + "node_modules/".length);
15556
+ const name2 = path2.slice(ix + "node_modules/".length);
15557
15557
  const version3 = typeof meta3.version === "string" ? meta3.version : "";
15558
15558
  if (!name2 || !version3) continue;
15559
15559
  components.push(component(name2, version3));
15560
- byPath.set(path, { name: name2, version: version3 });
15561
- const depth = path.split("node_modules/").length;
15560
+ byPath.set(path2, { name: name2, version: version3 });
15561
+ const depth = path2.split("node_modules/").length;
15562
15562
  const prev = hoisted.get(name2);
15563
15563
  if (!prev || depth < prev.depth) hoisted.set(name2, { version: version3, depth });
15564
15564
  }
15565
15565
  const dependencies = [];
15566
- for (const [path, meta3] of Object.entries(packages)) {
15567
- const self = byPath.get(path);
15566
+ for (const [path2, meta3] of Object.entries(packages)) {
15567
+ const self = byPath.get(path2);
15568
15568
  if (!self) continue;
15569
15569
  const deps = meta3.dependencies;
15570
15570
  if (!deps || typeof deps !== "object") continue;
@@ -15577,8 +15577,8 @@ function parsePackageLockJson(jsonText) {
15577
15577
  dependencies.push({ ref: npmPurl(self.name, self.version), dependsOn });
15578
15578
  }
15579
15579
  const directRaw = [];
15580
- for (const [path, meta3] of Object.entries(packages)) {
15581
- if (!isNpmImporterPath(path)) continue;
15580
+ for (const [path2, meta3] of Object.entries(packages)) {
15581
+ if (!isNpmImporterPath(path2)) continue;
15582
15582
  for (const section of [meta3.dependencies, meta3.devDependencies, meta3.optionalDependencies]) {
15583
15583
  if (!section || typeof section !== "object") continue;
15584
15584
  for (const name2 of Object.keys(section)) {
@@ -15825,31 +15825,31 @@ function basename(p) {
15825
15825
  const ix = p.lastIndexOf("/");
15826
15826
  return ix === -1 ? p : p.slice(ix + 1);
15827
15827
  }
15828
- function parseCsproj(path, text) {
15828
+ function parseCsproj(path2, text) {
15829
15829
  const deps = [];
15830
15830
  for (const m of text.matchAll(/<PackageReference\s+Include="([^"]+)"(?:\s+Version="([^"]+)")?/g)) {
15831
- deps.push({ ecosystem: "nuget", name: m[1] ?? "", version: m[2] ?? null, kind: "package", manifest: path });
15831
+ deps.push({ ecosystem: "nuget", name: m[1] ?? "", version: m[2] ?? null, kind: "package", manifest: path2 });
15832
15832
  }
15833
15833
  for (const m of text.matchAll(/<Project\s+Sdk="([^"/]+)(?:\/([^"]+))?"/g)) {
15834
15834
  const sdk = m[1] ?? "";
15835
15835
  if (sdk.toLowerCase() !== "microsoft.net.sdk") {
15836
- deps.push({ ecosystem: "nuget", name: sdk, version: m[2] ?? null, kind: "sdk", manifest: path });
15836
+ deps.push({ ecosystem: "nuget", name: sdk, version: m[2] ?? null, kind: "sdk", manifest: path2 });
15837
15837
  }
15838
15838
  }
15839
15839
  for (const m of text.matchAll(/<TargetFramework>([^<]+)<\/TargetFramework>/g)) {
15840
15840
  const mm = /^net(\d+\.\d+)/.exec((m[1] ?? "").trim());
15841
- if (mm) deps.push({ ecosystem: "dotnet", name: "dotnet", version: mm[1] ?? null, kind: "runtime", manifest: path });
15841
+ if (mm) deps.push({ ecosystem: "dotnet", name: "dotnet", version: mm[1] ?? null, kind: "runtime", manifest: path2 });
15842
15842
  }
15843
15843
  return deps;
15844
15844
  }
15845
- function parseGodot(path, text) {
15845
+ function parseGodot(path2, text) {
15846
15846
  const m = /config\/features=PackedStringArray\(([^)]*)\)/.exec(text);
15847
15847
  if (!m) return [];
15848
15848
  const feats = (m[1] ?? "").split(",").map((f) => f.trim().replace(/^"|"$/g, "")).filter((f) => f.length > 0);
15849
15849
  const version3 = feats.find((f) => /^\d+\.\d+/.test(f)) ?? null;
15850
- return [{ ecosystem: "godot", name: "godot", version: version3, kind: "engine", manifest: path }];
15850
+ return [{ ecosystem: "godot", name: "godot", version: version3, kind: "engine", manifest: path2 }];
15851
15851
  }
15852
- function parsePackageJson(path, text) {
15852
+ function parsePackageJson(path2, text) {
15853
15853
  let obj;
15854
15854
  try {
15855
15855
  obj = JSON.parse(text);
@@ -15863,7 +15863,7 @@ function parsePackageJson(path, text) {
15863
15863
  if (!section || typeof section !== "object") continue;
15864
15864
  for (const [name2, ver] of Object.entries(section)) {
15865
15865
  const version3 = ver ? String(ver) : null;
15866
- deps.push({ ecosystem: "npm", name: name2, version: version3, kind: "package", manifest: path });
15866
+ deps.push({ ecosystem: "npm", name: name2, version: version3, kind: "package", manifest: path2 });
15867
15867
  }
15868
15868
  }
15869
15869
  return deps;
@@ -15871,7 +15871,7 @@ function parsePackageJson(path, text) {
15871
15871
  function isPep508DirectRef(spec) {
15872
15872
  return /^[A-Za-z0-9][A-Za-z0-9._-]*(?:\[[^\]]*\])?\s*@\s*\S/.test(spec.trim());
15873
15873
  }
15874
- function parseRequirements(path, text) {
15874
+ function parseRequirements(path2, text) {
15875
15875
  const deps = [];
15876
15876
  for (const raw of text.split(/\r?\n/)) {
15877
15877
  const line = (raw.split("#", 1)[0] ?? "").trim();
@@ -15883,14 +15883,14 @@ function parseRequirements(path, text) {
15883
15883
  name: m[1] ?? "",
15884
15884
  version: m[2] ? m[3] ?? null : null,
15885
15885
  kind: "package",
15886
- manifest: path,
15886
+ manifest: path2,
15887
15887
  ...isPep508DirectRef(line) ? { directRef: true } : {}
15888
15888
  });
15889
15889
  }
15890
15890
  }
15891
15891
  return deps;
15892
15892
  }
15893
- function parsePyproject(path, text) {
15893
+ function parsePyproject(path2, text) {
15894
15894
  const deps = [];
15895
15895
  const m = /^\s*dependencies\s*=\s*\[([\s\S]*?)\]/m.exec(text);
15896
15896
  if (!m) return deps;
@@ -15903,14 +15903,14 @@ function parsePyproject(path, text) {
15903
15903
  name: mm[1] ?? "",
15904
15904
  version: null,
15905
15905
  kind: "package",
15906
- manifest: path,
15906
+ manifest: path2,
15907
15907
  ...isPep508DirectRef(spec) ? { directRef: true } : {}
15908
15908
  });
15909
15909
  }
15910
15910
  }
15911
15911
  return deps;
15912
15912
  }
15913
- function parseDocker(path, text) {
15913
+ function parseDocker(path2, text) {
15914
15914
  const deps = [];
15915
15915
  for (const m of text.matchAll(/^\s*(?:image:\s*|FROM\s+(?:--platform=\S+\s+)?)["']?([^\s"']+)/gm)) {
15916
15916
  const ref = m[1] ?? "";
@@ -15920,32 +15920,32 @@ function parseDocker(path, text) {
15920
15920
  const colon = undigested.indexOf(":");
15921
15921
  const name2 = colon === -1 ? undigested : undigested.slice(0, colon);
15922
15922
  const tag = colon === -1 ? "" : undigested.slice(colon + 1);
15923
- deps.push({ ecosystem: "docker", name: name2, version: tag || null, kind: "image", manifest: path });
15923
+ deps.push({ ecosystem: "docker", name: name2, version: tag || null, kind: "image", manifest: path2 });
15924
15924
  }
15925
15925
  return deps;
15926
15926
  }
15927
- function parseGoMod(path, text) {
15927
+ function parseGoMod(path2, text) {
15928
15928
  const deps = [];
15929
15929
  for (const m of text.matchAll(/^\s*(?:require\s+)?([a-z0-9.\-]+\.[a-z]+\/[^\s]+)\s+(v[^\s]+)/gm)) {
15930
15930
  const end = (m.index ?? 0) + m[0].length;
15931
15931
  if (text.slice(end, end + 20).includes("// indirect")) continue;
15932
- deps.push({ ecosystem: "golang", name: m[1] ?? "", version: m[2] ?? null, kind: "package", manifest: path });
15932
+ deps.push({ ecosystem: "golang", name: m[1] ?? "", version: m[2] ?? null, kind: "package", manifest: path2 });
15933
15933
  }
15934
15934
  return deps;
15935
15935
  }
15936
- function parseCargo(path, text) {
15936
+ function parseCargo(path2, text) {
15937
15937
  const deps = [];
15938
15938
  const sec = /^\[dependencies\]([\s\S]*?)(?=^\[|(?![\s\S]))/m.exec(text);
15939
15939
  if (!sec) return deps;
15940
15940
  for (const m of (sec[1] ?? "").matchAll(/^\s*([A-Za-z0-9_-]+)\s*=\s*(?:"([^"]+)"|\{[^}]*version\s*=\s*"([^"]+)")/gm)) {
15941
- deps.push({ ecosystem: "cargo", name: m[1] ?? "", version: m[2] ?? m[3] ?? null, kind: "package", manifest: path });
15941
+ deps.push({ ecosystem: "cargo", name: m[1] ?? "", version: m[2] ?? m[3] ?? null, kind: "package", manifest: path2 });
15942
15942
  }
15943
15943
  return deps;
15944
15944
  }
15945
15945
  function mavenName(groupId, artifactId) {
15946
15946
  return `${groupId.trim()}:${artifactId.trim()}`;
15947
15947
  }
15948
- function parsePom(path, text) {
15948
+ function parsePom(path2, text) {
15949
15949
  const deps = [];
15950
15950
  const coord = (block) => {
15951
15951
  const g = /<groupId>([^<]+)<\/groupId>/.exec(block)?.[1];
@@ -15955,15 +15955,15 @@ function parsePom(path, text) {
15955
15955
  };
15956
15956
  for (const m of text.matchAll(/<dependency>([\s\S]*?)<\/dependency>/g)) {
15957
15957
  const c = coord(m[1] ?? "");
15958
- if (c) deps.push({ ecosystem: "maven", name: mavenName(c.g, c.a), version: c.v, kind: "package", manifest: path });
15958
+ if (c) deps.push({ ecosystem: "maven", name: mavenName(c.g, c.a), version: c.v, kind: "package", manifest: path2 });
15959
15959
  }
15960
15960
  for (const m of text.matchAll(/<parent>([\s\S]*?)<\/parent>/g)) {
15961
15961
  const c = coord(m[1] ?? "");
15962
- if (c) deps.push({ ecosystem: "maven", name: mavenName(c.g, c.a), version: c.v, kind: "sdk", manifest: path });
15962
+ if (c) deps.push({ ecosystem: "maven", name: mavenName(c.g, c.a), version: c.v, kind: "sdk", manifest: path2 });
15963
15963
  }
15964
15964
  return deps;
15965
15965
  }
15966
- function parseGradle(path, text) {
15966
+ function parseGradle(path2, text) {
15967
15967
  const deps = [];
15968
15968
  const re = new RegExp(`\\b(?:${GRADLE_CONFIGS})\\s*(?:\\(\\s*)?["']([^"']+)["']`, "g");
15969
15969
  for (const m of text.matchAll(re)) {
@@ -15975,12 +15975,12 @@ function parseGradle(path, text) {
15975
15975
  name: mavenName(group, artifact),
15976
15976
  version: version3?.trim() || null,
15977
15977
  kind: "package",
15978
- manifest: path
15978
+ manifest: path2
15979
15979
  });
15980
15980
  }
15981
15981
  return deps;
15982
15982
  }
15983
- function parseVersionCatalog(path, text) {
15983
+ function parseVersionCatalog(path2, text) {
15984
15984
  const section = /^\s*\[libraries\]([\s\S]*?)(?=^\s*\[|(?![\s\S]))/m.exec(text);
15985
15985
  if (!section) return [];
15986
15986
  const deps = [];
@@ -15991,34 +15991,34 @@ function parseVersionCatalog(path, text) {
15991
15991
  if (module2) {
15992
15992
  const [group2, artifact2] = module2.split(":");
15993
15993
  if (group2 && artifact2) {
15994
- deps.push({ ecosystem: "maven", name: mavenName(group2, artifact2), version: version3, kind: "package", manifest: path });
15994
+ deps.push({ ecosystem: "maven", name: mavenName(group2, artifact2), version: version3, kind: "package", manifest: path2 });
15995
15995
  }
15996
15996
  continue;
15997
15997
  }
15998
15998
  const group = /\bgroup\s*=\s*["']([^"']+)["']/.exec(line)?.[1];
15999
15999
  const artifact = /\bname\s*=\s*["']([^"']+)["']/.exec(line)?.[1];
16000
16000
  if (group && artifact) {
16001
- deps.push({ ecosystem: "maven", name: mavenName(group, artifact), version: version3, kind: "package", manifest: path });
16001
+ deps.push({ ecosystem: "maven", name: mavenName(group, artifact), version: version3, kind: "package", manifest: path2 });
16002
16002
  }
16003
16003
  }
16004
16004
  return deps;
16005
16005
  }
16006
- function parseGemfile(path, text) {
16006
+ function parseGemfile(path2, text) {
16007
16007
  const deps = [];
16008
16008
  for (const raw of text.split(/\r?\n/)) {
16009
16009
  const line = (raw.split("#", 1)[0] ?? "").trim();
16010
16010
  const m = /^gem\s+["']([^"']+)["']\s*(?:,\s*["']([^"']+)["'])?/.exec(line);
16011
16011
  if (!m?.[1]) continue;
16012
- deps.push({ ecosystem: "gem", name: m[1], version: m[2] ?? null, kind: "package", manifest: path });
16012
+ deps.push({ ecosystem: "gem", name: m[1], version: m[2] ?? null, kind: "package", manifest: path2 });
16013
16013
  }
16014
16014
  return deps;
16015
16015
  }
16016
- function parseGemspec(path, text) {
16016
+ function parseGemspec(path2, text) {
16017
16017
  const deps = [];
16018
16018
  for (const m of text.matchAll(
16019
16019
  /\.add_(?:runtime_|development_)?dependency\s*\(?\s*["']([^"']+)["']\s*(?:,\s*["']([^"']+)["'])?/g
16020
16020
  )) {
16021
- if (m[1]) deps.push({ ecosystem: "gem", name: m[1], version: m[2] ?? null, kind: "package", manifest: path });
16021
+ if (m[1]) deps.push({ ecosystem: "gem", name: m[1], version: m[2] ?? null, kind: "package", manifest: path2 });
16022
16022
  }
16023
16023
  return deps;
16024
16024
  }
@@ -16039,8 +16039,8 @@ function pomSelf(text) {
16039
16039
  if (artifact) self.push({ ecosystem: "maven", kind: "name", value: mavenName(group, artifact) });
16040
16040
  return self;
16041
16041
  }
16042
- function parseManifestSelf(path, text) {
16043
- const file2 = basename(path);
16042
+ function parseManifestSelf(path2, text) {
16043
+ const file2 = basename(path2);
16044
16044
  if (file2 === "package.json") {
16045
16045
  let obj;
16046
16046
  try {
@@ -16082,23 +16082,23 @@ function parseManifestSelf(path, text) {
16082
16082
  }
16083
16083
  return [];
16084
16084
  }
16085
- function parseManifest(path, text) {
16086
- const name2 = basename(path);
16087
- if (name2.endsWith(".csproj") || name2.endsWith(".fsproj")) return parseCsproj(path, text);
16088
- if (name2 === "project.godot") return parseGodot(path, text);
16089
- if (name2 === "package.json") return parsePackageJson(path, text);
16090
- if (name2.startsWith("requirements") && name2.endsWith(".txt")) return parseRequirements(path, text);
16091
- if (name2 === "pyproject.toml") return parsePyproject(path, text);
16085
+ function parseManifest(path2, text) {
16086
+ const name2 = basename(path2);
16087
+ if (name2.endsWith(".csproj") || name2.endsWith(".fsproj")) return parseCsproj(path2, text);
16088
+ if (name2 === "project.godot") return parseGodot(path2, text);
16089
+ if (name2 === "package.json") return parsePackageJson(path2, text);
16090
+ if (name2.startsWith("requirements") && name2.endsWith(".txt")) return parseRequirements(path2, text);
16091
+ if (name2 === "pyproject.toml") return parsePyproject(path2, text);
16092
16092
  if (name2.startsWith("docker-compose") || name2.startsWith("compose") || name2.startsWith("Dockerfile")) {
16093
- return parseDocker(path, text);
16094
- }
16095
- if (name2 === "go.mod") return parseGoMod(path, text);
16096
- if (name2 === "libs.versions.toml") return parseVersionCatalog(path, text);
16097
- if (name2 === "Cargo.toml") return parseCargo(path, text);
16098
- if (name2 === "pom.xml") return parsePom(path, text);
16099
- if (name2 === "build.gradle" || name2 === "build.gradle.kts") return parseGradle(path, text);
16100
- if (name2 === "Gemfile") return parseGemfile(path, text);
16101
- if (name2.endsWith(".gemspec")) return parseGemspec(path, text);
16093
+ return parseDocker(path2, text);
16094
+ }
16095
+ if (name2 === "go.mod") return parseGoMod(path2, text);
16096
+ if (name2 === "libs.versions.toml") return parseVersionCatalog(path2, text);
16097
+ if (name2 === "Cargo.toml") return parseCargo(path2, text);
16098
+ if (name2 === "pom.xml") return parsePom(path2, text);
16099
+ if (name2 === "build.gradle" || name2 === "build.gradle.kts") return parseGradle(path2, text);
16100
+ if (name2 === "Gemfile") return parseGemfile(path2, text);
16101
+ if (name2.endsWith(".gemspec")) return parseGemspec(path2, text);
16102
16102
  return [];
16103
16103
  }
16104
16104
  function buildSpine(sha2, manifestPaths2, readText) {
@@ -16387,13 +16387,13 @@ function loadNodeSqlite() {
16387
16387
  process.emitWarning = original;
16388
16388
  }
16389
16389
  }
16390
- function openDatabase(path, opts) {
16391
- const db = opts ? new DatabaseSync(path, opts) : new DatabaseSync(path);
16390
+ function openDatabase(path2, opts) {
16391
+ const db = opts ? new DatabaseSync(path2, opts) : new DatabaseSync(path2);
16392
16392
  try {
16393
16393
  db.exec("PRAGMA foreign_keys = ON");
16394
16394
  } catch {
16395
16395
  }
16396
- if (path !== ":memory:" && !opts?.readOnly) {
16396
+ if (path2 !== ":memory:" && !opts?.readOnly) {
16397
16397
  try {
16398
16398
  db.exec("PRAGMA journal_mode = WAL");
16399
16399
  db.exec("PRAGMA synchronous = NORMAL");
@@ -16874,11 +16874,12 @@ function purgeWorkspaceCodeGraph(store2, workspaceId) {
16874
16874
  const edgesBefore = store2.edgeCount();
16875
16875
  store2.transaction(() => {
16876
16876
  for (const label of INDEXER_OWNED_LABELS) {
16877
- const nodes = store2.findAllVersionsByLabel(label);
16877
+ const nodes = store2.selectNodes({
16878
+ labels: [label],
16879
+ includeClosed: true,
16880
+ where: [{ attr: "workspaceId", eq: workspaceId }]
16881
+ });
16878
16882
  for (const n of nodes) {
16879
- if (n.attrs.workspaceId !== workspaceId) {
16880
- continue;
16881
- }
16882
16883
  store2.deleteNode(n.id);
16883
16884
  nodesDeleted++;
16884
16885
  }
@@ -18328,14 +18329,14 @@ function unmarshalNode(tree, address = TRANSFER_BUFFER) {
18328
18329
  address += SIZE_OF_INT;
18329
18330
  const row = C.getValue(address, "i32");
18330
18331
  address += SIZE_OF_INT;
18331
- const column = C.getValue(address, "i32");
18332
+ const column2 = C.getValue(address, "i32");
18332
18333
  address += SIZE_OF_INT;
18333
18334
  const other = C.getValue(address, "i32");
18334
18335
  const result = new Node(INTERNAL, {
18335
18336
  id,
18336
18337
  tree,
18337
18338
  startIndex: index,
18338
- startPosition: { row, column },
18339
+ startPosition: { row, column: column2 },
18339
18340
  other
18340
18341
  });
18341
18342
  return result;
@@ -18425,11 +18426,11 @@ async function Module2(moduleArg = {}) {
18425
18426
  }, "quit_");
18426
18427
  var _scriptName = import.meta.url;
18427
18428
  var scriptDirectory = "";
18428
- function locateFile(path) {
18429
+ function locateFile(path2) {
18429
18430
  if (Module["locateFile"]) {
18430
- return Module["locateFile"](path, scriptDirectory);
18431
+ return Module["locateFile"](path2, scriptDirectory);
18431
18432
  }
18432
- return scriptDirectory + path;
18433
+ return scriptDirectory + path2;
18433
18434
  }
18434
18435
  __name(locateFile, "locateFile");
18435
18436
  var readAsync, readBinary;
@@ -19581,11 +19582,11 @@ async function Module2(moduleArg = {}) {
19581
19582
  }
19582
19583
  }
19583
19584
  __name(_tree_sitter_log_callback, "_tree_sitter_log_callback");
19584
- function _tree_sitter_parse_callback(inputBufferAddress, index, row, column, lengthAddress) {
19585
+ function _tree_sitter_parse_callback(inputBufferAddress, index, row, column2, lengthAddress) {
19585
19586
  const INPUT_BUFFER_SIZE = 10 * 1024;
19586
19587
  const string4 = Module.currentParseCallback(index, {
19587
19588
  row,
19588
- column
19589
+ column: column2
19589
19590
  });
19590
19591
  if (typeof string4 === "string") {
19591
19592
  setValue(lengthAddress, string4.length, "i32");
@@ -23523,9 +23524,9 @@ function extractNode3(node, containerQname, containerIsClass, source) {
23523
23524
  ];
23524
23525
  }
23525
23526
  case "preproc_include": {
23526
- const path = node.childForFieldName("path")?.text;
23527
- if (!path) return [];
23528
- const src = path.replace(/^[<"]|[>"]$/g, "");
23527
+ const path2 = node.childForFieldName("path")?.text;
23528
+ if (!path2) return [];
23529
+ const src = path2.replace(/^[<"]|[>"]$/g, "");
23529
23530
  return [
23530
23531
  {
23531
23532
  kind: "import",
@@ -23913,9 +23914,9 @@ function importRecords(node) {
23913
23914
  if (n.type === "import_spec") specs.push(n);
23914
23915
  });
23915
23916
  for (const spec of specs) {
23916
- const path = spec.childForFieldName("path")?.text;
23917
- if (!path) continue;
23918
- const src = path.replace(/^["`]|["`]$/g, "");
23917
+ const path2 = spec.childForFieldName("path")?.text;
23918
+ if (!path2) continue;
23919
+ const src = path2.replace(/^["`]|["`]$/g, "");
23919
23920
  out2.push({
23920
23921
  kind: "import",
23921
23922
  name: src,
@@ -24998,16 +24999,16 @@ function baseTypeName(node) {
24998
24999
  }
24999
25000
  function usingPath(node) {
25000
25001
  const alias = node.childForFieldName("name");
25001
- let path = null;
25002
+ let path2 = null;
25002
25003
  for (let i2 = 0; i2 < node.namedChildCount; i2++) {
25003
25004
  const c = node.namedChild(i2);
25004
25005
  if (!c) continue;
25005
25006
  if (alias && c.startIndex === alias.startIndex && c.endIndex === alias.endIndex) continue;
25006
25007
  if (c.type === "qualified_name" || c.type === "identifier" || c.type === "generic_name") {
25007
- path = c;
25008
+ path2 = c;
25008
25009
  }
25009
25010
  }
25010
- return path?.text ?? null;
25011
+ return path2?.text ?? null;
25011
25012
  }
25012
25013
  function calleeName4(fn) {
25013
25014
  if (!fn) return null;
@@ -25515,6 +25516,38 @@ function installHistoryAttrSlim(db) {
25515
25516
  db.prepare("INSERT INTO store_meta(key,value) VALUES (?,?)").run(HISTORY_ATTR_SLIM_KEY, "done");
25516
25517
  }
25517
25518
 
25519
+ // ../../packages/local-graph/src/text-index.ts
25520
+ var TEXT_INDEX_KEY = "text-index-trigram-1";
25521
+ var TEXT_INDEX_MIN_TERM = 3;
25522
+ function installTextIndex(db) {
25523
+ if (db.prepare("SELECT value FROM store_meta WHERE key = ?").get(TEXT_INDEX_KEY)) return;
25524
+ try {
25525
+ db.exec(`CREATE VIRTUAL TABLE temp.fts5_probe USING fts5(x, tokenize='trigram'); DROP TABLE temp.fts5_probe`);
25526
+ } catch {
25527
+ db.prepare("INSERT INTO store_meta(key,value) VALUES (?,?)").run(TEXT_INDEX_KEY, "unavailable");
25528
+ return;
25529
+ }
25530
+ db.transaction(() => {
25531
+ db.exec(`CREATE VIRTUAL TABLE IF NOT EXISTS nodes_text
25532
+ USING fts5(description, content='nodes', content_rowid='rowid', tokenize='trigram')`);
25533
+ db.exec(`CREATE TRIGGER IF NOT EXISTS nodes_text_insert AFTER INSERT ON nodes WHEN NEW.valid_to IS NULL
25534
+ BEGIN INSERT INTO nodes_text(rowid, description) VALUES (NEW.rowid, NEW.description); END;`);
25535
+ db.exec(`CREATE TRIGGER IF NOT EXISTS nodes_text_update_out AFTER UPDATE OF description, valid_to ON nodes
25536
+ WHEN OLD.valid_to IS NULL
25537
+ BEGIN INSERT INTO nodes_text(nodes_text, rowid, description) VALUES ('delete', OLD.rowid, OLD.description); END;`);
25538
+ db.exec(`CREATE TRIGGER IF NOT EXISTS nodes_text_update_in AFTER UPDATE OF description, valid_to ON nodes
25539
+ WHEN NEW.valid_to IS NULL
25540
+ BEGIN INSERT INTO nodes_text(rowid, description) VALUES (NEW.rowid, NEW.description); END;`);
25541
+ db.exec(`CREATE TRIGGER IF NOT EXISTS nodes_text_delete AFTER DELETE ON nodes WHEN OLD.valid_to IS NULL
25542
+ BEGIN INSERT INTO nodes_text(nodes_text, rowid, description) VALUES ('delete', OLD.rowid, OLD.description); END;`);
25543
+ db.exec(`INSERT INTO nodes_text(rowid, description) SELECT rowid, description FROM nodes WHERE valid_to IS NULL`);
25544
+ db.prepare("INSERT INTO store_meta(key,value) VALUES (?,?)").run(TEXT_INDEX_KEY, "installed");
25545
+ });
25546
+ }
25547
+ function textIndexReady(db) {
25548
+ return db.prepare("SELECT value FROM store_meta WHERE key = ?").get(TEXT_INDEX_KEY)?.["value"] === "installed";
25549
+ }
25550
+
25518
25551
  // ../../packages/math/src/pagerank.ts
25519
25552
  function pagerank(input) {
25520
25553
  const damping = input.damping ?? 0.85;
@@ -25961,6 +25994,140 @@ function pagerankLocal(input) {
25961
25994
  return { scores, iterations: iter, converged };
25962
25995
  }
25963
25996
 
25997
+ // ../../packages/local-graph/src/node-select.ts
25998
+ var EMBEDDING_DIM_SQL = "(CASE WHEN length(embedding_blob) >= 4 THEN length(embedding_blob) / 4 ELSE COALESCE(json_array_length(embedding_json), 0) END)";
25999
+ var KEY = /^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$/;
26000
+ var COLUMNS = /* @__PURE__ */ new Set([
26001
+ "created_at",
26002
+ "last_updated_at",
26003
+ "page_rank",
26004
+ "created_at_seq",
26005
+ "last_reinforced_at_seq",
26006
+ "cumulative_hits",
26007
+ "extraction_confidence"
26008
+ ]);
26009
+ function path(key) {
26010
+ if (!KEY.test(key)) throw new Error(`selectNodes: bad attr key ${key}`);
26011
+ return `'$.${key}'`;
26012
+ }
26013
+ function column(c) {
26014
+ if (!COLUMNS.has(c)) throw new Error(`selectNodes: bad column ${c}`);
26015
+ return c;
26016
+ }
26017
+ function compileNodeWhere(q) {
26018
+ if (q.labels.length === 0) throw new Error("selectNodes: no labels");
26019
+ const params = [...q.labels];
26020
+ const conds = [`label IN (${q.labels.map(() => "?").join(", ")})`];
26021
+ if (!q.includeClosed) conds.push("valid_to IS NULL");
26022
+ for (const w of q.where ?? []) {
26023
+ if ("embedding" in w) {
26024
+ conds.push(`${EMBEDDING_DIM_SQL} ${w.embedding === "present" ? ">" : "="} 0`);
26025
+ } else if ("idPrefix" in w) {
26026
+ conds.push("substr(id, 1, ?) = ?");
26027
+ params.push(w.idPrefix.length, w.idPrefix);
26028
+ } else if ("descriptionIn" in w) {
26029
+ if (w.descriptionIn.length === 0) conds.push("0");
26030
+ else {
26031
+ conds.push(`description IN (${w.descriptionIn.map(() => "?").join(", ")})`);
26032
+ params.push(...w.descriptionIn);
26033
+ }
26034
+ } else if ("column" in w) {
26035
+ const c = column(w.column);
26036
+ for (const [op, sym] of [["gte", ">="], ["gt", ">"], ["lte", "<="], ["lt", "<"]]) {
26037
+ const v = w[op];
26038
+ if (v !== void 0) {
26039
+ conds.push(`${c} ${sym} ?`);
26040
+ params.push(v);
26041
+ }
26042
+ }
26043
+ } else {
26044
+ const p = path(w.attr);
26045
+ if ("absent" in w) conds.push(`json_type(attrs_json, ${p}) IS NULL`);
26046
+ else if ("present" in w) conds.push(`json_type(attrs_json, ${p}) IS NOT NULL`);
26047
+ else if ("nullish" in w) conds.push(`json_extract(attrs_json, ${p}) IS NULL`);
26048
+ else if ("notNullish" in w) conds.push(`json_extract(attrs_json, ${p}) IS NOT NULL`);
26049
+ else if ("eq" in w || "ne" in w) {
26050
+ const v = "eq" in w ? w.eq : w.ne;
26051
+ const neg = "ne" in w;
26052
+ if (typeof v === "boolean") {
26053
+ conds.push(`json_type(attrs_json, ${p}) ${neg ? "IS NOT" : "="} ?`);
26054
+ params.push(v ? "true" : "false");
26055
+ } else {
26056
+ conds.push(neg ? `json_extract(attrs_json, ${p}) IS NOT ?` : `json_extract(attrs_json, ${p}) = ?`);
26057
+ params.push(v);
26058
+ }
26059
+ }
26060
+ }
26061
+ }
26062
+ return { where: conds.join(" AND "), params };
26063
+ }
26064
+ function attrValueSql(p) {
26065
+ return `CASE json_type(attrs_json, ${p}) WHEN 'integer' THEN CAST(json_extract(attrs_json, ${p}) AS REAL) ELSE json_extract(attrs_json, ${p}) END`;
26066
+ }
26067
+ function compileNodeSelect(q) {
26068
+ const { where, params } = compileNodeWhere(q);
26069
+ const attrs = q.attrs ?? [];
26070
+ const attrCols = attrs.map((k, i2) => `, ${attrValueSql(path(k))} AS a${i2}, json_type(attrs_json, ${path(k)}) AS t${i2}`).join("");
26071
+ let order;
26072
+ if (q.orderBy && "column" in q.orderBy) {
26073
+ order = `${column(q.orderBy.column)} ${q.orderBy.desc ? "DESC" : "ASC"}, rowid`;
26074
+ } else if (q.orderBy) {
26075
+ const p = path(q.orderBy.attr);
26076
+ order = `json_extract(attrs_json, ${p}) IS NULL, json_extract(attrs_json, ${p}) ${q.orderBy.desc ? "DESC" : "ASC"}, rowid`;
26077
+ } else if (q.labels.length > 1) {
26078
+ order = `CASE label ${q.labels.map((_, i2) => `WHEN ? THEN ${i2}`).join(" ")} END, rowid`;
26079
+ } else {
26080
+ order = "rowid";
26081
+ }
26082
+ const orderParams = !q.orderBy && q.labels.length > 1 ? [...q.labels] : [];
26083
+ const limit = q.limit !== void 0 ? ` LIMIT ${Math.max(0, Math.floor(q.limit))}` : "";
26084
+ const sql = `SELECT id, label, description, created_at, last_updated_at, page_rank, cumulative_hits, extraction_confidence, extraction_source, community, created_at_seq, last_reinforced_at_seq, valid_to, ${EMBEDDING_DIM_SQL} AS embedding_dim${q.withEmbedding ? ", embedding_blob, embedding_json" : ""}${attrCols} FROM nodes WHERE ${where} ORDER BY ${order}${limit}`;
26085
+ return { sql, params: [...params, ...orderParams] };
26086
+ }
26087
+ function decodeAttr(value, type) {
26088
+ switch (type) {
26089
+ case null:
26090
+ case void 0:
26091
+ return void 0;
26092
+ case "true":
26093
+ return true;
26094
+ case "false":
26095
+ return false;
26096
+ case "null":
26097
+ return null;
26098
+ case "object":
26099
+ case "array":
26100
+ return typeof value === "string" ? JSON.parse(value) : value;
26101
+ default:
26102
+ return value;
26103
+ }
26104
+ }
26105
+ function decodeSelectedRow(r, attrs, decodeVector) {
26106
+ const out2 = {};
26107
+ attrs.forEach((k, i2) => {
26108
+ const v = decodeAttr(r[`a${i2}`], r[`t${i2}`]);
26109
+ if (v !== void 0) out2[k] = v;
26110
+ });
26111
+ return {
26112
+ id: r["id"],
26113
+ label: r["label"],
26114
+ description: r["description"] ?? "",
26115
+ createdAt: r["created_at"],
26116
+ lastUpdatedAt: r["last_updated_at"],
26117
+ pageRank: r["page_rank"],
26118
+ cumulativeHits: r["cumulative_hits"],
26119
+ extractionConfidence: r["extraction_confidence"],
26120
+ extractionSource: r["extraction_source"],
26121
+ community: r["community"] ?? null,
26122
+ ...r["created_at_seq"] != null ? { createdAtSeq: r["created_at_seq"] } : {},
26123
+ ...r["last_reinforced_at_seq"] != null ? { lastReinforcedAtSeq: r["last_reinforced_at_seq"] } : {},
26124
+ validTo: r["valid_to"] ?? null,
26125
+ embeddingDim: Number(r["embedding_dim"] ?? 0),
26126
+ ...decodeVector ? { embedding: decodeVector(r["embedding_blob"], r["embedding_json"] ?? "[]") } : {},
26127
+ attrs: out2
26128
+ };
26129
+ }
26130
+
25964
26131
  // ../../packages/local-graph/src/store.ts
25965
26132
  var PAGE_RANK_SCALE_KEY = "pageRankScale.p95.v1";
25966
26133
  var TEXT_SEARCH_COLUMNS = `id, label, description, page_rank,
@@ -26149,6 +26316,11 @@ CREATE INDEX IF NOT EXISTS nodes_cloud_node_id ON nodes(json_extract(attrs_json,
26149
26316
  -- Solution's and Problem's attrs per call. Not partial: the Problem pull reads
26150
26317
  -- closed versions too.
26151
26318
  CREATE INDEX IF NOT EXISTS nodes_enrichment_pending ON nodes(json_extract(attrs_json, '$.enrichmentPending'));
26319
+ -- Revisit flags, any label, any version: listNeedsRevisit's as-of read runs on
26320
+ -- every context render and otherwise json-checks every row (10.3 s on a 324k-row
26321
+ -- store, to return zero flags). The predicate must stay textually identical to
26322
+ -- nodesAsOfWhereTrue's or the planner will not use it.
26323
+ CREATE INDEX IF NOT EXISTS nodes_revisit_true ON nodes(valid_from) WHERE json_type(attrs_json, '$.revisit') = 'true';
26152
26324
  `;
26153
26325
  function encodeEmbedding(emb) {
26154
26326
  if (!emb || emb.length === 0) return null;
@@ -26249,6 +26421,7 @@ var SqliteGraphStore = class {
26249
26421
  installEditPlaceholderRetirement(this.db);
26250
26422
  installCloudAttrCompaction(this.db);
26251
26423
  installHistoryAttrSlim(this.db);
26424
+ installTextIndex(this.db);
26252
26425
  if (!this.db.prepare("SELECT value FROM store_meta WHERE key = ?").get(SESSION_REPAIR_KEY)) {
26253
26426
  this.db.transaction(() => {
26254
26427
  this.repairSessionAliases();
@@ -26626,8 +26799,8 @@ var SqliteGraphStore = class {
26626
26799
  setLandmark(id, isLandmark) {
26627
26800
  this.stmts.setLandmark.run({ id, v: isLandmark ? 1 : 0 });
26628
26801
  }
26629
- setLocalCommunity(id, community, column) {
26630
- this.stmts.setLocalCommunity.run({ id, v: community, col: column ? 1 : 0 });
26802
+ setLocalCommunity(id, community, column2) {
26803
+ this.stmts.setLocalCommunity.run({ id, v: community, col: column2 ? 1 : 0 });
26631
26804
  }
26632
26805
  fieldStmts = /* @__PURE__ */ new Map();
26633
26806
  findNodeFieldsByLabel(label, attrKeys) {
@@ -26635,7 +26808,7 @@ var SqliteGraphStore = class {
26635
26808
  const cacheKey = attrKeys.join(",");
26636
26809
  let stmt = this.fieldStmts.get(cacheKey);
26637
26810
  if (!stmt) {
26638
- const cols = attrKeys.map((k, i2) => `, json_extract(attrs_json, '$.${k}') AS a${i2}`).join("");
26811
+ const cols = attrKeys.map((k, i2) => `, ${attrValueSql(`'$.${k}'`)} AS a${i2}, json_type(attrs_json, '$.${k}') AS t${i2}`).join("");
26639
26812
  stmt = this.db.prepare(
26640
26813
  `SELECT id, description, community, extraction_confidence${cols} FROM nodes WHERE label = ? AND valid_to IS NULL`
26641
26814
  );
@@ -26644,8 +26817,8 @@ var SqliteGraphStore = class {
26644
26817
  return stmt.all(label).map((r) => {
26645
26818
  const attrs = {};
26646
26819
  attrKeys.forEach((k, i2) => {
26647
- const v = r[`a${i2}`];
26648
- if (v !== null && v !== void 0) attrs[k] = v;
26820
+ const v = decodeAttr(r[`a${i2}`], r[`t${i2}`]);
26821
+ if (v !== void 0) attrs[k] = v;
26649
26822
  });
26650
26823
  return {
26651
26824
  id: r["id"],
@@ -26656,6 +26829,15 @@ var SqliteGraphStore = class {
26656
26829
  };
26657
26830
  });
26658
26831
  }
26832
+ selectNodes(q) {
26833
+ const { sql, params } = compileNodeSelect(q);
26834
+ const rows = this.db.prepare(sql).all(...params);
26835
+ return rows.map((r) => decodeSelectedRow(r, q.attrs ?? [], q.withEmbedding ? decodeEmbedding : void 0));
26836
+ }
26837
+ countNodes(q) {
26838
+ const { where, params } = compileNodeWhere(q);
26839
+ return Number(this.db.prepare(`SELECT COUNT(*) AS n FROM nodes WHERE ${where}`).get(...params).n);
26840
+ }
26659
26841
  setCommunity(id, community) {
26660
26842
  this.stmts.setCommunity.run({ id, v: community });
26661
26843
  }
@@ -26903,6 +27085,20 @@ var SqliteGraphStore = class {
26903
27085
  }
26904
27086
  searchTextCandidates(terms) {
26905
27087
  if (terms.length === 0) return [];
27088
+ const indexed = terms.filter((t) => t.length >= TEXT_INDEX_MIN_TERM);
27089
+ if (indexed.length > 0 && textIndexReady(this.db)) {
27090
+ const short = terms.filter((t) => t.length < TEXT_INDEX_MIN_TERM).map((t) => t.toLowerCase());
27091
+ const rows2 = this.db.prepare(`WITH hits AS MATERIALIZED (
27092
+ SELECT t.rowid AS rid, COUNT(*) AS matched FROM json_each(:terms) q, nodes_text t
27093
+ WHERE t.description LIKE '%' || q.value || '%' GROUP BY t.rowid
27094
+ ) SELECT ${TEXT_SEARCH_COLUMNS}, hits.matched FROM hits JOIN nodes ON nodes.rowid = hits.rid
27095
+ WHERE nodes.valid_to IS NULL ORDER BY page_rank DESC, last_updated_at DESC`).all({ terms: JSON.stringify(indexed) });
27096
+ return rows2.map((row) => {
27097
+ const text = row.description.toLowerCase();
27098
+ const extra = short.filter((t) => text.includes(t)).length;
27099
+ return { node: textSearchNode(row), matched: row.matched + extra };
27100
+ });
27101
+ }
26906
27102
  const rows = this.db.prepare(`WITH matches AS MATERIALIZED (
26907
27103
  SELECT n.id, COUNT(*) AS matched FROM nodes n INDEXED BY nodes_live_description, json_each(:terms) t
26908
27104
  WHERE n.valid_to IS NULL AND n.description LIKE '%' || t.value || '%'
@@ -26911,6 +27107,18 @@ var SqliteGraphStore = class {
26911
27107
  JOIN matches USING (id) ORDER BY page_rank DESC, last_updated_at DESC`).all({ terms: JSON.stringify(terms) });
26912
27108
  return rows.map((row) => ({ node: textSearchNode(row), matched: row.matched }));
26913
27109
  }
27110
+ commentAnchors(commentIds) {
27111
+ const out2 = /* @__PURE__ */ new Map();
27112
+ if (commentIds.length === 0) return out2;
27113
+ const rows = this.db.prepare(`WITH a AS MATERIALIZED (
27114
+ SELECT q.value AS cid, COALESCE(
27115
+ (SELECT to_id FROM edges WHERE from_id = q.value AND type IN ('EXPLAINS', 'ANNOTATES') AND valid_to IS NULL LIMIT 1),
27116
+ (SELECT from_id FROM edges WHERE to_id = q.value AND type = 'DOCUMENTED_BY' AND valid_to IS NULL LIMIT 1)
27117
+ ) AS aid FROM json_each(:ids) q
27118
+ ) SELECT a.cid AS cid, ${TEXT_SEARCH_COLUMNS} FROM a JOIN nodes ON nodes.id = a.aid AND nodes.valid_to IS NULL`).all({ ids: JSON.stringify(commentIds) });
27119
+ for (const row of rows) out2.set(row.cid, textSearchNode(row));
27120
+ return out2;
27121
+ }
26914
27122
  getTextSearchNode(id) {
26915
27123
  const row = this.db.prepare(`SELECT ${TEXT_SEARCH_COLUMNS} FROM nodes WHERE id = ? AND valid_to IS NULL`).get(id);
26916
27124
  return row ? textSearchNode(row) : null;
@@ -27306,7 +27514,8 @@ var SqliteGraphStore = class {
27306
27514
  if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(attr)) throw new Error(`nodesAsOfWhereTrue: bad attr ${JSON.stringify(attr)}`);
27307
27515
  const rows = this.db.prepare(
27308
27516
  `SELECT * FROM nodes WHERE valid_from <= :t AND (valid_to IS NULL OR valid_to > :t)
27309
- AND json_type(attrs_json, '$.${attr}') = 'true'`
27517
+ AND json_type(attrs_json, '$.${attr}') = 'true'
27518
+ ORDER BY rowid`
27310
27519
  ).all({ t });
27311
27520
  return rows.map(rowToNode);
27312
27521
  }
@@ -27566,7 +27775,7 @@ var NAME_SEPARATOR = /[@/\-._]/;
27566
27775
  var MIN_NAME_LEN = 3;
27567
27776
  function buildPackageIndex(store2) {
27568
27777
  const idx = /* @__PURE__ */ new Map();
27569
- for (const n of store2.findNodesByLabel("Package")) {
27778
+ for (const n of store2.selectNodes({ labels: ["Package"], attrs: ["name", "resolved"] })) {
27570
27779
  const name2 = String(n.attrs["name"] ?? "").trim();
27571
27780
  if (!name2) continue;
27572
27781
  const key = name2.toLowerCase();
@@ -27633,7 +27842,7 @@ function backfillProblemPackageLinks(store2, ts) {
27633
27842
  const report = { problems: 0, edges: 0 };
27634
27843
  const idx = buildPackageIndex(store2);
27635
27844
  if (idx.size === 0) return report;
27636
- for (const p of store2.findNodesByLabel("Problem")) {
27845
+ for (const p of store2.selectNodes({ labels: ["Problem"], attrs: ["resolvedAs"] })) {
27637
27846
  if (p.attrs["resolvedAs"] === "false_positive") continue;
27638
27847
  const { linked } = linkProblemToPackages(store2, p.id, problemText(store2, p), ts, idx);
27639
27848
  if (linked.length > 0) {
@@ -27673,7 +27882,7 @@ function deriveContextFromAnchors(store2, problemId, ts, pkgIndex) {
27673
27882
  if (!p || p.label !== "Problem" && p.label !== "Vulnerability") return report;
27674
27883
  const files = store2.outEdges(problemId, ["ANCHORED_AT"]).map((e) => store2.getNode(e.to)).filter((n) => !!n && n.label === "File");
27675
27884
  if (files.length === 0) return report;
27676
- const idx = pkgIndex ?? buildPackageIndex(store2);
27885
+ let idx = pkgIndex;
27677
27886
  const haveLang = new Set(store2.outEdges(problemId, ["OCCURS_IN"]).map((e) => e.to));
27678
27887
  const havePkg = new Set(store2.outEdges(problemId, ["DEPENDS_ON"]).map((e) => e.to));
27679
27888
  for (const file2 of files) {
@@ -27712,7 +27921,7 @@ function deriveContextFromAnchors(store2, problemId, ts, pkgIndex) {
27712
27921
  if (!mod) continue;
27713
27922
  const name2 = specToPackageName(mod.description);
27714
27923
  if (!name2) continue;
27715
- const pkg = idx.get(name2);
27924
+ const pkg = (idx ??= buildPackageIndex(store2)).get(name2);
27716
27925
  if (!pkg || havePkg.has(pkg.id)) continue;
27717
27926
  addDependency(store2, {
27718
27927
  fromId: problemId,
@@ -27731,7 +27940,7 @@ function deriveContextFromAnchors(store2, problemId, ts, pkgIndex) {
27731
27940
  function backfillProblemContext(store2, ts) {
27732
27941
  const report = { problems: 0, edges: 0 };
27733
27942
  const idx = buildPackageIndex(store2);
27734
- for (const p of store2.findNodesByLabel("Problem")) {
27943
+ for (const p of store2.selectNodes({ labels: ["Problem"], attrs: ["resolvedAs"] })) {
27735
27944
  if (p.attrs["resolvedAs"] === "false_positive") continue;
27736
27945
  const r = deriveContextFromAnchors(store2, p.id, ts, idx);
27737
27946
  const n = r.languages.length + r.packages.length;
@@ -27757,6 +27966,11 @@ var REDIRECT_EDGES = [
27757
27966
  "MANIFESTED_IN",
27758
27967
  "EVIDENCED_BY"
27759
27968
  ];
27969
+ var OPEN_PROBLEM_WHERE = [
27970
+ { attr: "resolvedAt", nullish: true },
27971
+ { attr: "mergedInto", absent: true }
27972
+ ];
27973
+ var OPEN_PROBLEM_KEYS = ["kind", "corroborations"];
27760
27974
  function corroborations(n) {
27761
27975
  return Number(n.attrs["corroborations"] ?? 0);
27762
27976
  }
@@ -27770,7 +27984,7 @@ function mergeDuplicateProblems(store2, opts) {
27770
27984
  const minOverlap = opts.minOverlap ?? 0.85;
27771
27985
  const minTokens = opts.minTokens ?? 4;
27772
27986
  const report = { clusters: 0, merged: 0 };
27773
- const open = store2.findNodesByLabel("Problem").filter((p) => p.attrs["resolvedAt"] == null && p.attrs["mergedInto"] === void 0);
27987
+ const open = store2.selectNodes({ labels: ["Problem"], attrs: OPEN_PROBLEM_KEYS, where: OPEN_PROBLEM_WHERE });
27774
27988
  const tokens = /* @__PURE__ */ new Map();
27775
27989
  for (const p of open) tokens.set(p.id, new Set(retrievalTokens(p.description)));
27776
27990
  const consumed = /* @__PURE__ */ new Set();
@@ -27794,8 +28008,9 @@ function mergeDuplicateProblems(store2, opts) {
27794
28008
  if (cluster.length < 2) continue;
27795
28009
  report.clusters++;
27796
28010
  cluster.sort((x, y) => corroborations(y) - corroborations(x) || x.createdAt - y.createdAt);
27797
- const survivor = cluster[0];
27798
- for (const dup of cluster.slice(1)) {
28011
+ const members = cluster.map((m) => store2.getNode(m.id)).filter((n) => n !== null);
28012
+ const survivor = members[0];
28013
+ for (const dup of members.slice(1)) {
27799
28014
  foldDuplicateProblem(store2, dup, survivor, opts.ts);
27800
28015
  report.merged++;
27801
28016
  }
@@ -27848,11 +28063,21 @@ function isConstraintProblem(node) {
27848
28063
  return node.attrs["kind"] === "constraint";
27849
28064
  }
27850
28065
  var RECURRENCE_DEBOUNCE_MS = 60 * 60 * 1e3;
27851
- function resolveFileNode(store2, path, workspaceId) {
27852
- const want = path.trim().replace(/^\.?\//, "");
27853
- for (const n of store2.findNodesByLabel("File")) {
27854
- if (n.attrs["workspaceId"] && n.attrs["workspaceId"] !== workspaceId) continue;
27855
- if (n.attrs["relPath"] === want || n.description === want) return n;
28066
+ function resolveFileNode(store2, path2, workspaceId) {
28067
+ const want = path2.trim().replace(/^\.?\//, "");
28068
+ const id = firstFileByPath(store2, want, (a) => !(a["workspaceId"] && a["workspaceId"] !== workspaceId));
28069
+ return id ? store2.getNode(id) : null;
28070
+ }
28071
+ function firstFileByPath(store2, want, accept) {
28072
+ const byPath = store2.selectNodes({ labels: ["File"], attrs: ["workspaceId"], where: [{ attr: "relPath", eq: want }] }).find((r) => accept(r.attrs))?.id;
28073
+ const described = store2.liveNodesByDescription([want], ["File"]).filter((n) => accept(n.attrs));
28074
+ const byDescription = described.length === 1 ? described[0].id : void 0;
28075
+ if (described.length <= 1 && (byPath === void 0 || byDescription === void 0 || byPath === byDescription)) {
28076
+ return byPath ?? byDescription ?? null;
28077
+ }
28078
+ for (const r of store2.selectNodes({ labels: ["File"], attrs: ["workspaceId", "relPath"] })) {
28079
+ if (!accept(r.attrs)) continue;
28080
+ if (r.attrs["relPath"] === want || r.description === want) return r.id;
27856
28081
  }
27857
28082
  return null;
27858
28083
  }
@@ -27868,13 +28093,8 @@ function isAutoMinted(n) {
27868
28093
  }
27869
28094
  function priorsForFile(store2, relPath) {
27870
28095
  const want = relPath.trim().replace(/^\.?\//, "");
27871
- let file2 = null;
27872
- for (const n of store2.findNodesByLabel("File")) {
27873
- if (n.description === want || n.attrs["relPath"] === want) {
27874
- file2 = n;
27875
- break;
27876
- }
27877
- }
28096
+ const fileId = firstFileByPath(store2, want, () => true);
28097
+ const file2 = fileId ? store2.getNode(fileId) : null;
27878
28098
  if (!file2) return null;
27879
28099
  const openProblems = [];
27880
28100
  const constraints = [];
@@ -28064,10 +28284,10 @@ function openAnchorHint(p) {
28064
28284
  if (!h || typeof h.path !== "string" || h.upgradedAt) return null;
28065
28285
  return { path: h.path, ts: typeof h.ts === "number" ? h.ts : 0 };
28066
28286
  }
28067
- function consumeAnchorHint(store2, p, ts) {
28287
+ function consumeAnchorHint(store2, p, ts, pkgIndex) {
28068
28288
  const hint = p.attrs["anchorHint"];
28069
28289
  store2.updateNode(p.id, { attrs: { ...p.attrs, anchorHint: { ...hint, upgradedAt: ts } } });
28070
- deriveContextFromAnchors(store2, p.id, ts);
28290
+ deriveContextFromAnchors(store2, p.id, ts, pkgIndex);
28071
28291
  }
28072
28292
  function upgradeAnchorHints(store2, workspaceId, ts) {
28073
28293
  let upgraded = 0;
@@ -28075,14 +28295,20 @@ function upgradeAnchorHints(store2, workspaceId, ts) {
28075
28295
  let unresolvable = 0;
28076
28296
  let blocked = 0;
28077
28297
  const filesByPath = /* @__PURE__ */ new Map();
28078
- for (const f of store2.findNodesByLabel("File")) {
28298
+ for (const f of store2.selectNodes({ labels: ["File"], attrs: ["workspaceId", "relPath", "contentChangedAt"] })) {
28079
28299
  if (f.attrs["workspaceId"] && f.attrs["workspaceId"] !== workspaceId) continue;
28080
28300
  const rel = typeof f.attrs["relPath"] === "string" ? f.attrs["relPath"] : f.description;
28081
28301
  if (rel && !filesByPath.has(rel)) filesByPath.set(rel, f);
28082
28302
  }
28083
- for (const p of store2.findNodesByLabel("Problem")) {
28084
- if (p.validTo != null || p.attrs["resolvedAt"]) continue;
28085
- const hint = openAnchorHint(p);
28303
+ let pkgIndex;
28304
+ const hinted = store2.selectNodes({
28305
+ labels: ["Problem"],
28306
+ attrs: ["resolvedAt", "anchorHint"],
28307
+ where: [{ attr: "anchorHint", notNullish: true }]
28308
+ });
28309
+ for (const row of hinted) {
28310
+ if (row.attrs["resolvedAt"]) continue;
28311
+ const hint = openAnchorHint(row);
28086
28312
  if (!hint) continue;
28087
28313
  const file2 = filesByPath.get(hint.path.trim().replace(/^\.?\//, ""));
28088
28314
  if (!file2 || !isAnchorableCodePath(hint.path)) {
@@ -28092,8 +28318,10 @@ function upgradeAnchorHints(store2, workspaceId, ts) {
28092
28318
  standing++;
28093
28319
  const changedAt = Number(file2.attrs["contentChangedAt"] ?? 0);
28094
28320
  if (changedAt <= hint.ts) continue;
28321
+ const p = store2.getNode(row.id);
28322
+ if (!p) continue;
28095
28323
  if (anchorProblemToWorkingFile(store2, p.id, hint.path, workspaceId, ts, "hint-confirmed")) {
28096
- consumeAnchorHint(store2, p, ts);
28324
+ consumeAnchorHint(store2, p, ts, pkgIndex ??= buildPackageIndex(store2));
28097
28325
  upgraded++;
28098
28326
  standing--;
28099
28327
  } else {
@@ -28104,7 +28332,12 @@ function upgradeAnchorHints(store2, workspaceId, ts) {
28104
28332
  }
28105
28333
  function reopenAutoClosedProblems(store2, t) {
28106
28334
  const report = { reopened: 0, alreadySuspect: 0, agentDescribed: 0 };
28107
- for (const p of store2.findNodesByLabel("Problem")) {
28335
+ const closed = store2.selectNodes({
28336
+ labels: ["Problem"],
28337
+ attrs: ["resolvedAt", "resolvedAs", "mergedInto", "resolutionWitnessed", "retiredEditPlaceholder", "resolutionSuspect"],
28338
+ where: [{ attr: "resolvedAt", notNullish: true }, { attr: "resolvedAs", nullish: true }, { attr: "mergedInto", absent: true }]
28339
+ });
28340
+ for (const p of closed) {
28108
28341
  if (p.attrs["resolvedAt"] == null) continue;
28109
28342
  if (p.attrs["resolvedAs"] != null) continue;
28110
28343
  if (p.attrs["mergedInto"] !== void 0) continue;
@@ -28119,7 +28352,9 @@ function reopenAutoClosedProblems(store2, t) {
28119
28352
  continue;
28120
28353
  }
28121
28354
  if (p.attrs["resolutionSuspect"] === true) report.alreadySuspect++;
28122
- const attrs = { ...p.attrs };
28355
+ const node = store2.getNode(p.id);
28356
+ if (!node) continue;
28357
+ const attrs = { ...node.attrs };
28123
28358
  delete attrs["resolvedAt"];
28124
28359
  attrs["reopenedFrom"] = "auto-close";
28125
28360
  attrs["reopenedAt"] = t;
@@ -28130,7 +28365,12 @@ function reopenAutoClosedProblems(store2, t) {
28130
28365
  }
28131
28366
  function markFixCandidates(store2, t) {
28132
28367
  let resolved = 0;
28133
- for (const p of store2.findNodesByLabel("Problem")) {
28368
+ const candidates = store2.selectNodes({
28369
+ labels: ["Problem"],
28370
+ attrs: ["resolvedAt", "kind", "fixCandidateClearedAt", "fixCandidateAt"],
28371
+ where: [{ idPrefix: "dprob_" }]
28372
+ });
28373
+ for (const p of candidates) {
28134
28374
  if (!p.id.startsWith("dprob_")) continue;
28135
28375
  if (p.attrs["resolvedAt"]) continue;
28136
28376
  if (isConstraintProblem(p)) continue;
@@ -28157,9 +28397,11 @@ function markFixCandidates(store2, t) {
28157
28397
  return s !== null && !String(s.description ?? "").startsWith(AUTO_MINT_PREFIX);
28158
28398
  }))
28159
28399
  continue;
28400
+ const node = store2.getNode(p.id);
28401
+ if (!node) continue;
28160
28402
  store2.updateNode(p.id, {
28161
28403
  attrs: {
28162
- ...p.attrs,
28404
+ ...node.attrs,
28163
28405
  // The cue, kept as structured data so the render can name the file it is
28164
28406
  // asking about. Deliberately NOT `resolvedAt` — this is a question.
28165
28407
  fixCandidateAt: t,
@@ -28169,7 +28411,7 @@ function markFixCandidates(store2, t) {
28169
28411
  // measurable. `shownCount` is the node's LIFETIME count across every
28170
28412
  // band, so comparing it raw would retire a fresh ask on a
28171
28413
  // frequently-surfaced problem before anyone had seen the question once.
28172
- fixCandidateShownBase: Number(p.attrs["shownCount"] ?? 0)
28414
+ fixCandidateShownBase: Number(node.attrs["shownCount"] ?? 0)
28173
28415
  }
28174
28416
  // No `lastUpdatedAt`: raising a question is bookkeeping, not a new
28175
28417
  // observation of the problem, and the passive block's recent-problems band
@@ -28182,7 +28424,10 @@ function markFixCandidates(store2, t) {
28182
28424
  var FIX_CANDIDATE_ASK_LIMIT = 5;
28183
28425
  function clearSettledFixCandidates(store2, t) {
28184
28426
  const report = { answered: 0, ignored: 0, unsubstantiated: 0, standing: 0 };
28185
- for (const p of store2.findNodesByLabel("Problem")) {
28427
+ const asked = store2.selectNodes({ labels: ["Problem"], where: [{ attr: "fixCandidateAt", present: true }] });
28428
+ for (const row of asked) {
28429
+ const p = store2.getNode(row.id);
28430
+ if (!p) continue;
28186
28431
  if (p.attrs["fixCandidateAt"] === void 0) continue;
28187
28432
  const fileAnchors = store2.outEdges(p.id, ["ANCHORED_AT"]).filter((e) => e.attrs?.["mention"] !== true && e.attrs?.["anchorProvenance"] !== "legacy").map((e) => store2.getNode(e.to)).filter((n) => n !== null && n.label === "File");
28188
28433
  const unsubstantiated = fileAnchors.length > 0 && fileAnchors.every((f) => f.attrs["contentChangedAt"] === void 0);
@@ -28237,9 +28482,9 @@ var STATEMENT_PATH_RE = new RegExp(
28237
28482
  );
28238
28483
  function filePathResolver(store2) {
28239
28484
  const byPath = /* @__PURE__ */ new Map();
28240
- for (const f of store2.findNodesByLabel("File")) {
28241
- const path = String(f.attrs["relPath"] ?? f.description ?? "");
28242
- if (path) byPath.set(path, { id: f.id, path });
28485
+ for (const f of store2.selectNodes({ labels: ["File"], attrs: ["relPath"] })) {
28486
+ const path2 = String(f.attrs["relPath"] ?? f.description ?? "");
28487
+ if (path2) byPath.set(path2, { id: f.id, path: path2 });
28243
28488
  }
28244
28489
  return (named) => {
28245
28490
  const exact = byPath.get(named);
@@ -28283,7 +28528,7 @@ function repairLegacyAnchorsFromStatement(store2, ts) {
28283
28528
  alreadyCorrect: 0
28284
28529
  };
28285
28530
  const resolvePath = filePathResolver(store2);
28286
- for (const p of store2.findNodesByLabel("Problem")) {
28531
+ for (const p of store2.selectNodes({ labels: ["Problem"] })) {
28287
28532
  try {
28288
28533
  const anchors = store2.outEdges(p.id, ["ANCHORED_AT"]);
28289
28534
  const legacy = anchors.filter((e) => e.attrs?.["anchorProvenance"] === "legacy");
@@ -28347,10 +28592,12 @@ function backfillLegacyAnchors(store2, ts) {
28347
28592
  suspects: []
28348
28593
  };
28349
28594
  let resolvePath;
28350
- for (const p of store2.findNodesByLabel("Problem")) {
28351
- const resolved = p.attrs["resolvedAt"] !== void 0;
28352
- const legacy = store2.outEdges(p.id, ["ANCHORED_AT"]).filter((e) => isLegacyAnchor(e.attrs) || !resolved && e.attrs?.["anchorProvenance"] === "legacy");
28595
+ for (const row of store2.selectNodes({ labels: ["Problem"], attrs: ["resolvedAt"] })) {
28596
+ const resolved = row.attrs["resolvedAt"] !== void 0;
28597
+ const legacy = store2.outEdges(row.id, ["ANCHORED_AT"]).filter((e) => isLegacyAnchor(e.attrs) || !resolved && e.attrs?.["anchorProvenance"] === "legacy");
28353
28598
  if (legacy.length === 0) continue;
28599
+ const p = store2.getNode(row.id);
28600
+ if (!p) continue;
28354
28601
  try {
28355
28602
  if (!resolved) {
28356
28603
  resolvePath ??= filePathResolver(store2);
@@ -28365,8 +28612,8 @@ function backfillLegacyAnchors(store2, ts) {
28365
28612
  const retired = legacy.filter((e) => !(target && e.to === target.id));
28366
28613
  for (const e of retired) {
28367
28614
  const file2 = store2.getNode(e.to);
28368
- const path = String(file2?.attrs["relPath"] ?? file2?.description ?? "");
28369
- if (path) recordAnchorHint(store2, p.id, path, "legacy", ts);
28615
+ const path2 = String(file2?.attrs["relPath"] ?? file2?.description ?? "");
28616
+ if (path2) recordAnchorHint(store2, p.id, path2, "legacy", ts);
28370
28617
  store2.closeEdge(e.id, ts);
28371
28618
  report.demotedEdges++;
28372
28619
  }
@@ -28491,7 +28738,7 @@ function detectLocalCommunities(store2, opts = {}) {
28491
28738
  for (const n of unowned) {
28492
28739
  const pulled = n.attrs["source"] === "cloud";
28493
28740
  const clearColumn = !!n.community && !pulled;
28494
- if (n.attrs["localCommunity"] === void 0 && !clearColumn) continue;
28741
+ if (n.attrs["localCommunity"] == null && !clearColumn) continue;
28495
28742
  store2.setLocalCommunity(n.id, null, clearColumn);
28496
28743
  if (clearColumn) report.cleared++;
28497
28744
  }
@@ -28559,13 +28806,13 @@ function detectLocalCommunities(store2, opts = {}) {
28559
28806
  // ../../packages/local-graph/src/tools.ts
28560
28807
  init_src();
28561
28808
  function rankToolsForHandles(store2, limit = 5) {
28562
- const scored = store2.findNodesByLabel("Tool").map((node) => ({
28563
- node,
28564
- concerns: store2.inEdges(node.id, ["CONCERNS"]).length,
28565
- hits: node.cumulativeHits ?? 0
28809
+ const scored = store2.selectNodes({ labels: ["Tool"] }).map((row) => ({
28810
+ id: row.id,
28811
+ concerns: store2.inEdges(row.id, ["CONCERNS"]).length,
28812
+ hits: row.cumulativeHits ?? 0
28566
28813
  }));
28567
28814
  scored.sort((a, b) => b.concerns - a.concerns || b.hits - a.hits);
28568
- return scored.slice(0, Math.max(0, limit)).map((s) => s.node);
28815
+ return scored.slice(0, Math.max(0, limit)).map((s) => store2.getNode(s.id)).filter((n) => n !== null);
28569
28816
  }
28570
28817
 
28571
28818
  // ../../packages/local-graph/src/principle-sync.ts
@@ -28846,10 +29093,10 @@ function evaluateFed(store2, d) {
28846
29093
  return { count: count2, total, fraction: total === 0 ? 0 : count2 / total };
28847
29094
  }
28848
29095
  if (!d.fed) return { count: 0, total: 0, fraction: 0 };
28849
- const column = COLUMN_INPUTS[d.fed.attr];
29096
+ const column2 = COLUMN_INPUTS[d.fed.attr];
28850
29097
  const fed = d.fed;
28851
29098
  const nodes = fed.labels.flatMap((label) => store2.findNodeStampsByLabel ? store2.findNodeStampsByLabel(label, fed.attr) : store2.findNodeAttrsByLabel(label));
28852
- const has = (n) => column ? column(n) : n.has ?? n.attrs?.[fed.attr] !== void 0;
29099
+ const has = (n) => column2 ? column2(n) : n.has ?? n.attrs?.[fed.attr] !== void 0;
28853
29100
  let window2 = nodes;
28854
29101
  if (fed.recent !== void 0) {
28855
29102
  window2 = [...nodes].sort((a, b) => b.createdAt - a.createdAt).slice(0, fed.recent);
@@ -29036,14 +29283,12 @@ function promoteMotifs(store2, t) {
29036
29283
  }
29037
29284
  report.communities = byCommunity.size;
29038
29285
  const existing = /* @__PURE__ */ new Map();
29039
- for (const label of MOTIF_LABELS) {
29040
- for (const node of store2.findNodesByLabel(label)) {
29041
- if (!node.id.startsWith("motif_")) continue;
29042
- const edges = store2.inEdges(node.id, ["INSTANCE_OF"]).filter(isDerived);
29043
- const remembered = node.attrs["memberIds"];
29044
- const members = new Set(Array.isArray(remembered) ? remembered : edges.map((e) => e.from));
29045
- existing.set(node.id, { node, edges, members });
29046
- }
29286
+ for (const row of store2.selectNodes({ labels: MOTIF_LABELS, where: [{ idPrefix: "motif_" }] })) {
29287
+ const node = store2.getNode(row.id);
29288
+ const edges = store2.inEdges(node.id, ["INSTANCE_OF"]).filter(isDerived);
29289
+ const remembered = node.attrs["memberIds"];
29290
+ const members = new Set(Array.isArray(remembered) ? remembered : edges.map((e) => e.from));
29291
+ existing.set(node.id, { node, edges, members });
29047
29292
  }
29048
29293
  const pairs = [];
29049
29294
  for (const [cid, members] of byCommunity) {
@@ -29490,18 +29735,36 @@ function rankMotifs(pool, signal, k = MOTIF_BAND) {
29490
29735
  if (!signal) return pool.slice(0, k);
29491
29736
  return pool.filter((m) => (signal.get(m.id) ?? 0) > 0).sort((a, b) => signal.get(b.id) - signal.get(a.id) || b.pageRank - a.pageRank).slice(0, k);
29492
29737
  }
29738
+ var HISTORY_POLICY_ATTRS = ["source", "extractionSource", "historyQuality", "validationSource", "attrsJson"];
29739
+ function passiveAllowed(row, atCommit) {
29740
+ return historyReadPolicy({ extractionSource: row.extractionSource, attrs: row.attrs }, { mode: "passive", atCommit }).allow;
29741
+ }
29742
+ var PROBLEM_BAND_ATTRS = [
29743
+ "mergedInto",
29744
+ "resolvedAt",
29745
+ "resolvedAs",
29746
+ "kind",
29747
+ "shownSinceTouch",
29748
+ "shownSinceTouchAt",
29749
+ ...HISTORY_POLICY_ATTRS
29750
+ ];
29493
29751
  function buildSnapshot(opts) {
29494
- const problems = [...opts.store.findNodesByLabel("Problem"), ...opts.store.findNodesByLabel("Vulnerability")].filter((p) => p.attrs["mergedInto"] === void 0 && historyReadPolicy(p, { mode: "passive", atCommit: opts.atCommit }).allow);
29752
+ const hydrate = (id) => opts.store.getNode(id);
29753
+ const problems = opts.store.selectNodes({ labels: ["Problem", "Vulnerability"], attrs: PROBLEM_BAND_ATTRS }).filter((p) => p.attrs["mergedInto"] === void 0 && passiveAllowed(p, opts.atCommit));
29495
29754
  const stillOpen = problems.filter((p) => p.attrs["resolvedAt"] == null);
29496
29755
  const allProblems = rankRecentBand(stillOpen.filter((p) => !isConstraintProblem(p)));
29497
29756
  const openPool = allProblems.slice(0, RECENT_OPEN * SCOPE_POOL_FACTOR).map((p) => ({
29498
- node: p,
29757
+ node: hydrate(p.id),
29499
29758
  anchors: opts.store.outEdges(p.id, ["MANIFESTED_IN", "EVIDENCED_BY"])
29500
29759
  }));
29501
29760
  const recent = openPool.slice(0, RECENT_OPEN);
29502
- const constraintPool = rankRecentBand(stillOpen.filter((p) => isConstraintProblem(p)), { window: RECENT_WINDOW_BANDS * RECENT_CONSTRAINTS }).slice(0, RECENT_CONSTRAINTS * SCOPE_POOL_FACTOR);
29761
+ const constraintPool = rankRecentBand(stillOpen.filter((p) => isConstraintProblem(p)), { window: RECENT_WINDOW_BANDS * RECENT_CONSTRAINTS }).slice(0, RECENT_CONSTRAINTS * SCOPE_POOL_FACTOR).map((p) => hydrate(p.id));
29503
29762
  const recentConstraints = constraintPool.slice(0, RECENT_CONSTRAINTS);
29504
- const regressions = problems.filter((p) => p.attrs["resolvedAt"] == null && p.attrs["mergedInto"] === void 0).flatMap(
29763
+ const regressionSources = /* @__PURE__ */ new Set();
29764
+ for (const target of opts.store.inDegreeByType(["REGRESSION_OF"]).keys()) {
29765
+ for (const e of opts.store.inEdges(target, ["REGRESSION_OF"])) regressionSources.add(e.from);
29766
+ }
29767
+ const regressions = problems.filter((p) => p.attrs["resolvedAt"] == null && p.attrs["mergedInto"] === void 0 && regressionSources.has(p.id)).map((p) => hydrate(p.id)).flatMap(
29505
29768
  (open) => opts.store.outEdges(open.id, ["REGRESSION_OF"]).flatMap((e) => {
29506
29769
  const closed = opts.store.getNode(e.to);
29507
29770
  if (!closed || closed.attrs["resolutionSuspect"] !== true || closed.attrs["resolvedAt"] == null) {
@@ -29516,18 +29779,14 @@ function buildSnapshot(opts) {
29516
29779
  const resolvedPool = problems.filter((p) => p.attrs["resolvedAt"] != null && p.attrs["resolvedAs"] == null).filter((p) => !regressionClosedIds.has(p.id)).sort((a, b) => Number(b.attrs["resolvedAt"] ?? 0) - Number(a.attrs["resolvedAt"] ?? 0)).slice(0, RECENT_RESOLVED * SCOPE_POOL_FACTOR).map((p) => {
29517
29780
  const solEdge = opts.store.outEdges(p.id, ["SOLVED_BY"])[0];
29518
29781
  const solution = solEdge ? opts.store.getNode(solEdge.to) ?? void 0 : void 0;
29519
- return { node: p, ...solution ? { solution } : {} };
29782
+ return { node: hydrate(p.id), ...solution ? { solution } : {} };
29520
29783
  });
29521
29784
  const recentResolved = resolvedPool.slice(0, RECENT_RESOLVED);
29522
- const motifPool = [
29523
- ...opts.store.findNodesByLabel("Pattern"),
29524
- ...opts.store.findNodesByLabel("Technique"),
29525
- ...opts.store.findNodesByLabel("AntiPattern")
29526
- ].filter((n) => historyReadPolicy(n, { mode: "passive", atCommit: opts.atCommit }).allow).filter((n) => !(Number(n.attrs["missedRuns"] ?? 0) > 0)).sort((a, b) => b.pageRank - a.pageRank).slice(0, MOTIF_POOL).map((n) => n.embedding.length > 0 ? { ...n, embedding: [] } : n);
29785
+ const motifPool = opts.store.selectNodes({ labels: ["Pattern", "Technique", "AntiPattern"], attrs: ["missedRuns", ...HISTORY_POLICY_ATTRS] }).filter((n) => passiveAllowed(n, opts.atCommit)).filter((n) => !(Number(n.attrs["missedRuns"] ?? 0) > 0)).sort((a, b) => b.pageRank - a.pageRank).slice(0, MOTIF_POOL).map((r) => hydrate(r.id)).map((n) => n.embedding.length > 0 ? { ...n, embedding: [] } : n);
29527
29786
  const motifs = rankMotifs(motifPool, void 0);
29528
29787
  const workingFile = opts.workingFile ? sliceForFile(opts.store, opts.workingFile, opts.atCommit) : void 0;
29529
29788
  const byEpisode = /* @__PURE__ */ new Map();
29530
- for (const sol of opts.store.findNodesByLabel("Solution")) {
29789
+ for (const sol of opts.store.findLiveNodesByAttr("Solution", "enrichmentPending", 1)) {
29531
29790
  if (!historyReadPolicy(sol, { mode: "passive", atCommit: opts.atCommit }).allow) continue;
29532
29791
  if (sol.attrs["enrichmentPending"] !== true) continue;
29533
29792
  const ep = sol.attrs["episodeId"] ?? sol.id;
@@ -29558,13 +29817,14 @@ function buildSnapshot(opts) {
29558
29817
  const matchNode = (cands, key) => {
29559
29818
  const k = norm(key);
29560
29819
  if (k.length < 2) return null;
29561
- return cands.find((n) => norm(n.description ?? "") === k) ?? cands.find((n) => {
29820
+ const hit = cands.find((n) => norm(n.description ?? "") === k) ?? cands.find((n) => {
29562
29821
  const d = norm(n.description ?? "");
29563
29822
  return d.length >= 2 && (d.includes(k) || k.includes(d));
29564
- }) ?? null;
29823
+ });
29824
+ return hit ? hydrate(hit.id) : null;
29565
29825
  };
29566
- const langNodes = opts.store.findNodesByLabel("Language");
29567
- const pkgNodes = opts.store.findNodesByLabel("Package");
29826
+ const langNodes = opts.store.selectNodes({ labels: ["Language"] });
29827
+ const pkgNodes = opts.store.selectNodes({ labels: ["Package"] });
29568
29828
  const toolNodes = rankToolsForHandles(opts.store, 5);
29569
29829
  const profileContext = {
29570
29830
  languages: opts.profile.languages.map((name2) => ({ name: name2, node: matchNode(langNodes, name2) })),
@@ -29615,8 +29875,8 @@ var RECENT_RESOLVED = 4;
29615
29875
  var RECENT_CONSTRAINTS = 3;
29616
29876
  var SCOPE_POOL_FACTOR = 3;
29617
29877
  function sliceForFile(store2, relPath, atCommit) {
29618
- const candidates = store2.findNodesByLabel("File");
29619
- const file2 = candidates.find((n) => n.description === relPath);
29878
+ const hit = store2.selectNodes({ labels: ["File"], where: [{ descriptionIn: [relPath] }], limit: 1 })[0];
29879
+ const file2 = hit ? store2.getNode(hit.id) : null;
29620
29880
  if (!file2) return void 0;
29621
29881
  const symbols = [];
29622
29882
  for (const e of store2.outEdges(file2.id, ["DEFINES"])) {
@@ -30114,9 +30374,9 @@ function readDirectDependencies(root) {
30114
30374
  const hit = directCache.get(root);
30115
30375
  if (hit && hit.key === key) return hit.direct;
30116
30376
  const direct = [];
30117
- for (const { c, path } of found) {
30377
+ for (const { c, path: path2 } of found) {
30118
30378
  try {
30119
- direct.push(...c.parse(readFileSync3(path, "utf8")).direct ?? []);
30379
+ direct.push(...c.parse(readFileSync3(path2, "utf8")).direct ?? []);
30120
30380
  } catch {
30121
30381
  }
30122
30382
  }
@@ -30199,7 +30459,7 @@ function scanManifests(root) {
30199
30459
  try {
30200
30460
  const spine = buildSpine("workspace", [...texts.keys()], (p) => texts.get(p) ?? "");
30201
30461
  scan2.deps = Object.values(spine.manifests).flat();
30202
- for (const [path, text] of texts) scan2.self.push(...parseManifestSelf(path, text));
30462
+ for (const [path2, text] of texts) scan2.self.push(...parseManifestSelf(path2, text));
30203
30463
  } catch {
30204
30464
  scan2.deps = [];
30205
30465
  scan2.self = [];