@neat.is/core 0.5.0 → 0.5.1-dev.20260719

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/neatd.js CHANGED
@@ -2,11 +2,11 @@
2
2
  import {
3
3
  reconcileDaemonRecordSync,
4
4
  startDaemon
5
- } from "./chunk-5MGHWP6R.js";
5
+ } from "./chunk-O4PCNQFG.js";
6
6
  import {
7
7
  listProjects,
8
8
  registryPath
9
- } from "./chunk-QQDZSIY3.js";
9
+ } from "./chunk-BI3XKGVG.js";
10
10
  import {
11
11
  BindAuthorityError,
12
12
  __require
package/dist/server.cjs CHANGED
@@ -3166,6 +3166,7 @@ function ensureFrontierNode(graph, host, ts) {
3166
3166
  }
3167
3167
  function upsertObservedEdge(graph, type, source, target, ts, isError = false, evidence) {
3168
3168
  if (!graph.hasNode(source) || !graph.hasNode(target)) return null;
3169
+ const grain = source.startsWith("file:") ? "file" : "service";
3169
3170
  const id = makeObservedEdgeId(type, source, target);
3170
3171
  if (graph.hasEdge(id)) {
3171
3172
  const existing = graph.getEdgeAttributes(id);
@@ -3182,7 +3183,9 @@ function upsertObservedEdge(graph, type, source, target, ts, isError = false, ev
3182
3183
  lastObserved: ts,
3183
3184
  callCount: newSpanCount,
3184
3185
  signal: newSignal,
3185
- confidence: (0, import_types4.confidenceForObservedSignal)(newSignal)
3186
+ confidence: (0, import_types4.confidenceForObservedSignal)(newSignal),
3187
+ grain
3188
+ // backfills legacy edges that predate ADR-142
3186
3189
  };
3187
3190
  graph.replaceEdgeAttributes(id, updated);
3188
3191
  return { edge: updated, created: false };
@@ -3202,6 +3205,7 @@ function upsertObservedEdge(graph, type, source, target, ts, isError = false, ev
3202
3205
  lastObserved: ts,
3203
3206
  callCount: 1,
3204
3207
  signal,
3208
+ grain,
3205
3209
  // Call-site evidence from span code.* semconv (file-awareness.md §4 + §6).
3206
3210
  // Only set when code.filepath was present on the span — never fabricated.
3207
3211
  ...evidence ? { evidence } : {}
@@ -5263,6 +5267,15 @@ async function parse4(serviceDir) {
5263
5267
  const config = parseConnectionString(urlMatch[1]);
5264
5268
  if (config) return [{ ...config, sourceFile: filePath }];
5265
5269
  }
5270
+ const urlEnvMatch = content.match(
5271
+ /(?:url|connectionString)\s*:\s*process\.env(?:\.([A-Za-z_$][\w$]*)|\[\s*['"]([^'"]+)['"]\s*\])/
5272
+ );
5273
+ if (urlEnvMatch) {
5274
+ const varName = urlEnvMatch[1] ?? urlEnvMatch[2];
5275
+ const resolved = varName ? await resolveEnvVar(serviceDir, varName) : null;
5276
+ const config = resolved ? parseConnectionString(resolved) : null;
5277
+ if (config) return [{ ...config, sourceFile: filePath }];
5278
+ }
5266
5279
  const hostMatch = content.match(/host\s*:\s*['"`]([^'"`]+)['"`]/);
5267
5280
  if (hostMatch) {
5268
5281
  const portMatch = content.match(/port\s*:\s*(\d+)/);
@@ -5316,6 +5329,15 @@ async function parse5(serviceDir) {
5316
5329
  const config = parseConnectionString(urlMatch[1]);
5317
5330
  if (config) return [{ ...config, sourceFile: filePath }];
5318
5331
  }
5332
+ const urlEnvMatch = content.match(
5333
+ /connection\s*:\s*process\.env(?:\.([A-Za-z_$][\w$]*)|\[\s*['"]([^'"]+)['"]\s*\])/
5334
+ );
5335
+ if (urlEnvMatch) {
5336
+ const varName = urlEnvMatch[1] ?? urlEnvMatch[2];
5337
+ const resolved = varName ? await resolveEnvVar(serviceDir, varName) : null;
5338
+ const config = resolved ? parseConnectionString(resolved) : null;
5339
+ if (config) return [{ ...config, sourceFile: filePath }];
5340
+ }
5319
5341
  const host = content.match(/host\s*:\s*['"`]([^'"`]+)['"`]/)?.[1];
5320
5342
  if (host) {
5321
5343
  const port = content.match(/port\s*:\s*(\d+)/)?.[1];
@@ -6864,6 +6886,16 @@ function constructorMatchesImport(name, ctx) {
6864
6886
  if (name === "createClient") return ctx.hasSupabaseJs;
6865
6887
  return ctx.hasSupabaseSsr;
6866
6888
  }
6889
+ var SUPABASE_CLIENT_ASSIGN_RE = /(?:const|let|var)\s+(\w+)\s*=\s*(?:await\s+)?(createClient|createServerClient|createBrowserClient)\s*\(/g;
6890
+ function supabaseClientVars(content, ctx) {
6891
+ const vars = /* @__PURE__ */ new Set();
6892
+ SUPABASE_CLIENT_ASSIGN_RE.lastIndex = 0;
6893
+ let m;
6894
+ while ((m = SUPABASE_CLIENT_ASSIGN_RE.exec(content)) !== null) {
6895
+ if (constructorMatchesImport(m[2], ctx)) vars.add(m[1]);
6896
+ }
6897
+ return vars;
6898
+ }
6867
6899
  function supabaseEndpointsFromFile(file, serviceDir) {
6868
6900
  const ctx = readImports2(file.content);
6869
6901
  if (!ctx.hasSupabaseJs && !ctx.hasSupabaseSsr) return [];
@@ -6896,6 +6928,34 @@ function supabaseEndpointsFromFile(file, serviceDir) {
6896
6928
  }
6897
6929
  });
6898
6930
  }
6931
+ const clientVars = supabaseClientVars(file.content, ctx);
6932
+ for (const clientVar of clientVars) {
6933
+ const accessRe = new RegExp(
6934
+ `\\b${clientVar}\\s*\\.\\s*(from|rpc)\\s*\\(\\s*['"\`]([\\w.-]+)['"\`]`,
6935
+ "g"
6936
+ );
6937
+ let am;
6938
+ while ((am = accessRe.exec(file.content)) !== null) {
6939
+ const kind = am[1] === "rpc" ? "supabase-rpc" : "supabase-table";
6940
+ const resource = am[2];
6941
+ const key = `${kind}/${resource}`;
6942
+ if (seen.has(key)) continue;
6943
+ seen.add(key);
6944
+ const line = lineOf(file.content, am[0]);
6945
+ out.push({
6946
+ infraId: (0, import_types20.infraId)(kind, resource),
6947
+ name: resource,
6948
+ kind,
6949
+ edgeType: "CALLS",
6950
+ confidenceKind: "verified-call-site",
6951
+ evidence: {
6952
+ file: import_node_path32.default.relative(serviceDir, file.path),
6953
+ line,
6954
+ snippet: snippet(file.content, line)
6955
+ }
6956
+ });
6957
+ }
6958
+ }
6899
6959
  return out;
6900
6960
  }
6901
6961