@neat.is/core 0.4.6 → 0.4.8

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.d.cts CHANGED
@@ -41,6 +41,7 @@ interface ParsedArgs {
41
41
  declare function parseArgs(rest: string[]): ParsedArgs;
42
42
 
43
43
  declare function readPackageVersion(): string;
44
+ declare function printBanner(): void;
44
45
  declare function runInit(opts: InitOptions): Promise<InitResult>;
45
46
  declare const CLAUDE_SKILL_CONFIG: {
46
47
  mcpServers: {
@@ -64,4 +65,4 @@ declare function runSkill(opts: SkillOptions): Promise<{
64
65
  declare const QUERY_VERBS: Set<string>;
65
66
  declare function runQueryVerb(cmd: string, parsed: ParsedArgs): Promise<number>;
66
67
 
67
- export { CLAUDE_SKILL_CONFIG, type InitOptions, type InitResult, QUERY_VERBS, type SkillOptions, parseArgs, readPackageVersion, runInit, runQueryVerb, runSkill };
68
+ export { CLAUDE_SKILL_CONFIG, type InitOptions, type InitResult, QUERY_VERBS, type SkillOptions, parseArgs, printBanner, readPackageVersion, runInit, runQueryVerb, runSkill };
package/dist/cli.d.ts CHANGED
@@ -41,6 +41,7 @@ interface ParsedArgs {
41
41
  declare function parseArgs(rest: string[]): ParsedArgs;
42
42
 
43
43
  declare function readPackageVersion(): string;
44
+ declare function printBanner(): void;
44
45
  declare function runInit(opts: InitOptions): Promise<InitResult>;
45
46
  declare const CLAUDE_SKILL_CONFIG: {
46
47
  mcpServers: {
@@ -64,4 +65,4 @@ declare function runSkill(opts: SkillOptions): Promise<{
64
65
  declare const QUERY_VERBS: Set<string>;
65
66
  declare function runQueryVerb(cmd: string, parsed: ParsedArgs): Promise<number>;
66
67
 
67
- export { CLAUDE_SKILL_CONFIG, type InitOptions, type InitResult, QUERY_VERBS, type SkillOptions, parseArgs, readPackageVersion, runInit, runQueryVerb, runSkill };
68
+ export { CLAUDE_SKILL_CONFIG, type InitOptions, type InitResult, QUERY_VERBS, type SkillOptions, parseArgs, printBanner, readPackageVersion, runInit, runQueryVerb, runSkill };
package/dist/cli.js CHANGED
@@ -41,14 +41,16 @@ import {
41
41
  setStatus,
42
42
  startPersistLoop,
43
43
  startStalenessLoop
44
- } from "./chunk-RBWL4HRB.js";
44
+ } from "./chunk-J5CEKCTR.js";
45
45
  import {
46
46
  startOtelGrpcReceiver
47
47
  } from "./chunk-3QCRUEQD.js";
48
48
  import {
49
49
  __dirname,
50
50
  __require,
51
- buildOtelReceiver
51
+ assertBindAuthority,
52
+ buildOtelReceiver,
53
+ readAuthEnv
52
54
  } from "./chunk-HVF4S7J3.js";
53
55
 
54
56
  // src/cli.ts
@@ -383,7 +385,9 @@ async function startWatch(graph, opts) {
383
385
  project: projectName,
384
386
  onPolicyTrigger
385
387
  });
386
- const host = opts.host ?? "0.0.0.0";
388
+ const auth = readAuthEnv();
389
+ const host = opts.host ?? (auth.authToken ? "0.0.0.0" : "127.0.0.1");
390
+ assertBindAuthority(host, auth.authToken);
387
391
  const port = opts.port ?? 8080;
388
392
  const otelPort = opts.otelPort ?? 4318;
389
393
  const cachePath = opts.embeddingsCachePath ?? path2.join(path2.dirname(opts.outPath), "embeddings.json");
@@ -693,38 +697,123 @@ import path4 from "path";
693
697
 
694
698
  // src/installers/templates.ts
695
699
  var OTEL_INIT_HEADER = "// Generated by `neat init --apply` (ADR-069). OpenTelemetry auto-instrumentation hook.";
700
+ var OTEL_INIT_STAMP = "// neat-template-version: 3 \u2014 file-first call-site capture (ADR-089) + OTLP bearer auth (#410).";
701
+ var OTEL_OTLP_HEADERS_JS = "if (process.env.NEAT_OTEL_TOKEN) process.env.OTEL_EXPORTER_OTLP_HEADERS ||= 'Authorization=Bearer ' + process.env.NEAT_OTEL_TOKEN";
702
+ function neatCallsiteProcessorSource(ts) {
703
+ const stackT = ts ? ": string" : "";
704
+ const spanT = ts ? ": any" : "";
705
+ const strOpt = ts ? ": string | undefined" : "";
706
+ return `function __neatPickUserFrame(stack${stackT}) {
707
+ const lines = String(stack || '').split('\\n')
708
+ for (let i = 0; i < lines.length; i++) {
709
+ const raw = lines[i].trim()
710
+ if (raw.indexOf('at ') !== 0) continue
711
+ if (raw.indexOf('node_modules') !== -1) continue
712
+ if (raw.indexOf('@opentelemetry') !== -1) continue
713
+ if (raw.indexOf('node:') !== -1) continue
714
+ if (raw.indexOf('NeatCallSiteSpanProcessor') !== -1) continue
715
+ const bodyText = raw.slice(3)
716
+ const loc = bodyText.match(/:(\\d+):(\\d+)\\)?$/)
717
+ if (!loc) continue
718
+ const paren = bodyText.lastIndexOf('(')
719
+ let filepath${strOpt}
720
+ let fn${strOpt}
721
+ if (paren !== -1) {
722
+ fn = bodyText.slice(0, paren).trim()
723
+ if (fn.indexOf('async ') === 0) fn = fn.slice(6)
724
+ if (fn.indexOf('new ') === 0) fn = fn.slice(4)
725
+ filepath = bodyText.slice(paren + 1, bodyText.length - loc[0].length)
726
+ } else {
727
+ filepath = bodyText.slice(0, bodyText.length - loc[0].length)
728
+ }
729
+ if (filepath.indexOf('file://') === 0) filepath = filepath.slice(7)
730
+ if (!filepath) continue
731
+ return { filepath: filepath, lineno: Number(loc[1]), function: fn || undefined }
732
+ }
733
+ return null
734
+ }
735
+
736
+ class NeatCallSiteSpanProcessor {
737
+ onStart(span${spanT}) {
738
+ if (!span || (span.kind !== 2 && span.kind !== 3)) return
739
+ const frame = __neatPickUserFrame(new Error().stack)
740
+ if (!frame) return
741
+ span.setAttribute('code.filepath', frame.filepath)
742
+ if (typeof frame.lineno === 'number') span.setAttribute('code.lineno', frame.lineno)
743
+ if (frame.function) span.setAttribute('code.function', frame.function)
744
+ }
745
+ onEnd() {}
746
+ forceFlush() { return Promise.resolve() }
747
+ shutdown() { return Promise.resolve() }
748
+ }`;
749
+ }
750
+ var CALLSITE_PROCESSOR_JS = neatCallsiteProcessorSource(false);
751
+ var CALLSITE_PROCESSOR_TS = neatCallsiteProcessorSource(true);
752
+ function neatRegisterCallsiteSource(ts) {
753
+ const providerT = ts ? ": any" : "";
754
+ return `try {
755
+ const provider${providerT} = trace.getTracerProvider()
756
+ const delegate = provider && typeof provider.getDelegate === 'function' ? provider.getDelegate() : provider
757
+ if (delegate && typeof delegate.addSpanProcessor === 'function') {
758
+ delegate.addSpanProcessor(new NeatCallSiteSpanProcessor())
759
+ }
760
+ } catch {
761
+ // capture is best-effort; span export is unaffected
762
+ }`;
763
+ }
696
764
  var OTEL_INIT_CJS = `${OTEL_INIT_HEADER}
765
+ ${OTEL_INIT_STAMP}
697
766
  process.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'
698
767
  process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||= 'http://localhost:4318/projects/__PROJECT__/v1/traces'
768
+ ${OTEL_OTLP_HEADERS_JS}
699
769
 
700
770
  const { NodeSDK } = require('@opentelemetry/sdk-node')
701
771
  const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node')
772
+ const { trace } = require('@opentelemetry/api')
773
+
774
+ ${CALLSITE_PROCESSOR_JS}
702
775
 
703
776
  const instrumentations = [getNodeAutoInstrumentations()]
704
777
  __INSTRUMENTATION_BLOCK__
705
- new NodeSDK({ instrumentations }).start()
778
+ const sdk = new NodeSDK({ instrumentations })
779
+ sdk.start()
780
+ ${neatRegisterCallsiteSource(false)}
706
781
  `;
707
782
  var OTEL_INIT_ESM = `${OTEL_INIT_HEADER}
783
+ ${OTEL_INIT_STAMP}
708
784
  process.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'
709
785
  process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||= 'http://localhost:4318/projects/__PROJECT__/v1/traces'
786
+ ${OTEL_OTLP_HEADERS_JS}
710
787
 
711
788
  import { NodeSDK } from '@opentelemetry/sdk-node'
712
789
  import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'
790
+ import { trace } from '@opentelemetry/api'
791
+
792
+ ${CALLSITE_PROCESSOR_JS}
713
793
 
714
794
  const instrumentations = [getNodeAutoInstrumentations()]
715
795
  __INSTRUMENTATION_BLOCK__
716
- new NodeSDK({ instrumentations }).start()
796
+ const sdk = new NodeSDK({ instrumentations })
797
+ sdk.start()
798
+ ${neatRegisterCallsiteSource(false)}
717
799
  `;
718
800
  var OTEL_INIT_TS = `${OTEL_INIT_HEADER}
801
+ ${OTEL_INIT_STAMP}
719
802
  process.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'
720
803
  process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||= 'http://localhost:4318/projects/__PROJECT__/v1/traces'
804
+ ${OTEL_OTLP_HEADERS_JS}
721
805
 
722
806
  import { NodeSDK } from '@opentelemetry/sdk-node'
723
807
  import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'
808
+ import { trace } from '@opentelemetry/api'
809
+
810
+ ${CALLSITE_PROCESSOR_TS}
724
811
 
725
812
  const instrumentations = [getNodeAutoInstrumentations()]
726
813
  __INSTRUMENTATION_BLOCK__
727
- new NodeSDK({ instrumentations }).start()
814
+ const sdk = new NodeSDK({ instrumentations })
815
+ sdk.start()
816
+ ${neatRegisterCallsiteSource(true)}
728
817
  `;
729
818
  function renderNodeOtelInit(template, serviceName, projectName, registrations = []) {
730
819
  const block = registrations.length === 0 ? "" : `
@@ -737,6 +826,8 @@ function renderEnvNeat(serviceName, projectName) {
737
826
  "# Generated by `neat init --apply` (ADR-069).",
738
827
  `OTEL_SERVICE_NAME=${serviceName}`,
739
828
  `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4318/projects/${projectName}/v1/traces`,
829
+ "# Set NEAT_OTEL_TOKEN to the daemon's OTLP secret to authenticate exported spans (#410).",
830
+ "# NEAT_OTEL_TOKEN=",
740
831
  ""
741
832
  ].join("\n");
742
833
  }
@@ -758,6 +849,7 @@ export async function register() {
758
849
  var NEXT_INSTRUMENTATION_NODE_TS = `${NEXT_INSTRUMENTATION_HEADER}
759
850
  process.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'
760
851
  process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||= 'http://localhost:4318/projects/__PROJECT__/v1/traces'
852
+ ${OTEL_OTLP_HEADERS_JS}
761
853
 
762
854
  import { NodeSDK } from '@opentelemetry/sdk-node'
763
855
  import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'
@@ -769,6 +861,7 @@ new NodeSDK({ instrumentations }).start()
769
861
  var NEXT_INSTRUMENTATION_NODE_JS = `${NEXT_INSTRUMENTATION_HEADER}
770
862
  process.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'
771
863
  process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||= 'http://localhost:4318/projects/__PROJECT__/v1/traces'
864
+ ${OTEL_OTLP_HEADERS_JS}
772
865
 
773
866
  const { NodeSDK } = require('@opentelemetry/sdk-node')
774
867
  const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node')
@@ -787,6 +880,7 @@ var FRAMEWORK_OTEL_INIT_HEADER = "// Generated by `neat init --apply` (ADR-074).
787
880
  var FRAMEWORK_OTEL_INIT_TS_BODY = `${FRAMEWORK_OTEL_INIT_HEADER}
788
881
  process.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'
789
882
  process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||= 'http://localhost:4318/projects/__PROJECT__/v1/traces'
883
+ ${OTEL_OTLP_HEADERS_JS}
790
884
 
791
885
  import { NodeSDK } from '@opentelemetry/sdk-node'
792
886
  import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'
@@ -800,6 +894,7 @@ sdk.start()
800
894
  var FRAMEWORK_OTEL_INIT_JS_BODY = `${FRAMEWORK_OTEL_INIT_HEADER}
801
895
  process.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'
802
896
  process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||= 'http://localhost:4318/projects/__PROJECT__/v1/traces'
897
+ ${OTEL_OTLP_HEADERS_JS}
803
898
 
804
899
  const { NodeSDK } = require('@opentelemetry/sdk-node')
805
900
  const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node')
@@ -948,6 +1043,23 @@ async function exists(p) {
948
1043
  return false;
949
1044
  }
950
1045
  }
1046
+ async function readFileMaybe(p) {
1047
+ try {
1048
+ return await fs4.readFile(p, "utf8");
1049
+ } catch {
1050
+ return null;
1051
+ }
1052
+ }
1053
+ async function planOtelInitGeneration(file, contents) {
1054
+ const existing = await readFileMaybe(file);
1055
+ if (existing === null) {
1056
+ return { file, contents, skipIfExists: true };
1057
+ }
1058
+ if (existing.includes(OTEL_INIT_HEADER) && !existing.includes(OTEL_INIT_STAMP)) {
1059
+ return { file, contents, skipIfExists: false };
1060
+ }
1061
+ return null;
1062
+ }
951
1063
  async function detect(serviceDir) {
952
1064
  const pkg = await readPackageJson(serviceDir);
953
1065
  return pkg !== null && typeof pkg.name === "string";
@@ -1678,18 +1790,11 @@ async function plan(serviceDir, opts) {
1678
1790
  const projectName = projectToken(pkg, serviceDir, project);
1679
1791
  const registrations = nonBundled.map((i) => i.registration);
1680
1792
  const generatedFiles = [];
1681
- if (!await exists(otelInitFile)) {
1682
- generatedFiles.push({
1683
- file: otelInitFile,
1684
- contents: renderNodeOtelInit(
1685
- otelInitContents(flavor),
1686
- svcName,
1687
- projectName,
1688
- registrations
1689
- ),
1690
- skipIfExists: true
1691
- });
1692
- }
1793
+ const otelInitGen = await planOtelInitGeneration(
1794
+ otelInitFile,
1795
+ renderNodeOtelInit(otelInitContents(flavor), svcName, projectName, registrations)
1796
+ );
1797
+ if (otelInitGen) generatedFiles.push(otelInitGen);
1693
1798
  if (!await exists(envNeatFile)) {
1694
1799
  generatedFiles.push({
1695
1800
  file: envNeatFile,
@@ -3637,7 +3742,7 @@ function printBanner() {
3637
3742
  console.log("\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D ");
3638
3743
  console.log("");
3639
3744
  console.log(" Network Expressive Architecting Tool");
3640
- console.log(" neat.is \xB7 v0.4.0 \xB7 Apache 2.0");
3745
+ console.log(` neat.is \xB7 v${readPackageVersion()} \xB7 Apache 2.0`);
3641
3746
  console.log("");
3642
3747
  }
3643
3748
  function printDiscoveryReport(opts, services) {
@@ -4281,6 +4386,7 @@ export {
4281
4386
  CLAUDE_SKILL_CONFIG,
4282
4387
  QUERY_VERBS,
4283
4388
  parseArgs,
4389
+ printBanner,
4284
4390
  readPackageVersion,
4285
4391
  runInit,
4286
4392
  runQueryVerb,