@neat.is/core 0.4.20-dev.20260620 → 0.4.20-dev.20260622

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/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  readDaemonRecord
4
- } from "./chunk-ZV7GHZ2D.js";
4
+ } from "./chunk-62ELQVIP.js";
5
5
  import {
6
6
  buildSearchIndex
7
7
  } from "./chunk-XOOCA5T7.js";
@@ -10,6 +10,7 @@ import {
10
10
  PolicyViolationsLog,
11
11
  ProjectNameCollisionError,
12
12
  Projects,
13
+ SCHEMA_VERSION,
13
14
  addCallEdges,
14
15
  addConfigNodes,
15
16
  addDatabasesAndCompat,
@@ -52,7 +53,7 @@ import {
52
53
  signalDaemonStop,
53
54
  startPersistLoop,
54
55
  startStalenessLoop
55
- } from "./chunk-Q5EDVWKZ.js";
56
+ } from "./chunk-GNAX2CBF.js";
56
57
  import {
57
58
  startOtelGrpcReceiver
58
59
  } from "./chunk-MTXF77TN.js";
@@ -1307,6 +1308,7 @@ export const onRequest = defineMiddleware(async (context, next) => {
1307
1308
  `;
1308
1309
 
1309
1310
  // src/installers/javascript.ts
1311
+ import { resolve as resolveRegistry } from "@neat.is/instrumentation-registry";
1310
1312
  var SDK_PACKAGES = [
1311
1313
  { name: "@opentelemetry/api", version: "^1.9.0" },
1312
1314
  { name: "@opentelemetry/sdk-node", version: "^0.57.0" },
@@ -1431,6 +1433,34 @@ function hasNextDependency(pkg) {
1431
1433
  function allDeps(pkg) {
1432
1434
  return { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
1433
1435
  }
1436
+ var WEB_FRAMEWORK_DEPS = [
1437
+ "express",
1438
+ "fastify",
1439
+ "koa",
1440
+ "@hapi/hapi",
1441
+ "hapi",
1442
+ "restify",
1443
+ "connect",
1444
+ "@nestjs/core",
1445
+ "next",
1446
+ "hono",
1447
+ "elysia",
1448
+ "polka",
1449
+ "micro"
1450
+ ];
1451
+ function looksLikeWebApp(pkg) {
1452
+ const deps = allDeps(pkg);
1453
+ return WEB_FRAMEWORK_DEPS.some((name) => name in deps);
1454
+ }
1455
+ function uninstrumentedLibraries(pkg) {
1456
+ const deps = allDeps(pkg);
1457
+ const out = [];
1458
+ for (const [name, version] of Object.entries(deps)) {
1459
+ const entry2 = resolveRegistry(name, version);
1460
+ if (entry2 && entry2.coverage === "gap") out.push(name);
1461
+ }
1462
+ return out;
1463
+ }
1434
1464
  var REMIX_ENTRY_CANDIDATES = [
1435
1465
  "app/entry.server.ts",
1436
1466
  "app/entry.server.tsx",
@@ -1510,6 +1540,9 @@ var SRC_INDEX_CANDIDATES = INDEX_EXTENSIONS.map((ext) => `src/index${ext}`);
1510
1540
  var SRC_NAMED_CANDIDATES = ["server", "main", "app"].flatMap(
1511
1541
  (name) => INDEX_EXTENSIONS.map((ext) => `src/${name}${ext}`)
1512
1542
  );
1543
+ var ROOT_NAMED_CANDIDATES = ["server", "app", "main"].flatMap(
1544
+ (name) => INDEX_EXTENSIONS.map((ext) => `${name}${ext}`)
1545
+ );
1513
1546
  var SCRIPT_LAUNCHERS = /* @__PURE__ */ new Set([
1514
1547
  "node",
1515
1548
  "ts-node",
@@ -1584,6 +1617,10 @@ async function resolveEntry(serviceDir, pkg) {
1584
1617
  const candidate = path5.join(serviceDir, rel);
1585
1618
  if (await exists(candidate)) return candidate;
1586
1619
  }
1620
+ for (const rel of ROOT_NAMED_CANDIDATES) {
1621
+ const candidate = path5.join(serviceDir, rel);
1622
+ if (await exists(candidate)) return candidate;
1623
+ }
1587
1624
  for (const name of INDEX_CANDIDATES) {
1588
1625
  const candidate = path5.join(serviceDir, name);
1589
1626
  if (await exists(candidate)) return candidate;
@@ -2758,8 +2795,17 @@ async function applyInstallersOver(services, project, options = {}) {
2758
2795
  if (!installPlans.has(key)) installPlans.set(key, cmd);
2759
2796
  }
2760
2797
  } else if (outcome.outcome === "already-instrumented") already++;
2761
- else if (outcome.outcome === "lib-only") libOnly++;
2762
- else if (outcome.outcome === "browser-bundle") {
2798
+ else if (outcome.outcome === "lib-only") {
2799
+ libOnly++;
2800
+ if (svc.pkg && looksLikeWebApp(svc.pkg)) {
2801
+ const svcName = path7.basename(svc.dir);
2802
+ console.warn(
2803
+ `neat: runtime layer won't engage for ${svcName}: no entry point found.
2804
+ ${svc.dir} depends on a web framework but neat couldn't resolve an entry to instrument.
2805
+ Add a "start" script to package.json, or point neat at the entry file directly.`
2806
+ );
2807
+ }
2808
+ } else if (outcome.outcome === "browser-bundle") {
2763
2809
  browserBundle++;
2764
2810
  console.log(`skipping ${svc.dir}: browser bundle; browser-OTel support lands in a future release.`);
2765
2811
  } else if (outcome.outcome === "react-native") {
@@ -2818,6 +2864,19 @@ async function applyInstallersOver(services, project, options = {}) {
2818
2864
  See docs/installer-scope.md \u2192 "Manual setup for out-of-scope runtimes"`
2819
2865
  );
2820
2866
  }
2867
+ if (svc.pkg && (outcome.outcome === "instrumented" || outcome.outcome === "already-instrumented")) {
2868
+ const gaps = uninstrumentedLibraries(svc.pkg);
2869
+ if (gaps.length > 0) {
2870
+ const svcName = path7.basename(svc.dir);
2871
+ const list = gaps.join(", ");
2872
+ const verb = gaps.length === 1 ? "this library" : "these libraries";
2873
+ console.warn(
2874
+ `neat: calls to ${list} won't be observed by default in ${svcName}.
2875
+ ${verb} aren't in the default instrumentation set, so they produce no OBSERVED edges.
2876
+ Run \`neat list-uninstrumented\` to review them, then \`neat extend\` to capture them.`
2877
+ );
2878
+ }
2879
+ }
2821
2880
  }
2822
2881
  const packageManagerInstalls = [];
2823
2882
  for (const cmd of installPlans.values()) {
@@ -3840,7 +3899,10 @@ async function checkDaemonHealth(baseUrl) {
3840
3899
  }
3841
3900
  function snapshotForGraph(persisted) {
3842
3901
  return {
3843
- schemaVersion: 3,
3902
+ // Stamp the live schema version the daemon validates against on the
3903
+ // receiving `/snapshot` merge. Tracking the constant keeps the push
3904
+ // aligned with the current snapshot shape across schema migrations.
3905
+ schemaVersion: SCHEMA_VERSION,
3844
3906
  exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
3845
3907
  graph: persisted.graph.export()
3846
3908
  };