@neat.is/core 0.4.29-dev.20260715 → 0.4.29

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.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/banner.ts","../src/gitignore.ts","../src/summary.ts","../src/watch.ts","../src/deploy/detect.ts","../src/installers/javascript.ts","../src/installers/templates.ts","../src/installers/python.ts","../src/installers/shared.ts","../src/installers/index.ts","../src/orchestrator.ts","../src/connector-cli.ts","../src/cli-verbs.ts","../src/cli-client.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport path from 'node:path'\nimport { promises as fs } from 'node:fs'\nimport { printBanner, readPackageVersion } from './banner.js'\nimport { DEFAULT_PROJECT, getGraph, resetGraph } from './graph.js'\nimport { extractFromDirectory } from './extract.js'\nimport {\n formatExtractionBanner,\n formatPrecisionFloorBanner,\n isStrictExtractionEnabled,\n} from './extract/errors.js'\nimport { discoverServices } from './extract/services.js'\nimport type { DiscoveredService } from './extract/shared.js'\nimport { computeDivergences } from './divergences.js'\nimport { saveGraphToDisk } from './persist.js'\nimport { ensureNeatOutIgnored } from './gitignore.js'\nimport { renderValueForwardSummary } from './summary.js'\nimport { startWatch, type WatchHandle } from './watch.js'\nimport { runDeploy, renderOtelEnvBlock } from './deploy/detect.js'\nimport { pathsForProject } from './projects.js'\nimport {\n addProject,\n findDaemonByProject,\n listMachineProjects,\n listProjects,\n ProjectNameCollisionError,\n pruneRegistry,\n removeProject,\n removeDaemonRecord,\n setStatus,\n signalDaemonStop,\n type MachineProject,\n} from './registry.js'\nimport {\n INSTALLERS,\n isEmptyPlan,\n pickInstaller,\n renderPatch,\n type InstallPlan,\n type PatchSection,\n} from './installers/index.js'\nimport { runOrchestrator } from './orchestrator.js'\nimport { runConnectorCommand } from './connector-cli.js'\nimport { runSync } from './cli-verbs.js'\nimport { DivergenceTypeSchema, type DivergenceType } from '@neat.is/types'\nimport {\n createHttpClient,\n exitCodeForError,\n formatHuman,\n formatJson,\n HttpError,\n type HttpClient,\n resolveAuthToken,\n runBlastRadius,\n runDependencies,\n runDiff,\n runDivergences,\n runIncidents,\n runObservedDependencies,\n runPolicies,\n runRootCause,\n runSearch,\n runStaleEdges,\n TransportError,\n type VerbResult,\n} from './cli-client.js'\n\nexport interface InitOptions {\n scanPath: string\n outPath: string\n // The project's registry name. Defaults to the basename of the scan path\n // when the user didn't pass `--project` (ADR-046 — project naming).\n project: string\n // Whether `project` was set explicitly via `--project`. The flag affects\n // which in-memory graph slot we use: explicit names get isolated slots\n // per ADR-026, the default basename keeps using DEFAULT_PROJECT for\n // back-compat with `neat watch`.\n projectExplicit: boolean\n apply: boolean\n dryRun: boolean\n noInstall: boolean\n // ADR-073 §5 — when true, append the per-type node/edge breakdown after\n // the value-forward findings block. Default false.\n verbose: boolean\n}\n\nexport interface InitResult {\n // Process exit code. 0 on success, 1 on collision / runtime failure,\n // 2 on misuse (handled before we get here, but documented for completeness).\n exitCode: number\n // Paths the run actually wrote to. Empty in `--dry-run` except for\n // `neat.patch`. Useful for tests asserting \"init only wrote X\".\n writtenFiles: string[]\n}\n\n// True when this run came in through `npx neat.is` rather than a global\n// `neat` binary on PATH. npx never puts `neat`/`neatd`/`neat-mcp` on PATH —\n// only `npm i -g neat.is` does — so an npx user who copies a bare `neat init`\n// example from the help screen hits `command not found`. We render every\n// example with the prefix that actually works for how they invoked us.\n//\n// Two robust signals: npm sets `npm_command` / `npm_execpath` for anything it\n// spawns (including `npx`), and an npx run resolves argv[1] under a temporary\n// `_npx` cache dir rather than a global bin dir. Either one is enough.\nexport function isNpxInvocation(): boolean {\n if (process.env.npm_command === 'exec') return true\n const execpath = process.env.npm_execpath ?? ''\n if (execpath.includes('npx')) return true\n const entry = process.argv[1] ?? ''\n if (entry.includes('/_npx/') || entry.includes('\\\\_npx\\\\')) return true\n return false\n}\n\n// The command prefix every help example renders with. `npx neat.is` for an\n// npx run, plain `neat` for a global install.\nexport function commandPrefix(): string {\n return isNpxInvocation() ? 'npx neat.is' : 'neat'\n}\n\nexport function usage(): void {\n const neat = commandPrefix()\n console.log('Installed via npx? Prefix commands with `npx neat.is`, or install once: `npm i -g neat.is`.')\n console.log('')\n console.log(`usage: ${neat} <command> [args] [--project <name>]`)\n console.log('')\n console.log(`Run \\`${neat}\\` with no command from inside your project to go zero-to-graph in one step.`)\n console.log('')\n console.log('lifecycle commands:')\n console.log(' init <path> One-time install: discover, extract, register, plan SDK install.')\n console.log(' Snapshot lands in <path>/neat-out/graph.json by default')\n console.log(' (or <path>/neat-out/<project>.json for non-default).')\n console.log(' Flags:')\n console.log(' --apply run the SDK install patch in place')\n console.log(' --dry-run write only neat.patch; do not register or snapshot')\n console.log(' --no-install skip SDK install planning entirely')\n console.log(' watch <path> Start neat-core, watch <path>, re-extract on changes.')\n console.log(' PORT (default 8080), OTEL_PORT (4318), HOST (0.0.0.0)')\n console.log(' control listeners. NEAT_OTLP_GRPC=true also opens 4317.')\n console.log(' list Report the daemons running on this machine (alias: ps).')\n console.log(' Reads ~/.neat/daemons/ and folds in any registered')\n console.log(' project no daemon has self-described yet.')\n console.log(' ps Alias of list.')\n console.log(' pause <name> Stop a project\\'s daemon until it is started again.')\n console.log(' resume <name> Bring a paused project back; for a stopped daemon, re-run')\n console.log(' `neat <path>` to start it.')\n console.log(' uninstall <name>')\n console.log(' Stop a project\\'s daemon and retire it. Does not touch')\n console.log(' neat-out/, policy.json, or any user file.')\n console.log(' prune Drop registry entries whose path is gone from disk.')\n console.log(' Flags: --json emit the removed list as JSON')\n console.log(' version Print the installed @neat.is/core version and exit.')\n console.log(' Aliases: --version, -v.')\n console.log(' skill Install or print the Claude Code MCP drop-in.')\n console.log(' Flags:')\n console.log(' --print-config print the JSON snippet to stdout')\n console.log(' --apply merge mcpServers.neat into ~/.claude.json')\n console.log(' deploy Detect the deploy substrate, generate NEAT_AUTH_TOKEN,')\n console.log(' emit a docker-compose / systemd / docker run artifact, and')\n console.log(' print the OTel env-vars block to paste into your platform.')\n console.log(' sync Re-run discovery, extraction, and SDK apply against the')\n console.log(' registered project, then notify the running daemon.')\n console.log(' Flags:')\n console.log(' --project <name> target a registered project by name')\n console.log(' --to <url> push the snapshot to a remote daemon')\n console.log(' --token <token> bearer token for --to (or $NEAT_REMOTE_TOKEN)')\n console.log(' --dry-run run extraction in-memory; do not write')\n console.log(' --no-instrument skip the SDK install apply step')\n console.log(' --json emit the delta summary as JSON')\n console.log(' connector Configure pull-based OBSERVED connectors (supabase, railway,')\n console.log(' firebase, cloudflare). Subcommands:')\n console.log(' add <provider> add a connector; validates the credential')\n console.log(' against the provider first (--skip-validate to skip)')\n console.log(' flags: --project <name>, --credential/--token <$VAR|value>,')\n console.log(' --id <id>, --<option> <value>, --plaintext, --skip-validate')\n console.log(' list list configured connectors (credentials redacted)')\n console.log(' remove <id> remove a connector by id')\n console.log(' test <id> re-check an existing connector\\'s credential')\n console.log(' Credentials default to an env-var reference ($VAR) resolved at')\n console.log(' run time; the config file is written owner-only (0600).')\n console.log('')\n console.log('query commands (mirror the MCP tools, ADR-050):')\n console.log(' root-cause <node-id> Walk inbound edges to find what broke first.')\n console.log(` example: ${neat} root-cause service:<name>`)\n console.log(' blast-radius <node-id> BFS inbound — the dependents that break if this dies.')\n console.log(` example: ${neat} blast-radius database:<host>`)\n console.log(' dependencies <node-id> Transitive outbound dependencies.')\n console.log(' Flags: --depth N (default 3, max 10)')\n console.log(` example: ${neat} dependencies service:<name> --depth 2`)\n console.log(' observed-dependencies <node-id> OBSERVED-only outbound edges (runtime traffic).')\n console.log(` example: ${neat} observed-dependencies service:<name>`)\n console.log(' incidents [<node-id>] Recent error events; per-node when an id is given.')\n console.log(' Flags: --limit N (default 20)')\n console.log(` example: ${neat} incidents service:<name> --limit 5`)\n console.log(' search <query> Semantic (or substring) match on node names/ids.')\n console.log(` example: ${neat} search \"checkout\"`)\n console.log(' diff --against <snapshot> Compare the live graph to a saved snapshot.')\n console.log(` example: ${neat} diff --against ./snapshots/baseline.json`)\n console.log(' stale-edges Recent OBSERVED → STALE transitions.')\n console.log(' Flags: --limit N, --edge-type CALLS|CONNECTS_TO|...')\n console.log(` example: ${neat} stale-edges --edge-type CALLS`)\n console.log(' policies Current policy violations.')\n console.log(' Flags: --node <id>, --hypothetical-action <json>')\n console.log(` example: ${neat} policies --node service:<name> --json`)\n console.log(' divergences Where code (EXTRACTED) and production (OBSERVED) disagree.')\n console.log(' Flags: --type <list>, --min-confidence <0..1>, --node <id>')\n console.log(` example: ${neat} divergences --min-confidence 0.7`)\n console.log('')\n console.log('flags:')\n console.log(' --project <name> Name the project this command targets. Default: \"default\".')\n console.log(' --json Emit machine-readable JSON instead of human text. Query verbs only.')\n console.log('')\n console.log('exit codes:')\n console.log(' 0 success')\n console.log(' 1 server error (4xx/5xx body printed to stderr)')\n console.log(' 2 misuse (missing args, bad flags) — handled before any network call')\n console.log(' 3 environmental — daemon unreachable, or one of ports 8080 / 4318 / 6328')\n console.log(' is held by another process when `neat <path>` tries to spawn the daemon')\n console.log('')\n console.log('environment:')\n console.log(' NEAT_API_URL base URL for the core REST API (default http://localhost:8080)')\n console.log(' alias: NEAT_CORE_URL (the name the MCP server reads)')\n console.log(' NEAT_PROJECT project name when --project isn\\'t passed')\n}\n\n// Tiny argv parser — pulls `--project <name>`, the v0.2.5 init flags, and\n// the v0.2.8 verb flags out of `rest`. Boolean / value flags are surfaced\n// unconditionally; per-command validation lives in `main`.\ninterface ParsedArgs {\n project: string | null\n apply: boolean\n dryRun: boolean\n noInstall: boolean\n noInstrument: boolean\n noOpen: boolean\n yes: boolean\n verbose: boolean\n printConfig: boolean\n json: boolean\n depth: number | null\n limit: number | null\n edgeType: string | null\n node: string | null\n since: string | null\n against: string | null\n errorId: string | null\n hypotheticalAction: string | null\n type: string | null\n minConfidence: number | null\n // `neat sync` (ADR-074 §1) — remote daemon URL + bearer token.\n to: string | null\n token: string | null\n positional: string[]\n}\n\n// String-valued flags supported across the verb surface. Each entry maps the\n// canonical `--flag` name (and its `--flag=` equivalent) to the parsed-args\n// field that receives it. Centralising the table keeps misuse diagnostics\n// (exit code 2) consistent across verbs.\nconst STRING_FLAGS = [\n ['--project', 'project'],\n ['--depth', 'depth'],\n ['--limit', 'limit'],\n ['--edge-type', 'edgeType'],\n ['--node', 'node'],\n ['--since', 'since'],\n ['--against', 'against'],\n ['--error-id', 'errorId'],\n ['--hypothetical-action', 'hypotheticalAction'],\n ['--type', 'type'],\n ['--min-confidence', 'minConfidence'],\n ['--to', 'to'],\n ['--token', 'token'],\n] as const\n\nfunction parseArgs(rest: string[]): ParsedArgs {\n const positional: string[] = []\n const out: ParsedArgs = {\n project: null,\n apply: false,\n dryRun: false,\n noInstall: false,\n noInstrument: false,\n noOpen: false,\n yes: false,\n verbose: false,\n printConfig: false,\n json: false,\n depth: null,\n limit: null,\n edgeType: null,\n node: null,\n since: null,\n against: null,\n errorId: null,\n hypotheticalAction: null,\n type: null,\n minConfidence: null,\n to: null,\n token: null,\n positional: [],\n }\n for (let i = 0; i < rest.length; i++) {\n const arg = rest[i] as string\n\n // Boolean flags first.\n if (arg === '--apply') { out.apply = true; continue }\n if (arg === '--dry-run') { out.dryRun = true; continue }\n if (arg === '--no-install') { out.noInstall = true; continue }\n if (arg === '--no-instrument') { out.noInstrument = true; continue }\n if (arg === '--no-open') { out.noOpen = true; continue }\n if (arg === '--yes' || arg === '-y') { out.yes = true; continue }\n if (arg === '--verbose') { out.verbose = true; continue }\n if (arg === '--print-config') { out.printConfig = true; continue }\n if (arg === '--json') { out.json = true; continue }\n\n // String/number flags via the shared table.\n let matched = false\n for (const [flag, field] of STRING_FLAGS) {\n if (arg === flag) {\n const next = rest[i + 1]\n if (next === undefined) {\n console.error(`neat: ${flag} requires a value`)\n process.exit(2)\n }\n assignFlag(out, field, next)\n i++\n matched = true\n break\n }\n if (arg.startsWith(`${flag}=`)) {\n assignFlag(out, field, arg.slice(flag.length + 1))\n matched = true\n break\n }\n }\n if (matched) continue\n positional.push(arg)\n }\n out.positional = positional\n return out\n}\n\nexport { parseArgs }\n\n// Number flags get parsed at assignment time so misuse (`--depth foo`)\n// surfaces with exit code 2 before any network call.\nfunction assignFlag(out: ParsedArgs, field: (typeof STRING_FLAGS)[number][1], value: string): void {\n if (field === 'depth' || field === 'limit') {\n const n = Number(value)\n if (!Number.isFinite(n) || !Number.isInteger(n) || n < 1) {\n console.error(`neat: --${field === 'depth' ? 'depth' : 'limit'} must be a positive integer`)\n process.exit(2)\n }\n out[field] = n\n return\n }\n if (field === 'minConfidence') {\n const n = Number(value)\n if (!Number.isFinite(n) || n < 0 || n > 1) {\n console.error('neat: --min-confidence must be a number in [0, 1]')\n process.exit(2)\n }\n out.minConfidence = n\n return\n }\n // String fields.\n ;(out as unknown as Record<string, unknown>)[field] = value\n}\n\n// Per-type node/edge counts + compat formatting moved into summary.ts as\n// part of the value-forward findings block (issue #305 / ADR-073 §5).\n\n// `readPackageVersion` + `printBanner` live in banner.ts so the orchestrator\n// can print the same artwork without pulling in the whole CLI dispatch (and\n// without a cli ↔ orchestrator import cycle). Re-exported here so existing\n// importers of `cli.js` (e.g. the banner test, MCP) keep resolving them.\nexport { printBanner, readPackageVersion }\n\nfunction printVersion(): void {\n process.stdout.write(`${readPackageVersion()}\\n`)\n}\n\n// One `neat list` / `neat ps` row. A discovery-backed row reports the daemon's\n// state and ports; a legacy registry row (no daemon file yet) reports\n// `registered` and the registry status so the migration window stays legible.\nfunction formatMachineProjectRow(r: MachineProject): string {\n if (r.ports) {\n const where = r.pid !== undefined ? `\\tpid=${r.pid}` : ''\n return `${r.project}\\t${r.state}\\trest=${r.ports.rest} otlp=${r.ports.otlp} web=${r.ports.web}\\t${r.projectPath}${where}`\n }\n const status = r.registryStatus ? `\\t(${r.registryStatus})` : ''\n return `${r.project}\\t${r.state}${status}\\t${r.projectPath}`\n}\n\nfunction printDiscoveryReport(opts: InitOptions, services: DiscoveredService[]): void {\n const languages = [...new Set(services.map((s) => s.node.language))].sort()\n const mode = opts.dryRun ? 'dry-run' : opts.apply ? 'apply' : 'patch-only'\n printBanner()\n console.log('=== neat init: discovery ===')\n console.log(`scan path: ${opts.scanPath}`)\n console.log(`project: ${opts.project}`)\n console.log(`mode: ${mode}`)\n console.log(`services: ${services.length}`)\n for (const s of services) {\n const where = s.node.repoPath && s.node.repoPath.length > 0 ? s.node.repoPath : '.'\n console.log(` - ${s.node.name} (${s.node.language}) — ${where}`)\n }\n console.log(`languages: ${languages.length > 0 ? languages.join(', ') : '(none)'}`)\n if (opts.noInstall) {\n console.log('install: skipped (--no-install)')\n } else if (opts.dryRun) {\n console.log('install: patch will be written to neat.patch; nothing else.')\n } else if (opts.apply) {\n console.log('install: patch will be applied in place. Run `npm install` afterwards.')\n } else {\n console.log('install: patch will be written to neat.patch for review.')\n }\n console.log('')\n}\n\nasync function buildPatchSections(\n services: DiscoveredService[],\n project: string,\n): Promise<PatchSection[]> {\n const sections: PatchSection[] = []\n for (const svc of services) {\n const installer = await pickInstaller(svc.dir)\n if (!installer) continue\n // v0.4.1 / refs #339 — pass the registered project name so the per-\n // package `.env.neat` carries `OTEL_SERVICE_NAME=<project>`. The daemon\n // routes spans by registered project name; matching keys end-to-end\n // is what keeps OBSERVED edges landing.\n const plan: InstallPlan = await installer.plan(svc.dir, { project })\n // Lib-only + runtime-kind-skipped packages keep a section so the dry-run\n // patch documents the skip and the apply summary counts them (ADR-069 §2,\n // v0.4.4 / #370). Empty plans without either flag are already-instrumented\n // end-to-end and drop out.\n if (isEmptyPlan(plan) && !plan.libOnly && plan.runtimeKind === undefined) continue\n sections.push({ installer: installer.name, plan })\n }\n return sections\n}\n\nexport async function runInit(opts: InitOptions): Promise<InitResult> {\n const written: string[] = []\n\n // ── Step 1: validate path ────────────────────────────────────────────\n const stat = await fs.stat(opts.scanPath).catch(() => null)\n if (!stat || !stat.isDirectory()) {\n console.error(`neat init: ${opts.scanPath} is not a directory`)\n return { exitCode: 2, writtenFiles: written }\n }\n\n // ── Step 2: discovery (ADR-046 #2 — before any mutation) ─────────────\n const services = await discoverServices(opts.scanPath)\n printDiscoveryReport(opts, services)\n\n // ── Step 3: plan SDK install (pure data, no fs writes) ───────────────\n const sections = opts.noInstall ? [] : await buildPatchSections(services, opts.project)\n const patch = renderPatch(sections)\n const patchPath = path.join(opts.scanPath, 'neat.patch')\n\n // ── Step 4: dry-run shortcut — only neat.patch is allowed to land ────\n if (opts.dryRun) {\n await fs.writeFile(patchPath, patch, 'utf8')\n written.push(patchPath)\n console.log(`dry-run: patch written to ${patchPath}`)\n // ADR-073 §6 — list the planned `.gitignore` write alongside the other\n // planned writes. No file mutation in dry-run; only the announcement.\n const gitignorePath = path.join(opts.scanPath, '.gitignore')\n const gitignoreExists = await fs.stat(gitignorePath).then(() => true).catch(() => false)\n const verb = gitignoreExists ? 'append' : 'create'\n console.log(`dry-run: would ${verb} ${gitignorePath} (add neat-out/)`)\n console.log('rerun without --dry-run to register and snapshot.')\n return { exitCode: 0, writtenFiles: written }\n }\n\n // ── Step 5: extraction + snapshot ────────────────────────────────────\n // Use DEFAULT_PROJECT for the in-memory graph slot when --project wasn't\n // explicitly passed; named projects get isolated slots per ADR-026.\n const graphKey = opts.projectExplicit ? opts.project : DEFAULT_PROJECT\n resetGraph(graphKey)\n const graph = getGraph(graphKey)\n // ADR-065 — per-file extraction failures land alongside the snapshot in\n // <projectDir>/neat-out/errors.ndjson. Same file as OTel error events\n // (ADR-033) with a `source: 'extract'` discriminator.\n const projectPaths = pathsForProject(\n graphKey,\n path.join(opts.scanPath, 'neat-out'),\n )\n const errorsPath = path.join(path.dirname(opts.outPath), path.basename(projectPaths.errorsPath))\n const result = await extractFromDirectory(graph, opts.scanPath, { errorsPath })\n await saveGraphToDisk(graph, opts.outPath)\n written.push(opts.outPath)\n\n // ADR-073 §6 — ensure `neat-out/` is git-ignored. Snapshot just landed on\n // disk; an un-ignored neat-out/ would leak into git history on the next\n // commit. Idempotent: the helper no-ops when the line is already present.\n const gitignoreResult = await ensureNeatOutIgnored(opts.scanPath)\n if (gitignoreResult.action !== 'unchanged') {\n written.push(gitignoreResult.file)\n }\n\n // ── Step 6: register in the machine-level registry ───────────────────\n // Idempotent re-init of the same path under the same name refreshes the\n // entry; collision against a different path exits non-zero (ADR-046 #7).\n const languages = [...new Set(services.map((s) => s.node.language))].sort()\n let currentProjectName = opts.project\n try {\n const entry = await addProject({\n name: opts.project,\n path: opts.scanPath,\n languages,\n status: 'active',\n })\n currentProjectName = entry.name\n } catch (err) {\n if (err instanceof ProjectNameCollisionError) {\n console.error(`neat init: ${err.message}`)\n console.error('pass --project <other-name> to register under a different name.')\n return { exitCode: 1, writtenFiles: written }\n }\n throw err\n }\n\n // Narrow the active-project surface to the project the operator just\n // registered. Mirrors the bare-orchestrator behaviour so `neat init` and\n // `neat <path>` agree on the activation contract.\n const siblings = await listProjects()\n const paused: string[] = []\n for (const p of siblings) {\n if (p.name !== currentProjectName && p.status === 'active') {\n await setStatus(p.name, 'paused')\n paused.push(p.name)\n }\n }\n if (paused.length > 0) {\n const plural = paused.length === 1 ? '' : 's'\n console.log(\n `neat: paused ${paused.length} sibling project${plural}; run \\`neat resume <name>\\` to bring one back active.`,\n )\n }\n\n // ── Step 7: write or apply patch ─────────────────────────────────────\n if (!opts.noInstall) {\n if (opts.apply) {\n let instrumented = 0\n let alreadyInstrumented = 0\n let libOnly = 0\n let browserBundle = 0\n let reactNative = 0\n for (const section of sections) {\n const installer = INSTALLERS.find((i) => i.name === section.installer)\n if (!installer) continue\n const outcome = await installer.apply(section.plan)\n if (outcome.outcome === 'instrumented') {\n instrumented++\n for (const f of outcome.writtenFiles) written.push(f)\n } else if (outcome.outcome === 'already-instrumented') {\n alreadyInstrumented++\n } else if (outcome.outcome === 'lib-only') {\n libOnly++\n } else if (outcome.outcome === 'browser-bundle') {\n browserBundle++\n console.log(`skipping ${section.plan.serviceDir}: browser bundle; browser-OTel support lands in a future release.`)\n } else if (outcome.outcome === 'react-native') {\n reactNative++\n console.log(`skipping ${section.plan.serviceDir}: React Native target; browser-OTel support lands in a future release.`)\n }\n }\n if (sections.length > 0) {\n console.log('')\n const parts = [\n `instrumented ${instrumented}`,\n `already-instrumented ${alreadyInstrumented}`,\n `lib-only ${libOnly}`,\n ]\n if (browserBundle > 0) parts.push(`browser-bundle ${browserBundle}`)\n if (reactNative > 0) parts.push(`react-native ${reactNative}`)\n console.log(`apply: ${parts.join(', ')}`)\n console.log('Run `npm install` (or your language equivalent) to refresh lockfiles.')\n }\n } else {\n await fs.writeFile(patchPath, patch, 'utf8')\n written.push(patchPath)\n }\n }\n\n // ── Step 8: summary + incompatibilities ──────────────────────────────\n // ADR-073 §5 / issue #305 — findings-first: compat violations, top\n // divergences, services without OBSERVED coverage, then the OTel env-vars\n // block. Per-type counts ride behind `--verbose`.\n console.log('')\n console.log(`snapshot: ${opts.outPath}`)\n console.log(`added: ${result.nodesAdded} nodes, ${result.edgesAdded} edges`)\n console.log('')\n const divergenceResult = computeDivergences(graph)\n console.log(\n renderValueForwardSummary({\n graph,\n divergences: divergenceResult.divergences,\n verbose: opts.verbose,\n }),\n )\n // ADR-065 — loud failure mode banner. Unconditional; 0 is a positive\n // signal. When errors > 0, also surface the sidecar path so the operator\n // can read per-file detail.\n console.log(formatExtractionBanner(result.extractionErrors))\n if (result.extractionErrors > 0) {\n console.log(`errors: ${errorsPath}`)\n }\n // ADR-066 — precision-floor drop banner. Always emitted; 0 is observable\n // as a positive signal that no cross-service heuristic edges grew the\n // graph this pass.\n console.log(formatPrecisionFloorBanner(result.extractedDropped))\n\n // ADR-065 — NEAT_STRICT_EXTRACTION=1 makes any per-file failure exit\n // non-zero. Default is forgiving (banner only). Exit code 4 keeps\n // misuse (2) and daemon-down (3) distinguishable per the CLI contract.\n if (result.extractionErrors > 0 && isStrictExtractionEnabled()) {\n return { exitCode: 4, writtenFiles: written }\n }\n\n return { exitCode: 0, writtenFiles: written }\n}\n\n// ── Claude Code skill (ADR-049 / v0.2.5 step 6) ────────────────────────\n//\n// The skill is a one-shot MCP-config drop-in. Source of truth for the\n// snippet lives here (the @neat.is/claude-skill package's\n// claude_code_config.json holds an identical copy for documentation; a\n// contract test keeps the two byte-aligned).\nexport const CLAUDE_SKILL_CONFIG = {\n mcpServers: {\n neat: {\n type: 'stdio' as const,\n command: 'npx',\n args: ['-y', '@neat.is/mcp'],\n env: {\n NEAT_CORE_URL: 'http://localhost:8080',\n },\n },\n },\n}\n\nfunction claudeConfigPath(): string {\n // ~/.claude.json is Claude Code's user-level MCP config. Tests override\n // via NEAT_CLAUDE_CONFIG so they don't touch the real file.\n const override = process.env.NEAT_CLAUDE_CONFIG\n if (override && override.length > 0) return path.resolve(override)\n const home = process.env.HOME ?? process.env.USERPROFILE ?? ''\n return path.join(home, '.claude.json')\n}\n\nexport interface SkillOptions {\n apply: boolean\n printConfig: boolean\n}\n\nexport async function runSkill(opts: SkillOptions): Promise<{ exitCode: number }> {\n const snippet = JSON.stringify(CLAUDE_SKILL_CONFIG, null, 2) + '\\n'\n\n if (opts.printConfig) {\n process.stdout.write(snippet)\n return { exitCode: 0 }\n }\n\n if (opts.apply) {\n const target = claudeConfigPath()\n let existing: Record<string, unknown> = {}\n try {\n existing = JSON.parse(await fs.readFile(target, 'utf8'))\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n console.error(`neat skill: failed to read ${target} — ${(err as Error).message}`)\n return { exitCode: 1 }\n }\n }\n // Merge mcpServers.neat without disturbing other entries the user\n // might have wired up by hand.\n const mcp =\n (existing as { mcpServers?: Record<string, unknown> }).mcpServers ?? {}\n const merged = {\n ...existing,\n mcpServers: { ...mcp, neat: CLAUDE_SKILL_CONFIG.mcpServers.neat },\n }\n await fs.mkdir(path.dirname(target), { recursive: true })\n await fs.writeFile(target, JSON.stringify(merged, null, 2) + '\\n', 'utf8')\n console.log(`neat skill: wrote mcpServers.neat to ${target}`)\n console.log('restart Claude Code to pick up the new MCP server.')\n return { exitCode: 0 }\n }\n\n console.log('neat skill — Claude Code MCP drop-in for NEAT')\n console.log('')\n console.log(' --print-config print the JSON snippet to stdout')\n console.log(' --apply merge mcpServers.neat into ~/.claude.json')\n console.log('')\n console.log('Manual install: copy mcpServers.neat from --print-config into ~/.claude.json,')\n console.log('then restart Claude Code. See packages/claude-skill/SKILL.md for the tool list.')\n console.log('')\n console.log('The MCP server reads NEAT_CORE_URL for the daemon URL — point it at a')\n console.log('non-default daemon by editing that value in the generated config.')\n return { exitCode: 0 }\n}\n\nexport async function main(): Promise<void> {\n const argv = process.argv.slice(2)\n // First token, for the help/version flag checks. The command dispatch below\n // keys off the first *positional* (flag-stripped) instead, so a bare\n // `npx neat.is --no-open` still reaches the orchestrator.\n const cmd0 = argv[0]\n\n // `-h` / `--help` print the usage screen and exit clean.\n if (cmd0 === '-h' || cmd0 === '--help') {\n usage()\n process.exit(0)\n }\n\n // The dispatcher honors three spellings: --version, -v, version.\n if (cmd0 === '--version' || cmd0 === '-v' || cmd0 === 'version') {\n printVersion()\n process.exit(0)\n }\n\n // `neat connector <add|list|remove|test>` — the ADR-130 connector on-ramp\n // (docs/contracts/connector-config.md §3). A top-level config command family,\n // not an eleventh query verb; it takes provider-specific flags, so it parses\n // its own argv rather than routing through the shared query-flag table.\n if (cmd0 === 'connector') {\n const code = await runConnectorCommand(argv.slice(1))\n if (code !== 0) process.exit(code)\n return\n }\n\n // No positional command — `npx neat.is` (optionally with flags like\n // `--no-open`) run from inside a repo. This is the zero-to-graph path\n // (issue #483): run the orchestrator on the current working directory, the\n // same dispatch the explicit `neat <path>` form takes (project name =\n // basename of cwd). We detect \"no command\" by the absence of any\n // positional after flag-stripping, so a bare `npx neat.is --no-instrument`\n // still lands here instead of treating the flag as a command.\n const argvParsed = parseArgs(argv)\n if (argvParsed.positional.length === 0) {\n const orchestratorCode = await tryOrchestrator(process.cwd(), argvParsed)\n // tryOrchestrator returns null only when its path isn't a directory,\n // which can't happen for process.cwd(); the non-null branch always runs.\n if (orchestratorCode !== null && orchestratorCode !== 0) process.exit(orchestratorCode)\n return\n }\n\n // From here on, the first positional is the command. Reuse the already-\n // parsed flags and drop the command token from the positional list, so each\n // verb's `parsed.positional[0]` stays the verb's own first argument (e.g.\n // the node-id for `root-cause`), unchanged from the pre-#483 dispatch.\n const cmd = argvParsed.positional[0] as string\n const parsed: ParsedArgs = { ...argvParsed, positional: argvParsed.positional.slice(1) }\n const { positional, apply, dryRun, noInstall } = parsed\n const project = parsed.project ?? DEFAULT_PROJECT\n\n if (cmd === 'init') {\n const target = positional[0]\n if (!target) {\n console.error('neat init: missing <path>')\n usage()\n process.exit(2)\n }\n if (apply && dryRun) {\n console.error('neat init: --apply and --dry-run are mutually exclusive')\n process.exit(2)\n }\n const scanPath = path.resolve(target)\n // ADR-046 — when --project isn't passed, the registry name defaults to\n // the basename of the scan path. The in-memory graph slot stays on\n // DEFAULT_PROJECT (back-compat with existing `neat watch` invocations).\n const projectExplicit = parsed.project !== null\n const projectName = projectExplicit ? project : path.basename(scanPath)\n // Default project keeps writing to graph.json (ADR-026 back-compat);\n // named projects use <project>.json under the same neat-out directory.\n const projectKey = projectExplicit ? project : DEFAULT_PROJECT\n const fallback = pathsForProject(projectKey, path.join(scanPath, 'neat-out')).snapshotPath\n const outPath = path.resolve(process.env.NEAT_OUT_PATH ?? fallback)\n const result = await runInit({\n scanPath,\n outPath,\n project: projectName,\n projectExplicit,\n apply,\n dryRun,\n noInstall,\n verbose: parsed.verbose,\n })\n if (result.exitCode !== 0) process.exit(result.exitCode)\n return\n }\n\n if (cmd === 'watch') {\n const target = positional[0]\n if (!target) {\n console.error('neat watch: missing <path>')\n usage()\n process.exit(2)\n }\n const scanPath = path.resolve(target)\n const stat = await fs.stat(scanPath).catch(() => null)\n if (!stat || !stat.isDirectory()) {\n console.error(`neat watch: ${scanPath} is not a directory`)\n process.exit(2)\n }\n const projectPaths = pathsForProject(project, path.join(scanPath, 'neat-out'))\n const outPath = path.resolve(process.env.NEAT_OUT_PATH ?? projectPaths.snapshotPath)\n const errorsPath = path.resolve(\n process.env.NEAT_ERRORS_PATH ??\n path.join(path.dirname(outPath), path.basename(projectPaths.errorsPath)),\n )\n const staleEventsPath = path.resolve(\n process.env.NEAT_STALE_EVENTS_PATH ??\n path.join(path.dirname(outPath), path.basename(projectPaths.staleEventsPath)),\n )\n\n const embeddingsCachePath = process.env.NEAT_EMBEDDINGS_CACHE_PATH\n ? path.resolve(process.env.NEAT_EMBEDDINGS_CACHE_PATH)\n : undefined\n\n const handle: WatchHandle = await startWatch(getGraph(project), {\n scanPath,\n outPath,\n errorsPath,\n staleEventsPath,\n project,\n ...(embeddingsCachePath ? { embeddingsCachePath } : {}),\n host: process.env.HOST ?? '0.0.0.0',\n port: Number(process.env.PORT ?? 8080),\n otelPort: Number(process.env.OTEL_PORT ?? 4318),\n otelGrpc: process.env.NEAT_OTLP_GRPC === 'true',\n otelGrpcPort: process.env.NEAT_OTLP_GRPC_PORT\n ? Number(process.env.NEAT_OTLP_GRPC_PORT)\n : undefined,\n })\n\n // startPersistLoop already wires SIGTERM/SIGINT to flush + exit. Hook in\n // ahead of it so the watcher closes cleanly first; the persist handler's\n // `process.exit(0)` will still run after our stop() resolves.\n let shuttingDown = false\n const shutdown = (signal: NodeJS.Signals): void => {\n if (shuttingDown) return\n shuttingDown = true\n console.log(`neat watch: ${signal} received, stopping…`)\n void handle.stop().catch((err) => {\n console.error('neat watch: shutdown error', err)\n })\n }\n process.on('SIGTERM', shutdown)\n process.on('SIGINT', shutdown)\n return\n }\n\n // `list` / `ps` both report the daemons discovered on the machine. ADR-096\n // §6 — discovery reads the lock-free `~/.neat/daemons/` directory and folds\n // in any legacy registry entries no daemon has self-described yet, so a\n // pre-migration install still lists its projects.\n if (cmd === 'list' || cmd === 'ps') {\n const rows = await listMachineProjects()\n if (rows.length === 0) {\n console.log('no daemons running and no projects registered. run `neat init <path>` to register one.')\n return\n }\n for (const r of rows) {\n console.log(formatMachineProjectRow(r))\n }\n return\n }\n\n // `pause` stops a project's daemon. Under one-daemon-per-project (ADR-096)\n // that is the per-daemon shutdown driven by the discovery record's pid. While\n // a project still lives only in the legacy registry (the migration window\n // before #508 lands), it falls back to flipping the registry status the\n // multi-project daemon reads.\n if (cmd === 'pause') {\n const name = positional[0]\n if (!name) {\n console.error('neat pause: missing <name>')\n usage()\n process.exit(2)\n }\n const daemon = await findDaemonByProject(name)\n if (daemon) {\n if (daemon.live && signalDaemonStop(daemon.record.pid)) {\n console.log(`paused: ${name} (${daemon.record.projectPath}) — stopped daemon pid ${daemon.record.pid}`)\n } else {\n console.log(`paused: ${name} (${daemon.record.projectPath}) — daemon was not running`)\n }\n return\n }\n try {\n const entry = await setStatus(name, 'paused')\n console.log(`paused: ${entry.name} (${entry.path})`)\n } catch (err) {\n console.error((err as Error).message)\n process.exit(1)\n }\n return\n }\n\n // `resume` brings a paused project back. Spawning a per-project daemon is the\n // orchestrator's job (`neat <path>`), so against a stopped daemon record we\n // point the operator at it; against a legacy registry entry we flip the\n // status the multi-project daemon reads, preserving the pre-migration shape.\n if (cmd === 'resume') {\n const name = positional[0]\n if (!name) {\n console.error('neat resume: missing <name>')\n usage()\n process.exit(2)\n }\n const daemon = await findDaemonByProject(name)\n if (daemon) {\n if (daemon.live) {\n console.log(`resume: ${name} (${daemon.record.projectPath}) — daemon already running`)\n } else {\n console.log(`resume: ${name} (${daemon.record.projectPath}) — run \\`neat ${daemon.record.projectPath}\\` to start its daemon again`)\n }\n return\n }\n try {\n const entry = await setStatus(name, 'active')\n console.log(`resumed: ${entry.name} (${entry.path})`)\n } catch (err) {\n console.error((err as Error).message)\n process.exit(1)\n }\n return\n }\n\n if (cmd === 'skill') {\n const result = await runSkill({ apply: parsed.apply, printConfig: parsed.printConfig })\n if (result.exitCode !== 0) process.exit(result.exitCode)\n return\n }\n\n // `uninstall` retires a project. Under ADR-096 that means stopping its daemon\n // (via the discovery record's pid) and clearing its discovery file, then\n // dropping any legacy registry row. As before it never touches neat-out/,\n // policy.json, or user files at the project path (ADR-048 #6).\n if (cmd === 'uninstall') {\n const name = positional[0]\n if (!name) {\n console.error('neat uninstall: missing <name>')\n usage()\n process.exit(2)\n }\n const daemon = await findDaemonByProject(name)\n const removed = await removeProject(name)\n if (!daemon && !removed) {\n console.error(`neat uninstall: no project named \"${name}\"`)\n process.exit(1)\n }\n const projectPath = daemon?.record.projectPath ?? removed?.path ?? '(unknown path)'\n if (daemon) {\n if (daemon.live && signalDaemonStop(daemon.record.pid)) {\n console.log(`uninstall: ${name} — stopped daemon pid ${daemon.record.pid}`)\n }\n // Clear the discovery copy. A live daemon clears its own on graceful stop,\n // but removing it here covers a daemon that crashed without cleanup and\n // makes the verb idempotent against a stale record.\n await removeDaemonRecord(daemon.source)\n }\n console.log(`unregistered: ${name} (${projectPath})`)\n console.log('note: neat-out/, policy.json, and other files at the project path were left in place.')\n return\n }\n\n if (cmd === 'prune') {\n // #463 — one-shot cleanup of registry entries whose path is gone. Explicit\n // user intent, so it drops any ENOENT entry immediately regardless of the\n // auto-prune TTL. Only definite ENOENT entries go — a project whose path\n // still exists, or one behind a transient stat error, is left alone.\n const removed = await pruneRegistry({ ttlMs: 0 })\n if (parsed.json) {\n console.log(JSON.stringify(removed.map((p) => ({ name: p.name, path: p.path })), null, 2))\n return\n }\n if (removed.length === 0) {\n console.log('nothing to prune — every registered project path still exists.')\n return\n }\n console.log(`pruned ${removed.length} project${removed.length === 1 ? '' : 's'}: ${removed.map((p) => p.name).join(', ')}`)\n return\n }\n\n if (cmd === 'deploy') {\n // ADR-073 §2 — detect substrate, generate token, emit artifact, print\n // the OTel env-vars block. Token is the only secret printed to stdout;\n // the artifact written to disk names the env-var by reference only.\n const artifact = await runDeploy()\n const block = renderOtelEnvBlock(artifact.token)\n\n console.log()\n console.log(`Substrate detected: ${artifact.substrate}`)\n if (artifact.artifactPath) {\n console.log(`Artifact written: ${artifact.artifactPath}`)\n } else {\n console.log('No on-disk artifact — copy the snippet below into your substrate.')\n console.log()\n console.log(artifact.contents)\n }\n console.log()\n console.log('NEAT_AUTH_TOKEN (store this — it will not be printed again):')\n console.log(` ${artifact.token}`)\n console.log()\n console.log(\"For your application's deploy platform, set these env vars:\")\n console.log(block.split('\\n').map((l) => ` ${l}`).join('\\n'))\n console.log()\n console.log('Once NEAT is running, your dashboard will be at:')\n console.log(' https://<host>:6328')\n console.log()\n console.log('To start NEAT, run:')\n console.log(` ${artifact.startCommand}`)\n return\n }\n\n if (cmd === 'sync') {\n // ADR-074 §1 — re-runs discovery + extract + SDK apply + daemon notify\n // against the registered project. Skips registry registration, browser\n // open, daemon spawn, and the first-run summary block.\n const result = await runSync({\n ...(parsed.project ? { project: parsed.project } : {}),\n ...(parsed.to ? { to: parsed.to } : {}),\n ...(parsed.token ? { token: parsed.token } : {}),\n dryRun: parsed.dryRun,\n noInstrument: parsed.noInstrument,\n json: parsed.json,\n })\n if (result.exitCode !== 0) process.exit(result.exitCode)\n return\n }\n\n // ── Query verbs (ADR-050) ────────────────────────────────────────────\n // The nine verbs mirror the MCP tool allowlist. Same multi-project\n // routing, same three-part response shape (summary + block + footer),\n // exit codes branch on misuse vs server error vs daemon-down.\n if (QUERY_VERBS.has(cmd)) {\n const code = await runQueryVerb(cmd, parsed)\n if (code !== 0) process.exit(code)\n return\n }\n\n // ── Bare-path orchestrator (ADR-073 §1) ──────────────────────────────\n // `neat <path>` — when the first positional doesn't match any verb but\n // resolves to a directory, hand the run off to the orchestrator. This is\n // the `npx neat.is <path>` shape from ADR-073: one command, end-to-end.\n const orchestratorCode = await tryOrchestrator(cmd, parsed)\n if (orchestratorCode !== null) {\n if (orchestratorCode !== 0) process.exit(orchestratorCode)\n return\n }\n\n console.error(`neat: unknown command \"${cmd}\"`)\n usage()\n process.exit(1)\n}\n\n// Returns null when the first positional doesn't resolve to a directory\n// (so the caller can fall through to the unknown-command error). Returns\n// an exit code when the orchestrator ran.\nasync function tryOrchestrator(cmd: string, parsed: ParsedArgs): Promise<number | null> {\n const scanPath = path.resolve(cmd)\n const stat = await fs.stat(scanPath).catch(() => null)\n if (!stat || !stat.isDirectory()) return null\n\n const projectExplicit = parsed.project !== null\n const projectName = projectExplicit ? (parsed.project as string) : path.basename(scanPath)\n const result = await runOrchestrator({\n scanPath,\n project: projectName,\n projectExplicit,\n noInstrument: parsed.noInstrument,\n noOpen: parsed.noOpen,\n yes: parsed.yes,\n })\n return result.exitCode\n}\n\n// ── Query verb dispatcher ──────────────────────────────────────────────\n\nexport const QUERY_VERBS: Set<string> = new Set([\n 'root-cause',\n 'blast-radius',\n 'dependencies',\n 'observed-dependencies',\n 'incidents',\n 'search',\n 'diff',\n 'stale-edges',\n 'policies',\n // Tenth verb (ADR-060) — amends ADR-050's locked allowlist of nine.\n 'divergences',\n])\n\n// ADR-050 #2: --project flag → NEAT_PROJECT env → undefined (server's\n// `default` slot). undefined keeps legacy unprefixed routes; explicit names\n// route through /projects/:project/... Returns undefined when neither was set,\n// which is the signal to resolveProjectForVerb that it should look at the\n// registered projects and pick intelligently.\nfunction resolveProjectFlag(parsed: ParsedArgs): string | undefined {\n if (parsed.project) return parsed.project\n const env = process.env.NEAT_PROJECT\n if (env && env.length > 0 && env !== DEFAULT_PROJECT) return env\n return undefined\n}\n\n// Thrown when a bare query verb (no --project, no NEAT_PROJECT) can't pick a\n// project on its own — either nothing is registered, or several are and none\n// is named `default`. Carries an exit code so the dispatcher can surface a\n// helpful message instead of letting the request 404 on the `default` slot.\nexport class ProjectResolutionError extends Error {\n constructor(\n message: string,\n public readonly exitCode: number = 2,\n ) {\n super(message)\n this.name = 'ProjectResolutionError'\n }\n}\n\n// What `GET /projects` hands back (registry.ts RegistryEntry passthrough). We\n// only read `name`, so keep the shape minimal.\ninterface RegistryProjectSummary {\n name: string\n}\n\n// Decide which project a bare query verb should route to (issue #500). When the\n// user passed --project or set NEAT_PROJECT, that wins untouched. Otherwise we\n// ask the daemon which projects it has registered and pick:\n//\n// • exactly one registered → use it (the one-command `npx neat.is` case, so\n// `neat divergences` \"just works\" without --project)\n// • a project literally named `default` exists → keep the legacy default\n// routing (return undefined → unprefixed routes the server maps to default)\n// • several registered, none `default` → don't guess; error and list them\n// • none registered → error clearly rather than 404 on `default`\n//\n// A daemon that can't be reached lets the TransportError propagate, so the verb\n// still exits 3 with the existing \"is the daemon running?\" message.\nexport async function resolveProjectForVerb(\n client: HttpClient,\n parsed: ParsedArgs,\n): Promise<string | undefined> {\n const explicit = resolveProjectFlag(parsed)\n if (explicit) return explicit\n\n // Bare verb. Let TransportError out (exit 3); only HttpError/parse issues\n // become a resolution error here.\n const projects = await client.get<RegistryProjectSummary[]>('/projects')\n\n if (projects.some((p) => p.name === DEFAULT_PROJECT)) {\n // Back-compat: a real `default` project exists, so the legacy unprefixed\n // routes resolve. Returning undefined keeps that path.\n return undefined\n }\n\n if (projects.length === 1) {\n return projects[0]!.name\n }\n\n if (projects.length === 0) {\n throw new ProjectResolutionError(\n 'No projects are registered with the daemon yet. Run `npx neat.is` in a repo to build a graph first, then re-run this command.',\n )\n }\n\n const names = projects\n .map((p) => p.name)\n .sort()\n .map((n) => ` ${n}`)\n .join('\\n')\n throw new ProjectResolutionError(\n `Several projects are registered and none is named \"default\", so I can't pick one for you.\\n` +\n `Pass --project <name> to choose:\\n${names}`,\n )\n}\n\n// The daemon URL the CLI verbs talk to. Resolution mirrors the client-profiles\n// precedence (§3): an explicit env pin wins, then the requested project's own\n// per-project daemon (ADR-096 — one daemon per project, each on its own port),\n// then the loopback default. `NEAT_API_URL` is the name the verbs have always\n// read, so it keeps precedence for existing users; `NEAT_CORE_URL` is honored\n// as an alias so a single env var works for both the CLI and the MCP server.\n//\n// The project step is issue #579: with `--project foo` (or NEAT_PROJECT=foo)\n// but no env pin, the verb used to hit the loopback 8080 and append\n// `/projects/foo/...`, which lands on whatever daemon happens to own 8080 — a\n// different project's daemon, so it 404s. Under one-daemon-per-project the\n// project's REST port lives in its discovery record at `~/.neat/daemons/<foo>.json`;\n// resolving it there points the verb at the right daemon. A project that has no\n// discovery record falls through to loopback, unchanged.\nexport async function resolveDaemonUrl(project?: string): Promise<string> {\n const explicit = process.env.NEAT_API_URL ?? process.env.NEAT_CORE_URL\n if (explicit) return explicit\n if (project) {\n const daemon = await findDaemonByProject(project)\n if (daemon) return `http://localhost:${daemon.record.ports.rest}`\n }\n return 'http://localhost:8080'\n}\n\nexport async function runQueryVerb(cmd: string, parsed: ParsedArgs): Promise<number> {\n // Resolve the URL against the requested project up front (issue #579). When\n // the project comes from --project / NEAT_PROJECT it's known synchronously, so\n // the client points at that project's daemon before the first call. A bare\n // verb (no project named) resolves nothing here and keeps the loopback default\n // — its project is discovered from /projects below (issue #500).\n const requestedProject = resolveProjectFlag(parsed)\n const baseUrl = await resolveDaemonUrl(requestedProject)\n // ADR-073 §3 — read the bearer once and thread it into the single client\n // every verb shares, so no verb path can reach a secured daemon without it.\n const client = createHttpClient(baseUrl, resolveAuthToken())\n const positional = parsed.positional\n\n // Per-verb arg/flag validation runs first so misuse exits 2 before any\n // network call (ADR-050 #4). Each case builds a thunk that takes the\n // resolved project — we resolve the project (issue #500) only after the verb\n // proves well-formed, since resolution itself hits the daemon's /projects.\n let makeWork: (project: string | undefined) => Promise<VerbResult>\n switch (cmd) {\n case 'root-cause': {\n const node = positional[0]\n if (!node) {\n console.error('neat root-cause: missing <node-id>')\n return 2\n }\n makeWork = (project) => runRootCause(client, {\n errorNode: node,\n ...(parsed.errorId ? { errorId: parsed.errorId } : {}),\n ...(project ? { project } : {}),\n })\n break\n }\n case 'blast-radius': {\n const node = positional[0]\n if (!node) {\n console.error('neat blast-radius: missing <node-id>')\n return 2\n }\n makeWork = (project) => runBlastRadius(client, {\n nodeId: node,\n ...(parsed.depth !== null ? { depth: parsed.depth } : {}),\n ...(project ? { project } : {}),\n })\n break\n }\n case 'dependencies': {\n const node = positional[0]\n if (!node) {\n console.error('neat dependencies: missing <node-id>')\n return 2\n }\n makeWork = (project) => runDependencies(client, {\n nodeId: node,\n ...(parsed.depth !== null ? { depth: parsed.depth } : {}),\n ...(project ? { project } : {}),\n })\n break\n }\n case 'observed-dependencies': {\n const node = positional[0]\n if (!node) {\n console.error('neat observed-dependencies: missing <node-id>')\n return 2\n }\n makeWork = (project) => runObservedDependencies(client, {\n nodeId: node,\n ...(project ? { project } : {}),\n })\n break\n }\n case 'incidents': {\n // node-id is optional — bare `neat incidents` returns the global log.\n makeWork = (project) => runIncidents(client, {\n ...(positional[0] ? { nodeId: positional[0] } : {}),\n ...(parsed.limit !== null ? { limit: parsed.limit } : {}),\n ...(project ? { project } : {}),\n })\n break\n }\n case 'search': {\n const q = positional.join(' ').trim()\n if (!q) {\n console.error('neat search: missing <query>')\n return 2\n }\n makeWork = (project) => runSearch(client, { query: q, ...(project ? { project } : {}) })\n break\n }\n case 'diff': {\n // --against names a snapshot file the core can resolve via\n // loadSnapshotForDiff. --since is reserved for a future date-range\n // mode (the contract lists it as `[--since <date>]`); for MVP, the\n // diff verb requires --against.\n const against = parsed.against ?? parsed.since\n if (!against) {\n console.error('neat diff: --against <snapshot-path> is required')\n return 2\n }\n makeWork = (project) => runDiff(client, {\n againstSnapshot: against,\n ...(project ? { project } : {}),\n })\n break\n }\n case 'stale-edges': {\n makeWork = (project) => runStaleEdges(client, {\n ...(parsed.limit !== null ? { limit: parsed.limit } : {}),\n ...(parsed.edgeType ? { edgeType: parsed.edgeType } : {}),\n ...(project ? { project } : {}),\n })\n break\n }\n case 'policies': {\n let hypothetical: ReturnType<typeof JSON.parse> | undefined\n if (parsed.hypotheticalAction) {\n try {\n hypothetical = JSON.parse(parsed.hypotheticalAction)\n } catch (err) {\n console.error(\n `neat policies: --hypothetical-action must be valid JSON: ${(err as Error).message}`,\n )\n return 2\n }\n }\n makeWork = (project) => runPolicies(client, {\n ...(parsed.node ? { nodeId: parsed.node } : {}),\n ...(hypothetical ? { hypotheticalAction: hypothetical } : {}),\n ...(project ? { project } : {}),\n })\n break\n }\n case 'divergences': {\n let typeFilter: DivergenceType[] | undefined\n if (parsed.type) {\n const parts = parsed.type\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0)\n const out: DivergenceType[] = []\n for (const p of parts) {\n const r = DivergenceTypeSchema.safeParse(p)\n if (!r.success) {\n console.error(\n `neat divergences: unknown --type \"${p}\". allowed: ${DivergenceTypeSchema.options.join(', ')}`,\n )\n return 2\n }\n out.push(r.data)\n }\n typeFilter = out\n }\n makeWork = (project) => runDivergences(client, {\n ...(typeFilter ? { type: typeFilter } : {}),\n ...(parsed.minConfidence !== null ? { minConfidence: parsed.minConfidence } : {}),\n ...(parsed.node ? { node: parsed.node } : {}),\n ...(project ? { project } : {}),\n })\n break\n }\n default:\n // Unreachable — QUERY_VERBS gates the dispatch.\n console.error(`neat: unknown query verb \"${cmd}\"`)\n return 2\n }\n\n try {\n // Resolve which project to route to (issue #500). When --project /\n // NEAT_PROJECT are set this is a no-op; otherwise it asks the daemon's\n // /projects list and picks the single registered one (or keeps `default`).\n // A TransportError from here means the daemon is down — same exit-3 path as\n // any verb call.\n const project = await resolveProjectForVerb(client, parsed)\n const result = await makeWork(project)\n if (parsed.json) process.stdout.write(formatJson(result) + '\\n')\n else process.stdout.write(formatHuman(result) + '\\n')\n return 0\n } catch (err) {\n // Server / transport errors land on stderr per ADR-050 #3 (stderr for\n // diagnostics, stdout for results — never mix). Exit code branches per\n // ADR-050 #4: 1 for HttpError, 3 for TransportError.\n if (err instanceof ProjectResolutionError) {\n // Couldn't pick a project on the user's behalf (none registered, or\n // several and none named `default`). The message already says what to do.\n console.error(`neat ${cmd}: ${err.message}`)\n return err.exitCode\n }\n if (err instanceof HttpError) {\n const detail = err.responseBody.length > 0 ? err.responseBody : err.message\n console.error(`neat ${cmd}: ${detail.trim()}`)\n } else if (err instanceof TransportError) {\n console.error(`neat ${cmd}: ${err.message}. Is the daemon running? (endpoint=${baseUrl})`)\n } else {\n console.error(`neat ${cmd}: ${(err as Error).message}`)\n }\n return exitCodeForError(err)\n }\n}\n\n// Only auto-run when invoked as the CLI entry point. Importing this module\n// from tests must not start the parser; otherwise vitest sees a stray\n// `process.exit` from `main()` running with no argv.\nconst entry = process.argv[1] ?? ''\nif (/[\\\\/]cli\\.(?:cjs|js)$/.test(entry) || entry.endsWith('/cli') || entry.endsWith('/neat') || entry.endsWith('/neat.is')) {\n main().catch((err) => {\n console.error(err)\n process.exit(1)\n })\n}\n","import path from 'node:path'\nimport { readFileSync } from 'node:fs'\nimport { fileURLToPath } from 'node:url'\n\n// The `neat --version` family reads its answer from the bundled package's\n// own package.json. Reading at run time keeps the published bin in lockstep\n// with whatever version `tsup` shipped without a build-time substitution.\n// `dist/cli.cjs` sits one level below the package root.\nexport function readPackageVersion(): string {\n const here =\n typeof __dirname !== 'undefined'\n ? __dirname\n : path.dirname(fileURLToPath(import.meta.url))\n // dist/ → package root. tsup writes both cjs and mjs to dist/, so the\n // parent-of-parent walk is the same in either format.\n const candidates = [\n path.resolve(here, '../package.json'),\n path.resolve(here, '../../package.json'),\n ]\n for (const candidate of candidates) {\n try {\n const raw = readFileSync(candidate, 'utf8')\n const parsed = JSON.parse(raw) as { name?: string; version?: string }\n if (parsed.name === '@neat.is/core' && typeof parsed.version === 'string') {\n return parsed.version\n }\n } catch {\n // try the next candidate\n }\n }\n return 'unknown'\n}\n\n// The ASCII banner. Shared between the CLI's `neat init` discovery report and\n// the one-command orchestrator (issue #483) so the artwork lives in exactly\n// one place — no duplicated glyphs to drift apart.\nexport function printBanner(): void {\n console.log('███╗ ██╗███████╗ █████╗ ████████╗')\n console.log('████╗ ██║██╔════╝██╔══██╗╚══██╔══╝')\n console.log('██╔██╗ ██║█████╗ ███████║ ██║ ')\n console.log('██║╚██╗██║██╔══╝ ██╔══██║ ██║ ')\n console.log('██║ ╚████║███████╗██║ ██║ ██║ ')\n console.log('╚═╝ ╚═══╝╚══════╝╚═╝ ╚═╝ ╚═╝ ')\n console.log('')\n console.log(' Network Expressive Architecting Tool')\n console.log(` neat.is · v${readPackageVersion()} · Apache 2.0`)\n console.log('')\n}\n","/**\n * `.gitignore` automation for the init flow (ADR-073 §6).\n *\n * Init writes a snapshot under `<projectDir>/neat-out/`. Un-ignored, that\n * directory leaks the snapshot into git history within one commit. The\n * helper here ensures `neat-out/` is present in `<projectDir>/.gitignore` —\n * appending to an existing file with a NEAT comment header, creating the\n * file when absent, no-oping when the line is already there.\n *\n * Idempotency rule: an exact-match line (`neat-out/` or `neat-out`, with\n * any surrounding whitespace) counts as already-present. No duplicate\n * line is written on a re-run.\n */\n\nimport { promises as fs } from 'node:fs'\nimport path from 'node:path'\n\nexport const NEAT_OUT_LINE = 'neat-out/'\nconst NEAT_HEADER = '# NEAT — machine-local snapshots and events'\n\nexport interface EnsureNeatOutResult {\n // 'added' when the line was appended to an existing .gitignore.\n // 'created' when the file did not exist and was created with a single line.\n // 'unchanged' when the line was already present.\n action: 'added' | 'created' | 'unchanged'\n // Absolute path to the .gitignore file, regardless of action.\n file: string\n}\n\nfunction isNeatOutLine(line: string): boolean {\n const trimmed = line.trim()\n return trimmed === 'neat-out/' || trimmed === 'neat-out'\n}\n\nexport async function ensureNeatOutIgnored(projectDir: string): Promise<EnsureNeatOutResult> {\n const file = path.join(projectDir, '.gitignore')\n let existing: string | null = null\n try {\n existing = await fs.readFile(file, 'utf8')\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err\n }\n\n if (existing === null) {\n await fs.writeFile(file, `${NEAT_HEADER}\\n${NEAT_OUT_LINE}\\n`, 'utf8')\n return { action: 'created', file }\n }\n\n for (const line of existing.split(/\\r?\\n/)) {\n if (isNeatOutLine(line)) return { action: 'unchanged', file }\n }\n\n // Append with a leading newline if the file doesn't already end in one,\n // so the comment header sits on its own line.\n const needsLeadingNewline = existing.length > 0 && !existing.endsWith('\\n')\n const appended = `${needsLeadingNewline ? '\\n' : ''}\\n${NEAT_HEADER}\\n${NEAT_OUT_LINE}\\n`\n await fs.writeFile(file, existing + appended, 'utf8')\n return { action: 'added', file }\n}\n","/**\n * Value-forward CLI summary (issue #305, ADR-073 §5).\n *\n * Replaces the per-type node/edge counts that ended `neat init` with a\n * findings-first block — compat violations, top divergences, services\n * that never produced an OBSERVED edge, and the OTel env-vars block the\n * operator pastes into their deploy platform. Per-type counts move behind\n * `--verbose`.\n *\n * The renderer is a pure string builder so tests can assert against its\n * output without spawning the CLI.\n */\n\nimport type { Divergence, GraphEdge, GraphNode, ServiceNode } from '@neat.is/types'\nimport { NodeType, Provenance } from '@neat.is/types'\nimport type { NeatGraph } from './graph.js'\n\nexport interface SummaryInput {\n graph: NeatGraph\n divergences: Divergence[]\n // True → render the per-type counts after the value-forward block.\n verbose: boolean\n}\n\n// Static placeholder. The orchestrator and `neat deploy` print the same\n// block; `neat deploy` substitutes the actual token + host. This shape\n// lives in one place so the wire format stays in step.\nexport function renderOtelEnvBlock(): string {\n return [\n 'for prod OTel routing, set these in your deploy platform\\'s env:',\n ' OTEL_EXPORTER_OTLP_ENDPOINT=https://<your-neat-host>:4318',\n ' OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer <NEAT_AUTH_TOKEN>',\n ].join('\\n')\n}\n\nfunction findIncompatServices(nodes: GraphNode[]): ServiceNode[] {\n return nodes.filter(\n (n): n is ServiceNode =>\n n.type === NodeType.ServiceNode &&\n Array.isArray((n as ServiceNode).incompatibilities) &&\n ((n as ServiceNode).incompatibilities ?? []).length > 0,\n )\n}\n\n// Services that show up in the EXTRACTED graph but have no OBSERVED edge\n// pointing at or out of them. The thesis says: when the OBSERVED layer is\n// silent on a service, the gap is a load-bearing signal for the operator.\nfunction servicesWithoutObserved(nodes: GraphNode[], edges: GraphEdge[]): ServiceNode[] {\n const seen = new Set<string>()\n for (const e of edges) {\n if (e.provenance === Provenance.OBSERVED) {\n seen.add(e.source)\n seen.add(e.target)\n }\n }\n return nodes.filter(\n (n): n is ServiceNode => n.type === NodeType.ServiceNode && !seen.has(n.id),\n )\n}\n\nfunction formatDivergence(d: Divergence): string {\n // Short, scannable, one-line-per-finding. The reason field already carries\n // the load-bearing detail; the recommendation rides on a second indent.\n const conf = d.confidence.toFixed(2)\n return ` [${conf}] ${d.type} ${d.source} → ${d.target} — ${d.reason}`\n}\n\nexport function renderValueForwardSummary(input: SummaryInput): string {\n const { graph, divergences, verbose } = input\n const nodes: GraphNode[] = []\n graph.forEachNode((_id, attrs) => nodes.push(attrs))\n const edges: GraphEdge[] = []\n graph.forEachEdge((_id, attrs) => edges.push(attrs))\n\n const lines: string[] = []\n lines.push('=== neat: findings ===')\n lines.push('')\n\n // ── Compat violations (driver/engine mismatches) ───────────────────────\n const incompatServices = findIncompatServices(nodes)\n const totalIncompats = incompatServices.reduce(\n (acc, s) => acc + (s.incompatibilities?.length ?? 0),\n 0,\n )\n lines.push(`compat violations: ${totalIncompats}`)\n for (const svc of incompatServices) {\n for (const inc of svc.incompatibilities ?? []) {\n const detail = formatIncompat(inc)\n lines.push(` ${svc.name}: ${detail}`)\n }\n }\n lines.push('')\n\n // ── Top divergences (top 3 by confidence desc) ─────────────────────────\n const top = [...divergences].sort((a, b) => b.confidence - a.confidence).slice(0, 3)\n lines.push(`top divergences: ${divergences.length} total${top.length > 0 ? ', top 3:' : ''}`)\n for (const d of top) lines.push(formatDivergence(d))\n lines.push('')\n\n // ── Services missing OBSERVED coverage ─────────────────────────────────\n const noObserved = servicesWithoutObserved(nodes, edges)\n if (noObserved.length > 0) {\n lines.push(`services without OBSERVED coverage: ${noObserved.length}`)\n for (const svc of noObserved) lines.push(` ${svc.name}`)\n lines.push(' → run your services with the generated otel-init to populate OBSERVED edges.')\n lines.push('')\n }\n\n // ── OTel env-vars block (static; `neat deploy` substitutes real values)\n lines.push(renderOtelEnvBlock())\n lines.push('')\n\n // ── --verbose: per-type node/edge counts ──────────────────────────────\n if (verbose) {\n const byNode = new Map<string, number>()\n for (const n of nodes) byNode.set(n.type, (byNode.get(n.type) ?? 0) + 1)\n const byEdge = new Map<string, number>()\n for (const e of edges) byEdge.set(e.type, (byEdge.get(e.type) ?? 0) + 1)\n lines.push('=== graph (verbose) ===')\n lines.push(`total: ${graph.order} nodes, ${graph.size} edges`)\n lines.push('nodes:')\n for (const [t, c] of [...byNode.entries()].sort()) lines.push(` ${t}: ${c}`)\n lines.push('edges:')\n for (const [t, c] of [...byEdge.entries()].sort()) lines.push(` ${t}: ${c}`)\n lines.push('')\n }\n\n return lines.join('\\n')\n}\n\nfunction formatIncompat(inc: NonNullable<ServiceNode['incompatibilities']>[number]): string {\n if (inc.kind === 'node-engine') {\n const range = inc.declaredNodeEngine ? ` (engines.node=\"${inc.declaredNodeEngine}\")` : ''\n return `${inc.package}@${inc.packageVersion ?? '?'} requires Node ${inc.requiredNodeVersion}${range} — ${inc.reason}`\n }\n if (inc.kind === 'package-conflict') {\n const found = inc.foundVersion ? `@${inc.foundVersion}` : ' (missing)'\n return `${inc.package}@${inc.packageVersion ?? '?'} requires ${inc.requires.name}>=${inc.requires.minVersion}; found ${inc.requires.name}${found} — ${inc.reason}`\n }\n if (inc.kind === 'deprecated-api') {\n return `${inc.package}@${inc.packageVersion ?? '?'} is deprecated — ${inc.reason}`\n }\n return `${inc.driver}@${inc.driverVersion} vs ${inc.engine} ${inc.engineVersion} — ${inc.reason}`\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport chokidar, { type FSWatcher } from 'chokidar'\nimport type { FastifyInstance } from 'fastify'\nimport type { NeatGraph } from './graph.js'\nimport { buildApi } from './api.js'\nimport { assertBindAuthority, readAuthEnv } from './auth.js'\nimport { ensureCompatLoaded } from './compat.js'\nimport { discoverServices, addServiceNodes } from './extract/services.js'\nimport { addServiceAliases } from './extract/aliases.js'\nimport { addFiles } from './extract/files.js'\nimport { addImports } from './extract/imports.js'\nimport { addDatabasesAndCompat } from './extract/databases/index.js'\nimport { addConfigNodes } from './extract/configs.js'\nimport { addCallEdges } from './extract/calls/index.js'\nimport { addInfra } from './extract/infra/index.js'\nimport { retireEdgesByFile } from './extract/retire.js'\nimport {\n makeErrorSpanWriter,\n makeSpanHandler,\n promoteFrontierNodes,\n startStalenessLoop,\n} from './ingest.js'\nimport {\n evaluateAllPolicies,\n loadPolicyFile,\n PolicyViolationsLog,\n} from './policy.js'\nimport type { Policy } from '@neat.is/types'\nimport { buildOtelReceiver, listenSteppingOtlp } from './otel.js'\nimport {\n clearDaemonRecord,\n portFromListenAddress,\n resolveNeatVersion,\n writeDaemonRecord,\n type DaemonRecord,\n} from './daemon.js'\nimport { startOtelGrpcReceiver } from './otel-grpc.js'\nimport { loadGraphFromDisk, startPersistLoop } from './persist.js'\nimport { buildSearchIndex, type SearchIndex } from './search.js'\nimport { DEFAULT_PROJECT } from './graph.js'\nimport { Projects, pathsForProject } from './projects.js'\nimport { attachGraphToEventBus, emitNeatEvent } from './events.js'\n\nexport type ExtractPhase =\n | 'services'\n | 'aliases'\n | 'files'\n | 'imports'\n | 'databases'\n | 'configs'\n | 'calls'\n | 'infra'\n\nconst ALL_PHASES: ExtractPhase[] = [\n 'services',\n 'aliases',\n 'files',\n 'imports',\n 'databases',\n 'configs',\n 'calls',\n 'infra',\n]\n\n// Map a changed path to the phases that need re-running. Anything not matched\n// here falls back to a full re-extract — better an extra ~50ms of work than a\n// missed update because the path didn't fit a regex.\n//\n// Mapping:\n// package.json / requirements.txt / pyproject.toml → services + aliases + databases\n// (deps drive compat; aliases pull from manifest fields)\n// .env / *.env.* / prisma / knex / ormconfig → databases + configs\n// docker-compose / Dockerfile / *.tf / k8s yaml → infra + aliases\n// (compose labels and Dockerfile labels feed alias discovery)\n// *.js / *.ts / *.tsx / *.py / *.jsx / *.mjs / *.cjs → files + imports + calls\n// (a source edit can shift both its IMPORTS and CALLS edges; the shared\n// evidence.file retirement mechanism — static-extraction.md §Ghost-edge\n// cleanup — drops the stale ones from either producer before re-running.\n// The `files` phase re-enumerates FileNodes first: retiring an edited\n// file's edges also drops its CONTAINS edge — whose evidence.file is the\n// file itself — and can orphan the FileNode, so Phase 1 has to rebuild it\n// before imports/calls originate edges from it, or addImports emits from a\n// node that no longer exists.)\n// *.yaml / *.yml that isn't compose → databases + configs (ORM yaml fallbacks)\nexport function classifyChange(relPath: string): Set<ExtractPhase> {\n const phases = new Set<ExtractPhase>()\n const base = path.basename(relPath).toLowerCase()\n const segments = relPath.split(path.sep).map((s) => s.toLowerCase())\n\n if (\n base === 'package.json' ||\n base === 'requirements.txt' ||\n base === 'pyproject.toml' ||\n base === 'setup.py'\n ) {\n phases.add('services')\n phases.add('aliases')\n phases.add('databases')\n }\n\n if (\n base === '.env' ||\n base.startsWith('.env.') ||\n base === 'schema.prisma' ||\n /^knexfile\\.(?:js|ts|cjs|mjs)$/.test(base) ||\n /^ormconfig\\.(?:js|ts|json|ya?ml)$/.test(base)\n ) {\n phases.add('databases')\n phases.add('configs')\n }\n\n if (\n base === 'dockerfile' ||\n /^docker-compose.*\\.ya?ml$/.test(base) ||\n base.endsWith('.tf') ||\n segments.includes('k8s') ||\n segments.includes('kustomize') ||\n segments.includes('manifests')\n ) {\n phases.add('infra')\n phases.add('aliases')\n }\n\n if (/\\.(?:js|jsx|mjs|cjs|ts|tsx|py)$/.test(base)) {\n phases.add('files')\n phases.add('imports')\n phases.add('calls')\n }\n\n if (/\\.ya?ml$/.test(base) && !/^docker-compose.*\\.ya?ml$/.test(base)) {\n // Generic yaml — could be an ORM file, k8s manifest, or random config.\n // Cheap to run databases + configs; if it was infra, the dir-name check\n // above already added that phase.\n phases.add('databases')\n phases.add('configs')\n }\n\n return phases\n}\n\ninterface RunPhasesResult {\n phases: ExtractPhase[]\n nodesAdded: number\n edgesAdded: number\n frontiersPromoted: number\n durationMs: number\n}\n\nexport async function runExtractPhases(\n graph: NeatGraph,\n scanPath: string,\n phases: Set<ExtractPhase>,\n // Project tag passed through for the runtime event bus (ADR-051) — not\n // required for extraction logic itself but threaded for parity with\n // extractFromDirectory's project option.\n project: string = DEFAULT_PROJECT,\n): Promise<RunPhasesResult> {\n void project\n const started = Date.now()\n await ensureCompatLoaded()\n // Discovery is cheap and every phase needs the same DiscoveredService list,\n // so we always re-walk. If the user moved a service directory, this is also\n // the path that picks it up.\n const services = await discoverServices(scanPath)\n\n let nodesAdded = 0\n let edgesAdded = 0\n\n if (phases.has('services')) {\n nodesAdded += addServiceNodes(graph, services)\n }\n if (phases.has('aliases')) {\n await addServiceAliases(graph, scanPath, services)\n }\n // Phase 1 — file enumeration runs before imports/calls (file-awareness.md §1).\n // Both of those producers originate edges from FileNodes; a re-extract driven\n // by a source edit has already retired that file's CONTAINS edge (its\n // evidence.file is the file itself) and may have swept the now-orphaned\n // FileNode, so rebuilding it here is what keeps addImports from emitting an\n // edge off a missing node. Idempotent — an unchanged tree is a no-op.\n if (phases.has('files')) {\n const r = await addFiles(graph, services)\n nodesAdded += r.nodesAdded\n edgesAdded += r.edgesAdded\n }\n if (phases.has('imports')) {\n const r = await addImports(graph, services)\n nodesAdded += r.nodesAdded\n edgesAdded += r.edgesAdded\n }\n if (phases.has('databases')) {\n const r = await addDatabasesAndCompat(graph, services, scanPath)\n nodesAdded += r.nodesAdded\n edgesAdded += r.edgesAdded\n }\n if (phases.has('configs')) {\n const r = await addConfigNodes(graph, services, scanPath)\n nodesAdded += r.nodesAdded\n edgesAdded += r.edgesAdded\n }\n if (phases.has('calls')) {\n const r = await addCallEdges(graph, services)\n nodesAdded += r.nodesAdded\n edgesAdded += r.edgesAdded\n }\n if (phases.has('infra')) {\n const r = await addInfra(graph, scanPath, services)\n nodesAdded += r.nodesAdded\n edgesAdded += r.edgesAdded\n }\n const frontiersPromoted = promoteFrontierNodes(graph)\n\n return {\n phases: ALL_PHASES.filter((p) => phases.has(p)),\n nodesAdded,\n edgesAdded,\n frontiersPromoted,\n durationMs: Date.now() - started,\n }\n}\n\n// The canonical dashboard port recorded in daemon.json. `neat watch` binds no\n// dashboard of its own, but the DaemonRecord shape requires a web port; only\n// ports.otlp is load-bearing for the OBSERVED endpoint resolution this record\n// exists to serve. Mirrors DEFAULT_WEB_PORT in web-spawn.ts.\nconst DEFAULT_WATCH_WEB_PORT = 6328\n\nexport interface WatchOptions {\n scanPath: string\n outPath: string\n errorsPath: string\n staleEventsPath: string\n embeddingsCachePath?: string\n // Project name this watch instance owns. Defaults to `default` for the\n // single-project workflow that's been the only one until #83.\n project?: string\n host?: string\n port?: number\n otelPort?: number\n otelGrpc?: boolean\n otelGrpcPort?: number\n debounceMs?: number\n}\n\nexport interface WatchHandle {\n api: FastifyInstance\n stop: () => Promise<void>\n}\n\n// Anymatch-compatible ignore set passed to chokidar (#233). The earlier\n// implementation passed a function alone, which forced chokidar to descend\n// into every subdirectory before testing the path. On macOS with kqueue\n// (chokidar 4 dropped fsevents in favour of kqueue), each subdir under the\n// scan root opens a watch handle; nested `node_modules` blew through the\n// per-process kqueue cap with EMFILE before the function-based ignore ever\n// fired. Globs let chokidar prune at descent time — the dirs are never\n// opened in the first place.\nconst IGNORED_WATCH_GLOBS = [\n '**/node_modules/**',\n '**/.git/**',\n '**/dist/**',\n '**/build/**',\n '**/.turbo/**',\n '**/.next/**',\n '**/neat-out/**',\n // Python venv shapes (issue #344). chokidar opens one watch handle per\n // descended dir; a CPython venv carries 20k+ files and trivially blows\n // through the macOS kqueue cap before extraction even runs.\n '**/.venv/**',\n '**/venv/**',\n '**/__pypackages__/**',\n '**/.tox/**',\n '**/site-packages/**',\n '**/.DS_Store',\n]\n\n// Backstop regex set — covers anything chokidar surfaces post-descent that\n// the globs missed (e.g. a path containing one of these segments at an\n// unexpected depth). Same shape as before; the globs are the load-bearing\n// pruning, this is defence in depth.\nconst IGNORED_WATCH_PATHS = [\n /(?:^|[\\\\/])node_modules[\\\\/]/,\n /(?:^|[\\\\/])\\.git[\\\\/]/,\n /(?:^|[\\\\/])dist[\\\\/]/,\n /(?:^|[\\\\/])build[\\\\/]/,\n /(?:^|[\\\\/])\\.turbo[\\\\/]/,\n /(?:^|[\\\\/])\\.next[\\\\/]/,\n /(?:^|[\\\\/])neat-out[\\\\/]/,\n /(?:^|[\\\\/])\\.venv[\\\\/]/,\n /(?:^|[\\\\/])venv[\\\\/]/,\n /(?:^|[\\\\/])__pypackages__[\\\\/]/,\n /(?:^|[\\\\/])\\.tox[\\\\/]/,\n /(?:^|[\\\\/])site-packages[\\\\/]/,\n /[\\\\/]?\\.DS_Store$/,\n]\n\nfunction shouldIgnore(absPath: string): boolean {\n return IGNORED_WATCH_PATHS.some((re) => re.test(absPath))\n}\n\n// Roughly the number of immediate, non-ignored subdirectories in the scan\n// root above which `neat watch` should fall back to polling on darwin. kqueue\n// opens one handle per watched dir; macOS's per-process file-descriptor cap\n// is typically 256 (soft) / unlimited (hard) but raising the hard cap doesn't\n// help with the kqueue-specific limits. Empirically anything north of ~500\n// non-ignored dirs starts to flirt with EMFILE. Threshold sits comfortably\n// under that.\nconst DARWIN_POLLING_DIR_THRESHOLD = 400\n\n// Fast non-recursive count: walk top-level entries only, descending one\n// level into non-ignored subdirs to capture the medusa-shaped case where\n// `packages/*` itself looks small but each contains a heavy `node_modules`.\n// Returns early once it crosses the threshold so we don't waste time on huge\n// repos.\nfunction countWatchableDirs(scanPath: string, limit: number): number {\n let count = 0\n const visit = (dir: string, depth: number): void => {\n if (count >= limit) return\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true })\n } catch {\n return\n }\n for (const e of entries) {\n if (count >= limit) return\n if (!e.isDirectory()) continue\n if (IGNORED_WATCH_PATHS.some((re) => re.test(path.join(dir, e.name) + path.sep))) continue\n count++\n // One level deeper — enough to surface nested `node_modules` shapes\n // without traversing the whole tree.\n if (depth < 2) visit(path.join(dir, e.name), depth + 1)\n }\n }\n visit(scanPath, 0)\n return count\n}\n\n// Darwin heuristic (#233). Forces chokidar onto polling when the scan root\n// is large enough that kqueue would EMFILE. Override via NEAT_WATCH_POLLING:\n// - \"1\" / \"true\" → force polling regardless of platform/threshold\n// - \"0\" / \"false\" → never poll (matches pre-#233 behaviour)\n// - unset → auto-detect on darwin\nfunction shouldUsePolling(scanPath: string): boolean {\n const env = process.env.NEAT_WATCH_POLLING\n if (env === '1' || env === 'true') return true\n if (env === '0' || env === 'false') return false\n if (process.platform !== 'darwin') return false\n return countWatchableDirs(scanPath, DARWIN_POLLING_DIR_THRESHOLD) >= DARWIN_POLLING_DIR_THRESHOLD\n}\n\nexport async function startWatch(\n graph: NeatGraph,\n opts: WatchOptions,\n): Promise<WatchHandle> {\n const debounceMs = opts.debounceMs ?? 1000\n const projectName = opts.project ?? DEFAULT_PROJECT\n\n await loadGraphFromDisk(graph, opts.outPath)\n\n // Wire graph mutations into the event bus (ADR-051) before extract begins\n // so the initial pass also produces node/edge events. Detached on stop().\n const detachEventBus = attachGraphToEventBus(graph, { project: projectName })\n\n // Load policies + open the violations log once at startup. policy.json\n // lives at the project root per ADR-042 §File location; absent file is\n // a perfectly fine state (loadPolicyFile returns []). Reload-on-change\n // is queued for v0.2.5 — the kickoff doc tracks it.\n const policyFilePath = path.join(opts.scanPath, 'policy.json')\n const policyViolationsPath = path.join(path.dirname(opts.outPath), 'policy-violations.ndjson')\n let policies: Policy[] = []\n try {\n policies = await loadPolicyFile(policyFilePath)\n if (policies.length > 0) {\n console.log(`policies: loaded ${policies.length} from ${policyFilePath}`)\n }\n } catch (err) {\n console.warn(`policies: failed to load ${policyFilePath} — ${(err as Error).message}`)\n }\n const policyLog = new PolicyViolationsLog(policyViolationsPath, projectName)\n\n // Single shared trigger callback wired into post-ingest, post-extract, and\n // post-stale per ADR-043. Failures append to console.warn but don't kill\n // the daemon — a malformed evaluator shouldn't take down ingest.\n const onPolicyTrigger = async (g: NeatGraph): Promise<void> => {\n if (policies.length === 0) return\n try {\n const violations = evaluateAllPolicies(g, policies, { now: () => Date.now() })\n for (const v of violations) await policyLog.append(v)\n } catch (err) {\n console.warn(`policies: evaluation failed — ${(err as Error).message}`)\n }\n }\n\n // The post-extract trigger fires from extractFromDirectory via opts.\n // For the initial extract here we run it inline so violations land on\n // startup before the receiver opens. Subsequent watch-driven re-extract\n // passes go through runExtractPhases which doesn't take the hook directly\n // — we run it after each flush() instead.\n const initial = await runExtractPhases(\n graph,\n opts.scanPath,\n new Set(ALL_PHASES),\n projectName,\n )\n console.log(\n `extract: ${initial.nodesAdded} new nodes, ${initial.edgesAdded} new edges (graph total ${graph.order}/${graph.size})`,\n )\n // extraction-complete for the initial pass (ADR-051). runExtractPhases\n // doesn't emit on its own — the event lives at the watch / orchestrator\n // boundary so the daemon can swap in its own emission shape.\n emitNeatEvent({\n type: 'extraction-complete',\n project: projectName,\n payload: {\n project: projectName,\n fileCount: 0,\n nodesAdded: initial.nodesAdded,\n edgesAdded: initial.edgesAdded,\n },\n })\n await onPolicyTrigger(graph)\n\n const stopPersist = startPersistLoop(graph, opts.outPath)\n const stopStaleness = startStalenessLoop(graph, {\n staleEventsPath: opts.staleEventsPath,\n project: projectName,\n onPolicyTrigger,\n })\n\n // ADR-073 §3/§4 + issue #341 — `neat watch` follows the same bind discipline\n // as the daemon: an explicit host wins; otherwise loopback-only without a\n // token (laptop dev), public bind once `NEAT_AUTH_TOKEN` is set. buildApi\n // mounts the bearer gate from the same env, so a token-protected watch\n // returns 401 to unauthenticated callers exactly as `neatd` does.\n const auth = readAuthEnv()\n const host = opts.host ?? (auth.authToken ? '0.0.0.0' : '127.0.0.1')\n assertBindAuthority(host, auth.authToken)\n const port = opts.port ?? 8080\n const otelPort = opts.otelPort ?? 4318\n\n const cachePath =\n opts.embeddingsCachePath ?? path.join(path.dirname(opts.outPath), 'embeddings.json')\n let searchIndex: SearchIndex | undefined\n try {\n searchIndex = await buildSearchIndex(graph, { cachePath })\n console.log(`semantic_search: ${searchIndex.provider} provider`)\n } catch (err) {\n console.warn(\n `semantic_search: index build failed (${(err as Error).message}); falling back to inline substring`,\n )\n }\n\n const registry = new Projects()\n registry.set(projectName, {\n graph,\n scanPath: opts.scanPath,\n paths: {\n // Paths are derived from the explicit options the watch caller passes\n // — pathsForProject is only used to fill in the embeddings/snapshot\n // fields so the registry shape is complete.\n ...pathsForProject(projectName, path.dirname(opts.outPath)),\n snapshotPath: opts.outPath,\n errorsPath: opts.errorsPath,\n staleEventsPath: opts.staleEventsPath,\n },\n searchIndex,\n })\n\n const api = await buildApi({ projects: registry })\n const restAddress = await api.listen({ port, host })\n console.log(`neat-core listening on http://${host}:${port}`)\n console.log(` scan path: ${opts.scanPath} (watching for changes)`)\n console.log(` snapshot path: ${opts.outPath}`)\n console.log(` errors log: ${opts.errorsPath}`)\n\n // The receiver writes ErrorEvents synchronously before reply (durability).\n // makeSpanHandler runs on the async queue and skips the inline write\n // because the receiver already handled it. Ad-hoc callers that bypass the\n // receiver (CLI tests, fixtures) leave writeErrorEventInline at its default\n // and get the in-handleSpan write. ADR-033 §Error events.\n const onSpan = makeSpanHandler({\n graph,\n errorsPath: opts.errorsPath,\n scanPath: opts.scanPath,\n project: projectName,\n writeErrorEventInline: false,\n onPolicyTrigger,\n })\n const onErrorSpanSync = makeErrorSpanWriter(opts.errorsPath, graph, opts.scanPath)\n const otelHttp = await buildOtelReceiver({ onSpan, onErrorSpanSync })\n // A held OTLP port steps to the next free one rather than crashing the watch\n // process (daemon.md §Binding). The real bound port is what daemon.json\n // records below, so the instrumented app's otel-init resolves the right one.\n const otelAddress = await listenSteppingOtlp(otelHttp, otelPort, host)\n const boundOtelPort = portFromListenAddress(otelAddress, otelPort)\n console.log(`neat-core OTLP receiver on ${otelAddress}/v1/traces`)\n\n // Self-description (project-daemon §2). `neat watch` is a per-project daemon\n // in the dev loop: the generated otel-init resolves its OTLP endpoint from\n // `<project>/neat-out/daemon.json` `ports.otlp`, so an app instrumented\n // against a watch bound to a non-default (or stepped) OTLP port would fall\n // back to `:4318` and dark OBSERVED without this record.\n const boundRestPort = portFromListenAddress(restAddress, port)\n const daemonRecord: DaemonRecord = {\n project: projectName,\n projectPath: opts.scanPath,\n pid: process.pid,\n status: 'running',\n ports: {\n rest: boundRestPort,\n otlp: boundOtelPort,\n // watch serves no dashboard of its own; record the canonical web port so\n // the record shape is valid. Only ports.otlp is load-bearing here.\n web: DEFAULT_WATCH_WEB_PORT,\n },\n startedAt: new Date().toISOString(),\n neatVersion: resolveNeatVersion(),\n }\n try {\n await writeDaemonRecord(daemonRecord)\n console.log(\n `neat watch: wrote daemon.json (REST ${boundRestPort} / OTLP ${boundOtelPort})`,\n )\n } catch (err) {\n // The record is load-bearing for the OBSERVED layer; without it the app\n // silently falls back to :4318. Fail loud rather than run half-dark.\n await api.close().catch(() => {})\n await otelHttp.close().catch(() => {})\n throw new Error(\n `neat watch: failed to write daemon.json — ${(err as Error).message}`,\n )\n }\n\n let grpcReceiver: { stop: () => Promise<void> } | null = null\n if (opts.otelGrpc) {\n const grpcPort = opts.otelGrpcPort ?? 4317\n // gRPC handler keeps the inline ErrorEvent write — the gRPC receiver\n // awaits onSpan synchronously (otel-grpc.ts), so the same durability\n // guarantee is met without a separate sync hook. Non-blocking gRPC\n // ingest is out of scope for the v0.2.2 batch.\n const onSpanGrpc = makeSpanHandler({\n graph,\n errorsPath: opts.errorsPath,\n scanPath: opts.scanPath,\n project: projectName,\n onPolicyTrigger,\n })\n const r = await startOtelGrpcReceiver({ onSpan: onSpanGrpc, host, port: grpcPort })\n console.log(`neat-core OTLP/gRPC receiver on ${r.address}`)\n grpcReceiver = r\n }\n\n // Coalesce bursts of changes into a single re-extract. chokidar fires one\n // event per affected path; an editor save can produce 3+ events on the same\n // file in <50ms.\n const pending = new Set<ExtractPhase>()\n const pendingPaths = new Set<string>()\n let timer: NodeJS.Timeout | null = null\n let inflight: Promise<void> | null = null\n\n const flush = async (): Promise<void> => {\n if (pending.size === 0) return\n const phases = new Set(pending)\n const paths = new Set(pendingPaths)\n pending.clear()\n pendingPaths.clear()\n try {\n // Drop EXTRACTED edges keyed to changed paths first, so the producer's\n // idempotent re-extract recreates only the edges that still apply.\n // Without this, edges from deleted code would survive forever\n // (docs/contracts/static-extraction.md §Ghost-edge cleanup).\n let retired = 0\n for (const p of paths) retired += retireEdgesByFile(graph, p)\n const result = await runExtractPhases(graph, opts.scanPath, phases, projectName)\n console.log(\n `[watch] re-extract phases=${result.phases.join(',')} retired=${retired} +${result.nodesAdded}n/+${result.edgesAdded}e in ${result.durationMs}ms`,\n )\n // extraction-complete after every re-extract pass (ADR-051). fileCount\n // is the number of paths that drove the pass — closest signal we have\n // for \"how much source moved\" without per-phase accounting.\n emitNeatEvent({\n type: 'extraction-complete',\n project: projectName,\n payload: {\n project: projectName,\n fileCount: paths.size,\n nodesAdded: result.nodesAdded,\n edgesAdded: result.edgesAdded,\n },\n })\n if (searchIndex) {\n try {\n await searchIndex.refresh(graph)\n } catch (err) {\n console.warn('[watch] semantic_search refresh failed', err)\n }\n }\n // Post-extract policy trigger (ADR-043). The runExtractPhases call\n // doesn't take the hook directly — it runs through promoteFrontierNodes\n // for FRONTIER → OBSERVED upgrades but doesn't load policies itself.\n // Firing the evaluator here keeps the trigger surface symmetric across\n // ingest / extract / stale paths.\n await onPolicyTrigger(graph)\n } catch (err) {\n console.error('[watch] re-extract failed', err)\n }\n }\n\n const schedule = (): void => {\n if (timer) clearTimeout(timer)\n timer = setTimeout(() => {\n timer = null\n // Serialise re-extracts so two flushes can't interleave on the graph.\n inflight = (inflight ?? Promise.resolve()).then(flush)\n }, debounceMs)\n }\n\n const onPath = (absPath: string): void => {\n if (shouldIgnore(absPath)) return\n const rel = path.relative(opts.scanPath, absPath)\n if (!rel || rel.startsWith('..')) return\n pendingPaths.add(rel.split(path.sep).join('/'))\n const phases = classifyChange(rel)\n if (phases.size === 0) {\n // Unknown file kind — fall back to full re-extract rather than silently\n // miss it. Cheaper than the user wondering why their change didn't show.\n for (const p of ALL_PHASES) pending.add(p)\n } else {\n for (const p of phases) pending.add(p)\n }\n schedule()\n }\n\n const usePolling = shouldUsePolling(opts.scanPath)\n if (usePolling) {\n const reason =\n process.env.NEAT_WATCH_POLLING === '1' || process.env.NEAT_WATCH_POLLING === 'true'\n ? 'NEAT_WATCH_POLLING env override'\n : 'darwin heuristic — large scan root, kqueue cap risk'\n console.log(`[${projectName}] watch: usePolling=true (${reason})`)\n }\n const watcher: FSWatcher = chokidar.watch(opts.scanPath, {\n ignoreInitial: true,\n // Glob array prunes at descent time (#233) so chokidar never opens a\n // kqueue handle for `node_modules` and friends. The function backstop\n // catches any path that slipped through and matches the regex set.\n ignored: [...IGNORED_WATCH_GLOBS, (p: string) => shouldIgnore(p)],\n persistent: true,\n usePolling,\n awaitWriteFinish: { stabilityThreshold: 200, pollInterval: 50 },\n })\n watcher.on('add', onPath)\n watcher.on('change', onPath)\n watcher.on('unlink', onPath)\n watcher.on('addDir', onPath)\n watcher.on('unlinkDir', onPath)\n\n let stopped = false\n const stop = async (): Promise<void> => {\n if (stopped) return\n stopped = true\n if (timer) clearTimeout(timer)\n timer = null\n if (inflight) {\n try {\n await inflight\n } catch {\n // surfaced already in flush()\n }\n }\n await watcher.close()\n stopStaleness()\n stopPersist()\n detachEventBus()\n await api.close()\n await otelHttp.close()\n if (grpcReceiver) await grpcReceiver.stop()\n // Reconcile the self-description on shutdown (project-daemon §2) so a\n // stopped watch never leaves a `running` record pointing an app at a\n // receiver nothing is listening on.\n await clearDaemonRecord(daemonRecord).catch(() => {})\n }\n\n return { api, stop }\n}\n","/**\n * `neat deploy` substrate detection + artifact generation (ADR-073 §2).\n *\n * Three substrates, detected in order:\n *\n * 1. Docker + `docker compose` present → emit `docker-compose.neat.yml`.\n * 2. Bare machine with `systemctl` available → emit `neat.service`.\n * 3. Fallback → print a `docker run` snippet to stdout.\n *\n * Every branch generates a fresh `NEAT_AUTH_TOKEN` (32 bytes, base64url),\n * prints it once, and never embeds it in the on-disk artifact — the file\n * names the env-var, the operator stores the value out of band.\n *\n * Every branch also prints the OTel env-vars block the operator pastes into\n * their application services' deploy platform.\n */\n\nimport { promises as fs } from 'node:fs'\nimport path from 'node:path'\nimport { spawn } from 'node:child_process'\nimport { randomBytes } from 'node:crypto'\n\nexport type Substrate = 'docker-compose' | 'systemd' | 'docker-run'\n\nexport interface DetectOptions {\n cwd?: string\n // Detection is shellable-out by injected probes; tests pass these to avoid\n // depending on the local docker / systemctl installation.\n hasDocker?: () => Promise<boolean>\n hasSystemd?: () => Promise<boolean>\n}\n\nexport interface DeployArtifact {\n substrate: Substrate\n // Path written to disk; undefined for the docker-run fallback (stdout-only).\n artifactPath?: string\n // The newly generated bearer token. Printed once by the caller, never\n // re-read from disk.\n token: string\n // The body of the artifact. Always returned so callers (and tests) can\n // inspect what was written without re-reading the file.\n contents: string\n // The shell command the operator runs to bring NEAT up on this substrate.\n startCommand: string\n}\n\nexport function generateToken(): string {\n // 32 bytes → 43-byte base64url (no padding). Plenty of entropy; URL-safe\n // so the operator can paste it into env-var dashboards that escape `=`.\n return randomBytes(32).toString('base64url')\n}\n\nasync function probeBinary(binary: string, arg: string): Promise<boolean> {\n return new Promise((resolve) => {\n const child = spawn(binary, [arg], { stdio: 'ignore' })\n const timer = setTimeout(() => {\n child.kill('SIGKILL')\n resolve(false)\n }, 2000)\n child.once('error', () => {\n clearTimeout(timer)\n resolve(false)\n })\n child.once('exit', (code) => {\n clearTimeout(timer)\n resolve(code === 0)\n })\n })\n}\n\nexport async function detectSubstrate(opts: DetectOptions = {}): Promise<Substrate> {\n const hasDocker = opts.hasDocker ?? (() => probeBinary('docker', 'version'))\n const hasSystemd = opts.hasSystemd ?? (() => probeBinary('systemctl', '--version'))\n if (await hasDocker()) return 'docker-compose'\n if (await hasSystemd()) return 'systemd'\n return 'docker-run'\n}\n\nconst IMAGE = 'ghcr.io/neat-technologies/neat:latest'\n\nexport function emitDockerCompose(cwd: string): string {\n // Compose v3 — declares the three documented ports + a data volume. The\n // operator's deploy platform supplies `NEAT_AUTH_TOKEN`; the file names\n // the var with no default, so a missing env stops the container from\n // coming up rather than running unauthenticated.\n return [\n 'services:',\n ' neat:',\n ` image: ${IMAGE}`,\n ' restart: unless-stopped',\n ' environment:',\n ' NEAT_AUTH_TOKEN: ${NEAT_AUTH_TOKEN:?NEAT_AUTH_TOKEN must be set}',\n ' ports:',\n ' - \"8080:8080\"',\n ' - \"4318:4318\"',\n ' - \"6328:6328\"',\n ' volumes:',\n ` - ${cwd}:/workspace`,\n ' - ./neat-data:/neat-out',\n '',\n ].join('\\n')\n}\n\nexport function emitSystemdUnit(cwd: string): string {\n // Token lives in /etc/neat/neatd.env (NEAT_AUTH_TOKEN=...) so it's readable\n // only by root and the service user. The unit itself stays version-\n // controllable without leaking the secret.\n return [\n '# NEAT_AUTH_TOKEN is read from /etc/neat/neatd.env at startup.',\n '# Put `NEAT_AUTH_TOKEN=<value>` in that file with mode 0640 root:root.',\n '[Unit]',\n 'Description=NEAT daemon',\n 'After=network-online.target',\n 'Wants=network-online.target',\n '',\n '[Service]',\n 'Type=simple',\n 'ExecStart=/usr/local/bin/neatd start --foreground',\n `WorkingDirectory=${cwd}`,\n 'EnvironmentFile=/etc/neat/neatd.env',\n 'Restart=always',\n 'RestartSec=5',\n '',\n '[Install]',\n 'WantedBy=multi-user.target',\n '',\n ].join('\\n')\n}\n\nexport function emitDockerRunSnippet(): string {\n // Single-line `docker run` for substrates we can't detect. Operator pastes\n // their own token in; the variable name keeps the bearer-token-must-be-set\n // shape consistent across all three branches.\n return [\n '#!/usr/bin/env bash',\n 'set -euo pipefail',\n '',\n '# Generate a fresh token once, then store it where your secrets live.',\n ': \"${NEAT_AUTH_TOKEN:?NEAT_AUTH_TOKEN must be set}\"',\n '',\n `docker run -d --name neat \\\\`,\n ' -e NEAT_AUTH_TOKEN=\"$NEAT_AUTH_TOKEN\" \\\\',\n ' -p 8080:8080 -p 4318:4318 -p 6328:6328 \\\\',\n ' -v \"$PWD\":/workspace -v /var/lib/neat:/neat-out \\\\',\n ` ${IMAGE}`,\n '',\n ].join('\\n')\n}\n\nexport interface RenderDeployBlockOptions {\n substrate: Substrate\n // Host the operator's services will reach NEAT at. Defaults to a\n // placeholder so the operator notices and fills it in.\n host?: string\n}\n\n// The OTel env-vars block the operator pastes into their deploy platform.\n// Format matches the orchestrator summary so the two never drift.\nexport function renderOtelEnvBlock(token: string, host: string = '<host>'): string {\n return [\n `OTEL_EXPORTER_OTLP_ENDPOINT=https://${host}:4318`,\n `OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer ${token}`,\n 'OTEL_SERVICE_NAME=<service>',\n ].join('\\n')\n}\n\nexport async function runDeploy(opts: DetectOptions = {}): Promise<DeployArtifact> {\n const cwd = opts.cwd ?? process.cwd()\n const substrate = await detectSubstrate(opts)\n const token = generateToken()\n\n switch (substrate) {\n case 'docker-compose': {\n const artifactPath = path.join(cwd, 'docker-compose.neat.yml')\n const contents = emitDockerCompose(cwd)\n await fs.writeFile(artifactPath, contents, 'utf8')\n return {\n substrate,\n artifactPath,\n token,\n contents,\n startCommand: `NEAT_AUTH_TOKEN=${token} docker compose -f ${path.basename(artifactPath)} up -d`,\n }\n }\n case 'systemd': {\n const artifactPath = path.join(cwd, 'neat.service')\n const contents = emitSystemdUnit(cwd)\n await fs.writeFile(artifactPath, contents, 'utf8')\n return {\n substrate,\n artifactPath,\n token,\n contents,\n startCommand: [\n `sudo install -m 0640 -o root -g root <(echo NEAT_AUTH_TOKEN=${token}) /etc/neat/neatd.env`,\n `sudo install -m 0644 neat.service /etc/systemd/system/neat.service`,\n 'sudo systemctl daemon-reload && sudo systemctl enable --now neat',\n ].join(' && '),\n }\n }\n case 'docker-run':\n default: {\n const contents = emitDockerRunSnippet()\n // No on-disk artifact for the fallback — operator copies the snippet.\n return {\n substrate: 'docker-run',\n token,\n contents,\n startCommand: `NEAT_AUTH_TOKEN=${token} bash <(cat <<'EOF'\\n${contents}EOF\\n)`,\n }\n }\n }\n}\n","/**\n * Node / TypeScript SDK installer (ADR-047 + ADR-069).\n *\n * Detects services by the presence of a `package.json` carrying a `name`\n * field — same shape `extract/services.ts` uses to decide what counts as a\n * Node service. The plan adds four OTel-adjacent packages to `dependencies`\n * (api, sdk-node, auto-instrumentations-node, dotenv), writes a generated\n * `otel-init.{js,ts}` adjacent to the resolved entry, and injects the\n * require/import as the first non-shebang line of that entry. Per-package\n * `.env.neat` carries `OTEL_SERVICE_NAME` (scope-preserved) so dashboards\n * joining OBSERVED spans against the EXTRACTED graph use the same key.\n *\n * Lockfiles are never touched (ADR-047 §4). The apply phase writes only to\n * package.json, otel-init.{js,ts}, and .env.neat (ADR-069 §7). After\n * `--apply`, init prints \"run npm install\" so the user owns the lockfile\n * commit.\n *\n * Idempotency (ADR-069 §6): the generated otel-init's presence is the\n * primary signal that a package is instrumented end-to-end — when it\n * exists, the apply phase logs `already instrumented` and skips the file\n * write and the entry-point injection together. Existing `.env.neat` files\n * are preserved (never overwritten).\n */\n\nimport { promises as fs } from 'node:fs'\nimport path from 'node:path'\nimport semver from 'semver'\nimport type {\n ApplyResult,\n DependencyEdit,\n EntrypointEdit,\n EnvEdit,\n GeneratedFile,\n Installer,\n InstallPlan,\n PlanOptions,\n} from './shared.js'\nimport {\n ASTRO_MIDDLEWARE_JS,\n ASTRO_MIDDLEWARE_TS,\n ASTRO_OTEL_INIT_JS,\n ASTRO_OTEL_INIT_TS,\n NEXT_INSTRUMENTATION_EDGE_JS,\n NEXT_INSTRUMENTATION_EDGE_TS,\n NEXT_INSTRUMENTATION_HEADER,\n NEXT_INSTRUMENTATION_JS,\n NEXT_INSTRUMENTATION_NODE_JS,\n NEXT_INSTRUMENTATION_NODE_TS,\n NEXT_INSTRUMENTATION_TS,\n NUXT_OTEL_INIT_JS,\n NUXT_OTEL_INIT_TS,\n NUXT_OTEL_PLUGIN_JS,\n NUXT_OTEL_PLUGIN_TS,\n OTEL_INIT_CJS,\n OTEL_INIT_ESM,\n OTEL_INIT_HEADER,\n OTEL_INIT_STAMP,\n OTEL_INIT_TS,\n REMIX_OTEL_SERVER_JS,\n REMIX_OTEL_SERVER_TS,\n SVELTEKIT_HOOKS_SERVER_JS,\n SVELTEKIT_HOOKS_SERVER_TS,\n SVELTEKIT_OTEL_INIT_JS,\n SVELTEKIT_OTEL_INIT_TS,\n renderEnvNeat,\n renderFrameworkOtelInit,\n renderNextInstrumentationNode,\n renderNodeOtelInit,\n} from './templates.js'\nimport { resolve as resolveRegistry } from '@neat.is/instrumentation-registry'\n\n// ADR-069 §5 — three OTel packages land in `dependencies`. `dotenv` was a\n// fourth from v0.3.6 through v0.4.3; the generated `otel-init` templates\n// no longer load `.env.neat` from disk (issue #369), so it's gone from the\n// dep set.\nconst SDK_PACKAGES = [\n { name: '@opentelemetry/api', version: '^1.9.0' },\n { name: '@opentelemetry/sdk-node', version: '^0.57.0' },\n { name: '@opentelemetry/auto-instrumentations-node', version: '^0.55.0' },\n] as const\n\n// ADR-126 — the Next.js edge-runtime file is the first named exception to\n// the four-deps invariant (framework-installers.md §6/§7): the standard Node\n// SDK can't execute inside Next's Edge runtime at all, so\n// instrumentation.edge.{ts,js} depends on `@vercel/otel` instead of the\n// shared SDK_PACKAGES set. Scoped to this one generated file's dependency\n// list — SDK_PACKAGES itself is untouched, and every other framework branch\n// keeps reading only SDK_PACKAGES.\nconst NEXT_EDGE_PACKAGES = [{ name: '@vercel/otel', version: '^2.1.3' }] as const\n\n// Issue #376 — non-bundled instrumentations. The auto-instrumentations-node\n// set covers HTTP, fetch, and the common DB drivers via the wire protocol,\n// but libraries that bypass those wires (Prisma's Rust query engine talks\n// to its own engine binary; LangChain wraps model calls in its own SDK)\n// need their own instrumentation package registered explicitly. The detected\n// entries here compose into the generated otel-init's `instrumentations`\n// array — one `instrumentations.push(...)` line per entry — and join the\n// package.json dep set so the registration line resolves at runtime.\n//\n// v0.4.5 scope is Prisma alone (first library that meaningfully widens\n// NEAT's OBSERVED coverage on real codebases). The function's interface is\n// stable so the v0.5.0 instrumentation registry (ADR-080) can return more\n// entries without revisiting the template.\ninterface NonBundledInstrumentation {\n pkg: string\n version: string\n registration: string\n}\n\n// Pull the leading integer out of a semver range. `^6.2.0`, `~6.2.0`, `6.x`,\n// `>=6.0.0 <7` all return 6. Anything we can't parse (workspace:*, file:…,\n// undefined) returns 0 so the caller falls through to the pre-Prisma-6 path.\nexport function getMajor(versionRange: string | undefined): number {\n if (!versionRange) return 0\n const match = versionRange.match(/(\\d+)/)\n return match ? parseInt(match[1], 10) : 0\n}\n\nexport function detectNonBundledInstrumentations(\n pkg: PackageJsonShape,\n): NonBundledInstrumentation[] {\n const deps = allDeps(pkg)\n const out: NonBundledInstrumentation[] = []\n if ('@prisma/client' in deps) {\n // Issue #381 — `@prisma/instrumentation@^5` doesn't speak Prisma 6's\n // tracing-helper API. Connecting the client throws\n // `this.getGlobalTracingHelper(...).dispatchEngineSpans is not a function`\n // before any user query lands. Mirror the Prisma major so the\n // instrumentation package matches the client surface.\n const prismaMajor = getMajor(deps['@prisma/client'])\n const prismaInstrVersion = prismaMajor >= 6 ? '^6.0.0' : '^5.0.0'\n out.push({\n pkg: '@prisma/instrumentation',\n version: prismaInstrVersion,\n registration:\n \"instrumentations.push(new (require('@prisma/instrumentation').PrismaInstrumentation)())\",\n })\n }\n return out\n}\n\nconst OTEL_ENV: EnvEdit = {\n // ADR-069 §4 — endpoint moves into the per-package .env.neat (written\n // by the apply phase). The envEdits surface stays for the dry-run\n // patch render: it documents the key/value the user can inspect in the\n // generated .env.neat.\n file: null,\n key: 'OTEL_EXPORTER_OTLP_TRACES_ENDPOINT',\n value: 'http://localhost:4318/projects/<project>/v1/traces',\n}\n\ninterface PackageJsonShape {\n name?: string\n type?: string\n main?: string\n bin?: string | Record<string, string>\n scripts?: Record<string, string>\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n}\n\n// v0.4.4 — `OTEL_SERVICE_NAME` regains its proper semantic role: the\n// ServiceNode id inside the project's graph, not the project name. v0.4.1\n// papered over the missing routing key by writing the project basename here;\n// the project-scoped OTLP URL (issue #367) means the URL carries the routing\n// key and the env var goes back to naming the ServiceNode.\nfunction serviceNodeName(pkg: PackageJsonShape, serviceDir: string): string {\n return pkg.name ?? path.basename(serviceDir)\n}\n\n// The URL routing key. When the orchestrator threads a project through we use\n// it verbatim; ad-hoc / test usage falls back to the package's own name so\n// the generated file is still well-formed.\nfunction projectToken(\n pkg: PackageJsonShape,\n serviceDir: string,\n project: string | undefined,\n): string {\n if (project && project.length > 0) return project\n return pkg.name ?? path.basename(serviceDir)\n}\n\n// Issue #370 — runtime-kind detection. The installer historically treated\n// every JavaScript package as a Node service; Brief's frontend workspace\n// showed that wrong assumption write `instrumentation-node/register` into a\n// Vite browser bundle and an Expo React Native entry, where the Node SDK\n// can't execute. Detection runs after framework dispatch (Next / Remix /\n// SvelteKit / Nuxt / Astro all render server-side, so they classify as\n// `node`); only the framework-less packages reach the bucket here.\ntype RuntimeKind = 'node' | 'browser-bundle' | 'react-native' | 'bun' | 'deno' | 'cloudflare-workers' | 'electron'\n\nasync function readJsonFile(p: string): Promise<unknown> {\n try {\n const raw = await fs.readFile(p, 'utf8')\n return JSON.parse(raw) as unknown\n } catch {\n return null\n }\n}\n\nasync function detectRuntimeKind(\n pkgRoot: string,\n pkg: PackageJsonShape,\n): Promise<RuntimeKind> {\n const deps = allDeps(pkg)\n if ('react-native' in deps || 'expo' in deps) return 'react-native'\n // Expo apps sometimes carry the SDK only as a transitive dep but always\n // ship an `app.json` carrying an `expo` block — that's the canonical Expo\n // signal.\n const appJson = await readJsonFile(path.join(pkgRoot, 'app.json'))\n if (appJson && typeof appJson === 'object' && 'expo' in (appJson as Record<string, unknown>)) {\n return 'react-native'\n }\n if (\n (await exists(path.join(pkgRoot, 'vite.config.js'))) ||\n (await exists(path.join(pkgRoot, 'vite.config.ts'))) ||\n (await exists(path.join(pkgRoot, 'vite.config.mjs'))) ||\n 'vite' in deps\n ) {\n return 'browser-bundle'\n }\n // Issues #389 #390 — out-of-scope runtime detection for BYO-OTel escape hatch.\n // Order: wrangler.toml first (Workers projects may also carry package.json),\n // then bun.lockb (Bun projects often have package.json too), then Deno signals.\n if (await exists(path.join(pkgRoot, 'wrangler.toml'))) return 'cloudflare-workers'\n if (await exists(path.join(pkgRoot, 'bun.lockb'))) return 'bun'\n if (\n (await exists(path.join(pkgRoot, 'deno.json'))) ||\n (await exists(path.join(pkgRoot, 'deno.lock')))\n ) {\n return 'deno'\n }\n const engines = (pkg as { engines?: Record<string, unknown> }).engines ?? {}\n if ('electron' in engines) return 'electron'\n return 'node'\n}\n\n// Issue #368 — `OTel deps in package.json` is no longer the signal for\n// `already-instrumented`. The hook file is. Each `plan<Framework>` reads its\n// canonical hook path off disk via `await exists(...)` before queueing the\n// generated-file write, so deps-present-but-hook-absent correctly buckets\n// the package as `instrumented` (the installer writes the hook), not\n// `already-instrumented`. The next-deps-no-hook fixture in the contract\n// suite locks this against regression.\n\nasync function readPackageJson(serviceDir: string): Promise<PackageJsonShape | null> {\n try {\n const raw = await fs.readFile(path.join(serviceDir, 'package.json'), 'utf8')\n return JSON.parse(raw) as PackageJsonShape\n } catch {\n return null\n }\n}\n\nasync function exists(p: string): Promise<boolean> {\n try {\n await fs.stat(p)\n return true\n } catch {\n return false\n }\n}\n\n// Read a file's contents, or null when it doesn't exist. Used by the\n// otel-init migration check (file-awareness.md §4) so a single read decides\n// between write / migrate / preserve.\nasync function readFileMaybe(p: string): Promise<string | null> {\n try {\n return await fs.readFile(p, 'utf8')\n } catch {\n return null\n }\n}\n\n// Decide what to do with the generated otel-init at `file`, given its rendered\n// current contents. A missing file is written (skipIfExists honours a race\n// where it appears between plan and apply). A NEAT-owned file (carries\n// OTEL_INIT_HEADER) on an older template — no current stamp — is regenerated so\n// a re-run upgrades the install. A current-stamp NEAT file is already current,\n// and a hand-written init (no header) is never touched.\nasync function planOtelInitGeneration(\n file: string,\n contents: string,\n): Promise<GeneratedFile | null> {\n const existing = await readFileMaybe(file)\n if (existing === null) {\n return { file, contents, skipIfExists: true }\n }\n if (existing.includes(OTEL_INIT_HEADER) && !existing.includes(OTEL_INIT_STAMP)) {\n return { file, contents, skipIfExists: false }\n }\n return null\n}\n\nasync function detect(serviceDir: string): Promise<boolean> {\n const pkg = await readPackageJson(serviceDir)\n return pkg !== null && typeof pkg.name === 'string'\n}\n\n// Returns true when the currently-installed range and the registry-resolved\n// expected range have no intersection — meaning the installed version is\n// incompatible and an upgrade edit should be emitted.\nfunction needsVersionUpgrade(installed: string, expected: string): boolean {\n return (\n !semver.satisfies(\n semver.minVersion(installed)?.version ?? installed,\n expected,\n ) && !semver.intersects(installed, expected)\n )\n}\n\n// ADR-073 §1 — Next.js detection. A package is Next-flavored when it\n// declares `next` as a (dev)dependency AND ships a `next.config.{js,ts,mjs}`\n// at the package root. Both are required: a stray `next` import without the\n// config file isn't a Next app, and a config file without the dep is dead\n// configuration.\nconst NEXT_CONFIG_CANDIDATES = ['next.config.js', 'next.config.ts', 'next.config.mjs']\n\nasync function findNextConfig(serviceDir: string): Promise<string | null> {\n for (const name of NEXT_CONFIG_CANDIDATES) {\n const candidate = path.join(serviceDir, name)\n if (await exists(candidate)) return candidate\n }\n return null\n}\n\nfunction hasNextDependency(pkg: PackageJsonShape): boolean {\n return (\n (pkg.dependencies?.next !== undefined) ||\n (pkg.devDependencies?.next !== undefined)\n )\n}\n\n// Read the merged dep + devDep map once per detection step. Framework checks\n// only care about presence, not version.\nfunction allDeps(pkg: PackageJsonShape): Record<string, string> {\n return { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) }\n}\n\n// Issue #545 — web-framework signals. When a package depends on one of these\n// but the installer couldn't resolve an entry point, it's almost certainly a\n// runnable app whose runtime layer is about to silently fail to engage rather\n// than a true library. The orchestrator uses this to turn a quiet `lib-only N`\n// tally into a loud, actionable line. Presence is enough — version doesn't\n// matter for the warning.\nconst WEB_FRAMEWORK_DEPS = [\n 'express',\n 'fastify',\n 'koa',\n '@hapi/hapi',\n 'hapi',\n 'restify',\n 'connect',\n '@nestjs/core',\n 'next',\n 'hono',\n 'elysia',\n 'polka',\n 'micro',\n] as const\n\n// Issue #570 — background-worker / queue-consumer signals. A package that\n// pulls jobs off a queue or consumes a message bus is a runnable process, not\n// a pure library: a lib-only classification on one of these is a missed entry\n// just like a web framework, so it earns the same loud warning instead of a\n// silent `lib-only N`. These sit alongside WEB_FRAMEWORK_DEPS rather than in\n// the registry because they're an app-shape heuristic, not instrumentation\n// coverage — the registry stays the single source of truth for what is/isn't\n// observed (uninstrumentedLibraries below), and these only answer \"is this a\n// runnable app whose entry we failed to find?\".\nconst WORKER_FRAMEWORK_DEPS = [\n 'bullmq',\n 'bull',\n 'bee-queue',\n 'agenda',\n 'kafkajs',\n 'amqplib',\n 'amqp-connection-manager',\n 'nats',\n 'node-resque',\n 'pg-boss',\n 'graphile-worker',\n] as const\n\n// Every dependency family that marks a package as a runnable application\n// (inbound web framework or background worker) rather than a library.\nconst APP_FRAMEWORK_DEPS = [...WEB_FRAMEWORK_DEPS, ...WORKER_FRAMEWORK_DEPS] as const\n\n// The application-framework dependencies a package declares — the names the\n// orchestrator puts in its warning so a lib-only-but-app-shaped package gets a\n// specific recovery line (\"depends on bullmq but neat couldn't resolve an\n// entry\") instead of a silent tally bump.\nexport function appFrameworkDependencies(pkg: PackageJsonShape): string[] {\n const deps = allDeps(pkg)\n return APP_FRAMEWORK_DEPS.filter((name) => name in deps)\n}\n\n// Issue #546 — libraries whose calls aren't observed by the default\n// auto-instrumentation set. Resolved through the instrumentation registry (the\n// single source of truth, contract §3) rather than a hardcoded list: a\n// dependency whose registry coverage is `gap` produces no OBSERVED edges out of\n// the box. `sqlite3` / `better-sqlite3` are the motivating cases — in-process\n// drivers that never cross an instrumented wire. Returns the library names so\n// the orchestrator can name them in its guidance line.\nexport function uninstrumentedLibraries(pkg: PackageJsonShape): string[] {\n const deps = allDeps(pkg)\n const out: string[] = []\n for (const [name, version] of Object.entries(deps)) {\n const entry = resolveRegistry(name, version)\n if (entry && entry.coverage === 'gap') out.push(name)\n }\n return out\n}\n\n// ADR-074 §3 — Remix detection. A package is Remix-flavored when it declares\n// `remix` or any `@remix-run/*` package AND ships an entry-server file at one\n// of the canonical paths (`app/entry.server.{ts,tsx,js,jsx}`).\nconst REMIX_ENTRY_CANDIDATES = [\n 'app/entry.server.ts',\n 'app/entry.server.tsx',\n 'app/entry.server.js',\n 'app/entry.server.jsx',\n]\n\nfunction hasRemixDependency(pkg: PackageJsonShape): boolean {\n const deps = allDeps(pkg)\n if ('remix' in deps) return true\n for (const name of Object.keys(deps)) {\n if (name.startsWith('@remix-run/')) return true\n }\n return false\n}\n\nasync function findRemixEntry(serviceDir: string): Promise<string | null> {\n for (const rel of REMIX_ENTRY_CANDIDATES) {\n const candidate = path.join(serviceDir, rel)\n if (await exists(candidate)) return candidate\n }\n return null\n}\n\n// ADR-074 §3 — SvelteKit detection. `@sveltejs/kit` dep, plus either an\n// existing `src/hooks.server.{ts,js}` or a top-level `svelte.config.{js,ts}`\n// (the absent-hooks case where the installer creates the hook file).\nconst SVELTEKIT_HOOKS_CANDIDATES = ['src/hooks.server.ts', 'src/hooks.server.js']\nconst SVELTEKIT_CONFIG_CANDIDATES = ['svelte.config.js', 'svelte.config.ts']\n\nfunction hasSvelteKitDependency(pkg: PackageJsonShape): boolean {\n return '@sveltejs/kit' in allDeps(pkg)\n}\n\nasync function findSvelteKitHooks(serviceDir: string): Promise<string | null> {\n for (const rel of SVELTEKIT_HOOKS_CANDIDATES) {\n const candidate = path.join(serviceDir, rel)\n if (await exists(candidate)) return candidate\n }\n return null\n}\n\nasync function findSvelteKitConfig(serviceDir: string): Promise<string | null> {\n for (const rel of SVELTEKIT_CONFIG_CANDIDATES) {\n const candidate = path.join(serviceDir, rel)\n if (await exists(candidate)) return candidate\n }\n return null\n}\n\n// ADR-074 §3 — Nuxt detection. `nuxt` dep + `nuxt.config.{ts,js,mjs}`.\nconst NUXT_CONFIG_CANDIDATES = ['nuxt.config.ts', 'nuxt.config.js', 'nuxt.config.mjs']\n\nfunction hasNuxtDependency(pkg: PackageJsonShape): boolean {\n return 'nuxt' in allDeps(pkg)\n}\n\nasync function findNuxtConfig(serviceDir: string): Promise<string | null> {\n for (const name of NUXT_CONFIG_CANDIDATES) {\n const candidate = path.join(serviceDir, name)\n if (await exists(candidate)) return candidate\n }\n return null\n}\n\n// ADR-074 §3 — Astro detection. `astro` dep + `astro.config.{mjs,ts,js}`.\nconst ASTRO_CONFIG_CANDIDATES = ['astro.config.mjs', 'astro.config.ts', 'astro.config.js']\n\nfunction hasAstroDependency(pkg: PackageJsonShape): boolean {\n return 'astro' in allDeps(pkg)\n}\n\nasync function findAstroConfig(serviceDir: string): Promise<string | null> {\n for (const name of ASTRO_CONFIG_CANDIDATES) {\n const candidate = path.join(serviceDir, name)\n if (await exists(candidate)) return candidate\n }\n return null\n}\n\n// Parse the leading major version out of a semver range like \"^14.0.3\" or\n// \"~15.0\" or \"15.0.0\". Returns null when the range can't be read (workspace\n// links, git refs, \"*\", etc.).\nexport function parseNextMajor(range: string | undefined): number | null {\n if (!range) return null\n const cleaned = range.trim().replace(/^[\\^~>=<\\s]+/, '')\n const match = cleaned.match(/^(\\d+)/)\n if (!match) return null\n const n = Number(match[1])\n return Number.isFinite(n) ? n : null\n}\n\nasync function isTypeScriptProject(serviceDir: string): Promise<boolean> {\n return exists(path.join(serviceDir, 'tsconfig.json'))\n}\n\n// ADR-069 §2 + ADR-070 + issue #545 #570 — entry resolution: pkg.main →\n// pkg.bin → scripts.start → scripts.dev → src/index.* →\n// src/{server,main,app,worker}.* → root {server,app,main,worker}.* →\n// root index.*. `pkg.main` is only accepted when\n// the file it names actually exists; a stale `main` (e.g. `dist/index.js` that\n// hasn't been built, or a leftover that was deleted) falls through to the rest\n// of the chain rather than marking the package lib-only. Returns the absolute\n// path to the resolved entry, or null when the package is lib-only (no\n// resolvable entry).\nconst INDEX_EXTENSIONS = ['.ts', '.tsx', '.js', '.mjs', '.cjs']\nconst INDEX_CANDIDATES = INDEX_EXTENSIONS.map((ext) => `index${ext}`)\nconst SRC_INDEX_CANDIDATES = INDEX_EXTENSIONS.map((ext) => `src/index${ext}`)\n// `worker` joins the named set (issue #570) — a background-queue worker\n// (bullmq, kafkajs, …) is a runnable process whose entry conventionally lives\n// in `worker.{js,ts}`, never under `index`. Without it the worker fell to\n// lib-only and its runtime layer silently never engaged.\nconst SRC_NAMED_CANDIDATES = ['server', 'main', 'app', 'worker'].flatMap((name) =>\n INDEX_EXTENSIONS.map((ext) => `src/${name}${ext}`),\n)\n// Issue #545 / #570 — a runnable app commonly keeps its entry at the repo root\n// under a conventional name (`server.js`, `app.js`, `main.js`, or `worker.js`\n// for a queue consumer) with no `scripts.start` and a `pkg.main` that points at\n// a build output that doesn't exist yet. Those shapes resolved to lib-only\n// before — the runtime layer never engaged. Root named candidates sit just\n// before the `index.*` root fallback so they're the last resort after the\n// manifest/script/src signals, but still keep the app from silently dropping\n// out of instrumentation.\nconst ROOT_NAMED_CANDIDATES = ['server', 'app', 'main', 'worker'].flatMap((name) =>\n INDEX_EXTENSIONS.map((ext) => `${name}${ext}`),\n)\n\n// ADR-070 — script-entry tokeniser. Launchers and similar wrappers we strip\n// before reading the first file-shaped argument. Anything not in this set is\n// treated as a candidate entry if it looks like a relative file path.\nconst SCRIPT_LAUNCHERS = new Set([\n 'node',\n 'ts-node',\n 'tsx',\n 'ts-node-dev',\n 'nodemon',\n 'npx',\n 'pnpm',\n 'yarn',\n 'npm',\n 'cross-env',\n 'dotenv',\n '--',\n])\n\n// True when the token resembles a path inside the package — contains a `/` or\n// ends in one of the JS/TS extensions we instrument.\nfunction looksLikeEntryPath(token: string): boolean {\n if (token.length === 0) return false\n if (token.startsWith('-')) return false\n if (token.includes('=')) return false // env-var assignments\n if (token.includes('/')) return true\n return /\\.(?:m?[jt]sx?|c[jt]s)$/.test(token)\n}\n\n// Bail when the script chains commands or pipes — those scripts mean an\n// orchestrator runs multiple things and our heuristic can't pick safely.\nfunction scriptHasShellChain(script: string): boolean {\n return /(?:&&|\\|\\||;|\\|(?!\\|))/.test(script)\n}\n\n// Pull the first file-shaped argument out of a script invocation, after\n// stripping recognised launchers and inline env-var assignments. Returns\n// undefined when no candidate surfaces (or when shell chaining bails us out).\nexport function entryFromScript(script: string | undefined): string | undefined {\n if (!script) return undefined\n if (scriptHasShellChain(script)) return undefined\n const tokens = script.split(/\\s+/).filter((t) => t.length > 0)\n for (const token of tokens) {\n const lower = token.toLowerCase()\n if (SCRIPT_LAUNCHERS.has(lower)) continue\n // Strip a leading `./` so the existence check resolves cleanly.\n const cleaned = token.startsWith('./') ? token.slice(2) : token\n if (looksLikeEntryPath(cleaned)) return cleaned\n }\n return undefined\n}\n\nexport async function resolveEntry(\n serviceDir: string,\n pkg: PackageJsonShape,\n): Promise<string | null> {\n // 1) pkg.main — but only when it actually exists on disk (ADR-070).\n if (typeof pkg.main === 'string' && pkg.main.length > 0) {\n const candidate = path.resolve(serviceDir, pkg.main)\n if (await exists(candidate)) return candidate\n // Manifest points main at a missing build output (e.g. dist/index.js\n // pre-build). Fall through to bin/scripts/src heuristics rather than\n // marking lib-only.\n }\n // 2) pkg.bin (string or pkg.name-keyed map).\n if (pkg.bin) {\n let binEntry: string | undefined\n if (typeof pkg.bin === 'string') {\n binEntry = pkg.bin\n } else if (pkg.name && typeof pkg.bin[pkg.name] === 'string') {\n binEntry = pkg.bin[pkg.name]\n } else {\n const first = Object.values(pkg.bin)[0]\n if (typeof first === 'string') binEntry = first\n }\n if (binEntry) {\n const candidate = path.resolve(serviceDir, binEntry)\n if (await exists(candidate)) return candidate\n }\n }\n // 3) scripts.start — ADR-070.\n const startEntry = entryFromScript(pkg.scripts?.start)\n if (startEntry) {\n const candidate = path.resolve(serviceDir, startEntry)\n if (await exists(candidate)) return candidate\n }\n // 4) scripts.dev — ADR-070.\n const devEntry = entryFromScript(pkg.scripts?.dev)\n if (devEntry) {\n const candidate = path.resolve(serviceDir, devEntry)\n if (await exists(candidate)) return candidate\n }\n // 5) src/index.* — ADR-070.\n for (const rel of SRC_INDEX_CANDIDATES) {\n const candidate = path.join(serviceDir, rel)\n if (await exists(candidate)) return candidate\n }\n // 6) src/server.*, src/main.*, src/app.*, src/worker.* — ADR-070 + #570.\n for (const rel of SRC_NAMED_CANDIDATES) {\n const candidate = path.join(serviceDir, rel)\n if (await exists(candidate)) return candidate\n }\n // 7) root server.*, app.*, main.*, worker.* — issue #545 / #570. Common for\n // a runnable app or queue worker whose entry sits at the repo root.\n for (const rel of ROOT_NAMED_CANDIDATES) {\n const candidate = path.join(serviceDir, rel)\n if (await exists(candidate)) return candidate\n }\n // 8) root index.* — original ADR-069 §3 fallback.\n for (const name of INDEX_CANDIDATES) {\n const candidate = path.join(serviceDir, name)\n if (await exists(candidate)) return candidate\n }\n return null\n}\n\n// ADR-069 §1, §3 — dispatch by entry extension + pkg.type.\ntype EntryFlavor = 'cjs' | 'esm' | 'ts'\n\nexport function dispatchEntry(entryFile: string, pkg: PackageJsonShape): EntryFlavor {\n const ext = path.extname(entryFile).toLowerCase()\n if (ext === '.ts' || ext === '.tsx') return 'ts'\n if (ext === '.mjs') return 'esm'\n if (ext === '.cjs') return 'cjs'\n // .js — disambiguate on pkg.type. \"module\" → ESM, anything else → CJS.\n return pkg.type === 'module' ? 'esm' : 'cjs'\n}\n\n// Generated-file basename per flavor.\nfunction otelInitFilename(flavor: EntryFlavor): string {\n if (flavor === 'ts') return 'otel-init.ts'\n if (flavor === 'esm') return 'otel-init.mjs'\n return 'otel-init.cjs'\n}\n\nfunction otelInitContents(flavor: EntryFlavor): string {\n if (flavor === 'ts') return OTEL_INIT_TS\n if (flavor === 'esm') return OTEL_INIT_ESM\n return OTEL_INIT_CJS\n}\n\n// Build the injection line per flavor. The relative path is computed against\n// the entry's directory so the injection works regardless of the entry's\n// depth inside the package.\nexport function injectionLine(\n flavor: EntryFlavor,\n entryFile: string,\n otelInitFile: string,\n): string {\n let rel = path.relative(path.dirname(entryFile), otelInitFile)\n if (!rel.startsWith('.')) rel = `./${rel}`\n // Normalize to forward slashes for cross-platform module specifiers.\n rel = rel.split(path.sep).join('/')\n if (flavor === 'cjs') return `require('${rel}')`\n if (flavor === 'esm') return `import '${rel}'`\n // TS: drop the .ts extension so the resolver doesn't choke on it under\n // either tsc-output or runtime-loader pipelines.\n const tsRel = rel.replace(/\\.ts$/, '')\n return `import '${tsRel}'`\n}\n\n// Detect whether a given line already matches an injection of our otel-init.\n// Used for the entry-point idempotency check (ADR-069 §6).\nfunction lineIsOtelInjection(line: string): boolean {\n const trimmed = line.trim()\n if (trimmed.length === 0) return false\n // Match require('./otel-init…') and import './otel-init…' shapes.\n return /(?:require\\(|import\\s+)['\"]\\.\\/otel-init[^'\"]*['\"]/.test(trimmed)\n}\n\n// `create-next-app --src-dir` puts source under `src/` and Next then resolves\n// the instrumentation hook from `src/instrumentation.ts`. Routing the\n// generated files to root in that case means the hook never loads. We detect\n// src-layout by the presence of `src/app/` or `src/pages/` AND the absence of\n// the same at the package root — a project with both is treated as flat, the\n// safer default for monorepos that vendor a `src/` subpackage.\nasync function detectsSrcLayout(serviceDir: string): Promise<boolean> {\n const [hasSrcApp, hasSrcPages, hasRootApp, hasRootPages] = await Promise.all([\n exists(path.join(serviceDir, 'src', 'app')),\n exists(path.join(serviceDir, 'src', 'pages')),\n exists(path.join(serviceDir, 'app')),\n exists(path.join(serviceDir, 'pages')),\n ])\n return (hasSrcApp || hasSrcPages) && !hasRootApp && !hasRootPages\n}\n\n// ADR-073 §1 / ADR-126 — Next.js apply path. Emits `instrumentation.{ts,js}`,\n// `instrumentation.node.{ts,js}`, and `instrumentation.edge.{ts,js}` at the\n// package root (or under `src/` for `--src-dir` layouts), plus `.env.neat`\n// co-located with them. Skips entry-point injection entirely — Next loads\n// the instrumentation file through its own runtime hook. Queues a\n// next.config edit only when the declared major is < 15 (the flag is\n// on-by-default from Next 15 on).\nasync function planNext(\n serviceDir: string,\n pkg: PackageJsonShape,\n manifestPath: string,\n nextConfigPath: string,\n project: string | undefined,\n): Promise<InstallPlan> {\n const useTs = await isTypeScriptProject(serviceDir)\n const srcLayout = await detectsSrcLayout(serviceDir)\n // Co-locate the generated files with where Next looks for the hook. When\n // src-layout is detected the framework resolves `src/instrumentation.{ts,js}`\n // and we route the .env.neat alongside so an operator reading the codebase\n // finds the wiring in one place. The flat layout keeps the existing root\n // placement.\n const baseDir = srcLayout ? path.join(serviceDir, 'src') : serviceDir\n const instrumentationFile = path.join(baseDir, useTs ? 'instrumentation.ts' : 'instrumentation.js')\n const instrumentationNodeFile = path.join(\n baseDir,\n useTs ? 'instrumentation.node.ts' : 'instrumentation.node.js',\n )\n const instrumentationEdgeFile = path.join(\n baseDir,\n useTs ? 'instrumentation.edge.ts' : 'instrumentation.edge.js',\n )\n const envNeatFile = path.join(baseDir, '.env.neat')\n\n // Dependency edits — `dotenv` is gone repo-wide from v0.4.4 (issue #369),\n // so SDK_PACKAGES has the three OTel packages the apply phase adds and the\n // Next branch shares the same loop as every other framework. Issue #376\n // adds non-bundled instrumentations (Prisma in v0.4.5) — each detected\n // entry contributes one dep + one registration line into the generated\n // instrumentation.node file.\n const existingDeps = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) }\n const dependencyEdits: DependencyEdit[] = []\n for (const sdk of SDK_PACKAGES) {\n if (sdk.name in existingDeps) {\n if (needsVersionUpgrade(existingDeps[sdk.name]!, sdk.version)) {\n dependencyEdits.push({ file: manifestPath, kind: 'upgrade', name: sdk.name, version: sdk.version, fromVersion: existingDeps[sdk.name]! })\n }\n continue\n }\n dependencyEdits.push({ file: manifestPath, kind: 'add', name: sdk.name, version: sdk.version })\n }\n // ADR-126 — `@vercel/otel` lands only for the edge file's sake, read from\n // NEXT_EDGE_PACKAGES rather than SDK_PACKAGES. Same existing-deps / upgrade\n // check as the loop above so a project that already depends on\n // `@vercel/otel` (e.g. it already had ambient Vercel tracing) doesn't get a\n // redundant or downgrading edit.\n for (const sdk of NEXT_EDGE_PACKAGES) {\n if (sdk.name in existingDeps) {\n if (needsVersionUpgrade(existingDeps[sdk.name]!, sdk.version)) {\n dependencyEdits.push({ file: manifestPath, kind: 'upgrade', name: sdk.name, version: sdk.version, fromVersion: existingDeps[sdk.name]! })\n }\n continue\n }\n dependencyEdits.push({ file: manifestPath, kind: 'add', name: sdk.name, version: sdk.version })\n }\n const nonBundled = detectNonBundledInstrumentations(pkg)\n for (const inst of nonBundled) {\n if (inst.pkg in existingDeps) {\n if (needsVersionUpgrade(existingDeps[inst.pkg]!, inst.version)) {\n dependencyEdits.push({ file: manifestPath, kind: 'upgrade', name: inst.pkg, version: inst.version, fromVersion: existingDeps[inst.pkg]! })\n }\n continue\n }\n dependencyEdits.push({ file: manifestPath, kind: 'add', name: inst.pkg, version: inst.version })\n }\n\n // Generated files — instrumentation pair + .env.neat. Existing files are\n // preserved (skipIfExists honours user customisations and keeps the apply\n // phase idempotent per ADR-069 §6). The instrumentation.node template\n // carries `__SERVICE_NAME__` (the ServiceNode id) and `__PROJECT__` (the\n // registered project basename — the URL routing key) placeholders we\n // substitute here so the bundler-survivable `process.env.X ||=` lines land\n // with both values verbatim.\n const svcName = serviceNodeName(pkg, serviceDir)\n const projectName = projectToken(pkg, serviceDir, project)\n const registrations = nonBundled.map((i) => i.registration)\n const generatedFiles: GeneratedFile[] = []\n if (!(await exists(instrumentationFile))) {\n generatedFiles.push({\n file: instrumentationFile,\n contents: useTs ? NEXT_INSTRUMENTATION_TS : NEXT_INSTRUMENTATION_JS,\n skipIfExists: true,\n })\n }\n if (!(await exists(instrumentationNodeFile))) {\n generatedFiles.push({\n file: instrumentationNodeFile,\n contents: renderNextInstrumentationNode(\n useTs ? NEXT_INSTRUMENTATION_NODE_TS : NEXT_INSTRUMENTATION_NODE_JS,\n svcName,\n projectName,\n registrations,\n ),\n skipIfExists: true,\n })\n }\n // ADR-126 — the edge-runtime file. Same substitution style as the Node\n // file (renderFrameworkOtelInit does the same __SERVICE_NAME__/__PROJECT__\n // regex replace renderNextInstrumentationNode does), same skipIfExists\n // idempotency so a re-run never clobbers a hand-edited registerOTel() call.\n if (!(await exists(instrumentationEdgeFile))) {\n generatedFiles.push({\n file: instrumentationEdgeFile,\n contents: renderFrameworkOtelInit(\n useTs ? NEXT_INSTRUMENTATION_EDGE_TS : NEXT_INSTRUMENTATION_EDGE_JS,\n svcName,\n projectName,\n ),\n skipIfExists: true,\n })\n }\n if (!(await exists(envNeatFile))) {\n generatedFiles.push({\n file: envNeatFile,\n contents: renderEnvNeat(svcName, projectName),\n skipIfExists: true,\n })\n }\n\n // ADR-073 §1 — `experimental.instrumentationHook: true` is required for\n // Next 13 / 14 and a no-op on Next 15+. Plan the edit only when the\n // declared major is < 15 and the flag isn't already present.\n let nextConfigEdit: InstallPlan['nextConfigEdit']\n const nextRange = pkg.dependencies?.next ?? pkg.devDependencies?.next\n const nextMajor = parseNextMajor(nextRange)\n if (nextMajor !== null && nextMajor < 15) {\n try {\n const raw = await fs.readFile(nextConfigPath, 'utf8')\n if (!raw.includes('instrumentationHook')) {\n nextConfigEdit = {\n file: nextConfigPath,\n reason: `enable experimental.instrumentationHook (Next ${nextMajor} requires the opt-in flag)`,\n }\n }\n } catch {\n // Config disappeared between detect and plan. Skip the edit.\n }\n }\n\n const empty =\n dependencyEdits.length === 0 &&\n generatedFiles.length === 0 &&\n nextConfigEdit === undefined\n\n if (empty) {\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits: [],\n entrypointEdits: [],\n envEdits: [],\n generatedFiles: [],\n framework: 'next',\n }\n }\n\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits,\n entrypointEdits: [],\n envEdits: [OTEL_ENV],\n generatedFiles,\n framework: 'next',\n ...(nextConfigEdit ? { nextConfigEdit } : {}),\n }\n}\n\n// ── Meta-framework planners (ADR-074 §3). ───────────────────────────────\n//\n// Each planner mirrors planNext's shape: build dep edits via the same\n// SDK_PACKAGES + existing-deps filter, queue generated files for the\n// framework-canonical hook surface, record `framework: '<name>'`, never\n// inject into pkg.main. Idempotency rides on `skipIfExists` for generated\n// files and on a re-read header-grep for the inject-into-existing case.\n\nfunction buildDependencyEdits(\n pkg: PackageJsonShape,\n manifestPath: string,\n): DependencyEdit[] {\n const existingDeps = allDeps(pkg)\n const edits: DependencyEdit[] = []\n for (const sdk of SDK_PACKAGES) {\n if (sdk.name in existingDeps) continue\n edits.push({\n file: manifestPath,\n kind: 'add',\n name: sdk.name,\n version: sdk.version,\n })\n }\n return edits\n}\n\nasync function queueEnvNeat(\n serviceDir: string,\n pkg: PackageJsonShape,\n project: string | undefined,\n generatedFiles: GeneratedFile[],\n): Promise<void> {\n const envNeatFile = path.join(serviceDir, '.env.neat')\n if (!(await exists(envNeatFile))) {\n generatedFiles.push({\n file: envNeatFile,\n contents: renderEnvNeat(\n serviceNodeName(pkg, serviceDir),\n projectToken(pkg, serviceDir, project),\n ),\n skipIfExists: true,\n })\n }\n}\n\nfunction renderFrameworkOtelInitForPkg(\n template: string,\n pkg: PackageJsonShape,\n serviceDir: string,\n project: string | undefined,\n): string {\n return renderFrameworkOtelInit(\n template,\n serviceNodeName(pkg, serviceDir),\n projectToken(pkg, serviceDir, project),\n )\n}\n\nfunction fileImportsOtelHook(raw: string, specifiers: readonly string[]): boolean {\n const lines = raw.split(/\\r?\\n/)\n for (const line of lines) {\n const trimmed = line.trim()\n for (const spec of specifiers) {\n const escaped = spec.replace(/\\./g, '\\\\.')\n const pattern = new RegExp(\n `(?:import\\\\s+['\"]${escaped}['\"]|require\\\\(['\"]${escaped}['\"]\\\\))`,\n )\n if (pattern.test(trimmed)) return true\n }\n }\n return false\n}\n\nasync function planRemix(\n serviceDir: string,\n pkg: PackageJsonShape,\n manifestPath: string,\n entryFile: string,\n project: string | undefined,\n): Promise<InstallPlan> {\n const useTs = await isTypeScriptProject(serviceDir)\n const otelServerFile = path.join(\n serviceDir,\n useTs ? 'app/otel.server.ts' : 'app/otel.server.js',\n )\n\n const dependencyEdits = buildDependencyEdits(pkg, manifestPath)\n const generatedFiles: GeneratedFile[] = []\n\n if (!(await exists(otelServerFile))) {\n generatedFiles.push({\n file: otelServerFile,\n contents: renderFrameworkOtelInitForPkg(\n useTs ? REMIX_OTEL_SERVER_TS : REMIX_OTEL_SERVER_JS,\n pkg,\n serviceDir,\n project,\n ),\n skipIfExists: true,\n })\n }\n await queueEnvNeat(serviceDir, pkg, project, generatedFiles)\n\n const entrypointEdits: EntrypointEdit[] = []\n try {\n const raw = await fs.readFile(entryFile, 'utf8')\n if (!fileImportsOtelHook(raw, ['./otel.server'])) {\n const lines = raw.split(/\\r?\\n/)\n const firstReal = lines[0]?.startsWith('#!') ? lines[1] ?? '' : lines[0] ?? ''\n entrypointEdits.push({\n file: entryFile,\n before: firstReal,\n after: \"import './otel.server'\",\n })\n }\n } catch {\n // Entry file disappeared between detect and plan; fall through.\n }\n\n const empty =\n dependencyEdits.length === 0 &&\n generatedFiles.length === 0 &&\n entrypointEdits.length === 0\n\n if (empty) {\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits: [],\n entrypointEdits: [],\n envEdits: [],\n generatedFiles: [],\n framework: 'remix',\n }\n }\n\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits,\n entrypointEdits,\n envEdits: [OTEL_ENV],\n generatedFiles,\n framework: 'remix',\n }\n}\n\nasync function planSvelteKit(\n serviceDir: string,\n pkg: PackageJsonShape,\n manifestPath: string,\n hooksFile: string | null,\n project: string | undefined,\n): Promise<InstallPlan> {\n const useTs = await isTypeScriptProject(serviceDir)\n const otelInitFile = path.join(\n serviceDir,\n useTs ? 'src/otel-init.ts' : 'src/otel-init.js',\n )\n const resolvedHooksFile =\n hooksFile ??\n path.join(serviceDir, useTs ? 'src/hooks.server.ts' : 'src/hooks.server.js')\n\n const dependencyEdits = buildDependencyEdits(pkg, manifestPath)\n const generatedFiles: GeneratedFile[] = []\n const entrypointEdits: EntrypointEdit[] = []\n\n if (!(await exists(otelInitFile))) {\n generatedFiles.push({\n file: otelInitFile,\n contents: renderFrameworkOtelInitForPkg(\n useTs ? SVELTEKIT_OTEL_INIT_TS : SVELTEKIT_OTEL_INIT_JS,\n pkg,\n serviceDir,\n project,\n ),\n skipIfExists: true,\n })\n }\n await queueEnvNeat(serviceDir, pkg, project, generatedFiles)\n\n if (hooksFile === null) {\n generatedFiles.push({\n file: resolvedHooksFile,\n contents: useTs ? SVELTEKIT_HOOKS_SERVER_TS : SVELTEKIT_HOOKS_SERVER_JS,\n skipIfExists: true,\n })\n } else {\n try {\n const raw = await fs.readFile(hooksFile, 'utf8')\n if (!fileImportsOtelHook(raw, ['./otel-init'])) {\n const lines = raw.split(/\\r?\\n/)\n const firstReal = lines[0]?.startsWith('#!') ? lines[1] ?? '' : lines[0] ?? ''\n entrypointEdits.push({\n file: hooksFile,\n before: firstReal,\n after: \"import './otel-init'\",\n })\n }\n } catch {\n // Disappeared between detect and plan; fall through.\n }\n }\n\n const empty =\n dependencyEdits.length === 0 &&\n generatedFiles.length === 0 &&\n entrypointEdits.length === 0\n\n if (empty) {\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits: [],\n entrypointEdits: [],\n envEdits: [],\n generatedFiles: [],\n framework: 'sveltekit',\n }\n }\n\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits,\n entrypointEdits,\n envEdits: [OTEL_ENV],\n generatedFiles,\n framework: 'sveltekit',\n }\n}\n\nasync function planNuxt(\n serviceDir: string,\n pkg: PackageJsonShape,\n manifestPath: string,\n project: string | undefined,\n): Promise<InstallPlan> {\n const useTs = await isTypeScriptProject(serviceDir)\n const otelPluginFile = path.join(\n serviceDir,\n useTs ? 'server/plugins/otel.ts' : 'server/plugins/otel.js',\n )\n const otelInitFile = path.join(\n serviceDir,\n useTs ? 'server/plugins/otel-init.ts' : 'server/plugins/otel-init.js',\n )\n\n const dependencyEdits = buildDependencyEdits(pkg, manifestPath)\n const generatedFiles: GeneratedFile[] = []\n\n if (!(await exists(otelInitFile))) {\n generatedFiles.push({\n file: otelInitFile,\n contents: renderFrameworkOtelInitForPkg(\n useTs ? NUXT_OTEL_INIT_TS : NUXT_OTEL_INIT_JS,\n pkg,\n serviceDir,\n project,\n ),\n skipIfExists: true,\n })\n }\n if (!(await exists(otelPluginFile))) {\n generatedFiles.push({\n file: otelPluginFile,\n contents: useTs ? NUXT_OTEL_PLUGIN_TS : NUXT_OTEL_PLUGIN_JS,\n skipIfExists: true,\n })\n }\n await queueEnvNeat(serviceDir, pkg, project, generatedFiles)\n\n const empty = dependencyEdits.length === 0 && generatedFiles.length === 0\n\n if (empty) {\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits: [],\n entrypointEdits: [],\n envEdits: [],\n generatedFiles: [],\n framework: 'nuxt',\n }\n }\n\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits,\n entrypointEdits: [],\n envEdits: [OTEL_ENV],\n generatedFiles,\n framework: 'nuxt',\n }\n}\n\nconst ASTRO_MIDDLEWARE_CANDIDATES = ['src/middleware.ts', 'src/middleware.js']\n\nasync function findAstroMiddleware(serviceDir: string): Promise<string | null> {\n for (const rel of ASTRO_MIDDLEWARE_CANDIDATES) {\n const candidate = path.join(serviceDir, rel)\n if (await exists(candidate)) return candidate\n }\n return null\n}\n\nasync function planAstro(\n serviceDir: string,\n pkg: PackageJsonShape,\n manifestPath: string,\n project: string | undefined,\n): Promise<InstallPlan> {\n const useTs = await isTypeScriptProject(serviceDir)\n const otelInitFile = path.join(\n serviceDir,\n useTs ? 'src/otel-init.ts' : 'src/otel-init.js',\n )\n const existingMiddleware = await findAstroMiddleware(serviceDir)\n const middlewareFile =\n existingMiddleware ??\n path.join(serviceDir, useTs ? 'src/middleware.ts' : 'src/middleware.js')\n\n const dependencyEdits = buildDependencyEdits(pkg, manifestPath)\n const generatedFiles: GeneratedFile[] = []\n const entrypointEdits: EntrypointEdit[] = []\n\n if (!(await exists(otelInitFile))) {\n generatedFiles.push({\n file: otelInitFile,\n contents: renderFrameworkOtelInitForPkg(\n useTs ? ASTRO_OTEL_INIT_TS : ASTRO_OTEL_INIT_JS,\n pkg,\n serviceDir,\n project,\n ),\n skipIfExists: true,\n })\n }\n await queueEnvNeat(serviceDir, pkg, project, generatedFiles)\n\n if (existingMiddleware === null) {\n generatedFiles.push({\n file: middlewareFile,\n contents: useTs ? ASTRO_MIDDLEWARE_TS : ASTRO_MIDDLEWARE_JS,\n skipIfExists: true,\n })\n } else {\n try {\n const raw = await fs.readFile(existingMiddleware, 'utf8')\n if (!fileImportsOtelHook(raw, ['./otel-init'])) {\n const lines = raw.split(/\\r?\\n/)\n const firstReal = lines[0]?.startsWith('#!') ? lines[1] ?? '' : lines[0] ?? ''\n entrypointEdits.push({\n file: existingMiddleware,\n before: firstReal,\n after: \"import './otel-init'\",\n })\n }\n } catch {\n // Disappeared between detect and plan; fall through.\n }\n }\n\n const empty =\n dependencyEdits.length === 0 &&\n generatedFiles.length === 0 &&\n entrypointEdits.length === 0\n\n if (empty) {\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits: [],\n entrypointEdits: [],\n envEdits: [],\n generatedFiles: [],\n framework: 'astro',\n }\n }\n\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits,\n entrypointEdits,\n envEdits: [OTEL_ENV],\n generatedFiles,\n framework: 'astro',\n }\n}\n\ntype FrameworkDispatch = () => Promise<InstallPlan>\n\n// ADR-073 §1 + ADR-074 §3 — framework signal lookup. Returns a thunk that\n// invokes the framework-specific planner when a match lands, or null when\n// none do. Detection precedence is Next → Remix → SvelteKit → Nuxt → Astro;\n// the chain bails on the first match. Pulled out of `plan()` so issue\n// #375's lib-only check can see the framework signal upfront — a package\n// with no framework hook AND no Node entry buckets as lib-only regardless\n// of stray Vite config or Expo deps.\nasync function findFrameworkDispatch(\n serviceDir: string,\n pkg: PackageJsonShape,\n manifestPath: string,\n project: string | undefined,\n): Promise<FrameworkDispatch | null> {\n if (hasNextDependency(pkg)) {\n const nextConfig = await findNextConfig(serviceDir)\n if (nextConfig) {\n return () => planNext(serviceDir, pkg, manifestPath, nextConfig, project)\n }\n }\n if (hasRemixDependency(pkg)) {\n const remixEntry = await findRemixEntry(serviceDir)\n if (remixEntry) {\n return () => planRemix(serviceDir, pkg, manifestPath, remixEntry, project)\n }\n }\n if (hasSvelteKitDependency(pkg)) {\n const hooks = await findSvelteKitHooks(serviceDir)\n const config = await findSvelteKitConfig(serviceDir)\n if (hooks || config) {\n return () => planSvelteKit(serviceDir, pkg, manifestPath, hooks, project)\n }\n }\n if (hasNuxtDependency(pkg)) {\n const nuxtConfig = await findNuxtConfig(serviceDir)\n if (nuxtConfig) {\n return () => planNuxt(serviceDir, pkg, manifestPath, project)\n }\n }\n if (hasAstroDependency(pkg)) {\n const astroConfig = await findAstroConfig(serviceDir)\n if (astroConfig) {\n return () => planAstro(serviceDir, pkg, manifestPath, project)\n }\n }\n return null\n}\n\nasync function plan(serviceDir: string, opts?: PlanOptions): Promise<InstallPlan> {\n const pkg = await readPackageJson(serviceDir)\n const manifestPath = path.join(serviceDir, 'package.json')\n const project = opts?.project\n const empty: InstallPlan = {\n language: 'javascript',\n serviceDir,\n dependencyEdits: [],\n entrypointEdits: [],\n envEdits: [],\n generatedFiles: [],\n }\n if (!pkg) return empty\n\n // Issue #375 — classification pipeline order: lib-only → framework →\n // runtime-kind → emit. A package with no framework hook AND no resolvable\n // Node entry is lib-only regardless of stray Vite config or Expo deps. The\n // runtime-kind dispatch only fires for non-framework packages that\n // actually have an entry to instrument; without this ordering, a UI library\n // that ships a `vite.config.ts` for its build pipeline would bucket as\n // browser-bundle and surface in the operator summary as if it were a real\n // SPA the installer was choosing to skip.\n const frameworkDispatch = await findFrameworkDispatch(\n serviceDir,\n pkg,\n manifestPath,\n project,\n )\n\n // Resolve the Node entry up front so the lib-only check can read both\n // signals together. Skipped on the framework branch — frameworks own their\n // boot path and never need a `pkg.main` injection (the chain returns\n // before this line runs).\n let entryFile: string | null = null\n if (!frameworkDispatch) {\n entryFile = await resolveEntry(serviceDir, pkg)\n if (!entryFile) {\n return { ...empty, libOnly: true }\n }\n }\n\n if (frameworkDispatch) {\n return frameworkDispatch()\n }\n\n // Issue #370 — runtime-kind detection sits between the lib-only check and\n // vanilla Node template emission. Browser bundles (Vite) and React Native\n // / Expo packages bucket here so the apply phase skips every write and\n // surfaces the package in the summary instead of injecting a Node SDK hook\n // into code that can't run it.\n const runtimeKind = await detectRuntimeKind(serviceDir, pkg)\n if (runtimeKind !== 'node') {\n return { ...empty, runtimeKind }\n }\n\n // entryFile resolved above on the non-framework branch; the null path\n // already returned lib-only.\n if (!entryFile) {\n return { ...empty, libOnly: true }\n }\n const flavor = dispatchEntry(entryFile, pkg)\n const otelInitFile = path.join(path.dirname(entryFile), otelInitFilename(flavor))\n const envNeatFile = path.join(serviceDir, '.env.neat')\n\n // ── Dependency edits (four-deps invariant; ADR-069 §5). ────────────────\n // Issue #376 — non-bundled instrumentations append additional deps when\n // the host package declares libraries whose runtime traffic bypasses the\n // auto-instrumentation set (Prisma's Rust query engine for v0.4.5; the\n // v0.5.0 registry feeds the same loop with more entries).\n const existingDeps = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) }\n const dependencyEdits: DependencyEdit[] = []\n for (const sdk of SDK_PACKAGES) {\n if (sdk.name in existingDeps) {\n if (needsVersionUpgrade(existingDeps[sdk.name]!, sdk.version)) {\n dependencyEdits.push({ file: manifestPath, kind: 'upgrade', name: sdk.name, version: sdk.version, fromVersion: existingDeps[sdk.name]! })\n }\n continue\n }\n dependencyEdits.push({ file: manifestPath, kind: 'add', name: sdk.name, version: sdk.version })\n }\n const nonBundled = detectNonBundledInstrumentations(pkg)\n for (const inst of nonBundled) {\n if (inst.pkg in existingDeps) {\n if (needsVersionUpgrade(existingDeps[inst.pkg]!, inst.version)) {\n dependencyEdits.push({ file: manifestPath, kind: 'upgrade', name: inst.pkg, version: inst.version, fromVersion: existingDeps[inst.pkg]! })\n }\n continue\n }\n dependencyEdits.push({ file: manifestPath, kind: 'add', name: inst.pkg, version: inst.version })\n }\n\n // ── Entry-point injection edit (ADR-069 §3). ───────────────────────────\n const entrypointEdits: EntrypointEdit[] = []\n try {\n const raw = await fs.readFile(entryFile, 'utf8')\n const lines = raw.split(/\\r?\\n/)\n // Preserve a shebang on line 1 and check line 2 (the first non-shebang\n // line) for an existing injection.\n const firstReal = lines[0]?.startsWith('#!') ? lines[1] ?? '' : lines[0] ?? ''\n if (!lineIsOtelInjection(firstReal)) {\n const inject = injectionLine(flavor, entryFile, otelInitFile)\n // Use the existing first-real line as the `before` marker so the apply\n // phase can splice the injection cleanly even if the file shifts.\n entrypointEdits.push({\n file: entryFile,\n before: firstReal,\n after: inject,\n })\n }\n } catch {\n // Entry file disappeared between resolve and plan (rare). Treat as\n // lib-only.\n return { ...empty, libOnly: true }\n }\n\n // ── Generated files (ADR-069 §1, §4). ──────────────────────────────────\n // v0.4.4 — the otel-init template carries `__SERVICE_NAME__` (the\n // ServiceNode id) and `__PROJECT__` (the URL routing key) placeholders we\n // substitute here. The .env.neat shape lands with the same pair so an\n // operator can grep for both fields in one place.\n // v0.4.5 — `__INSTRUMENTATION_BLOCK__` substitutes to the registration\n // snippets for any non-bundled instrumentations detected above (Prisma\n // for v0.4.5; the v0.5.0 registry will feed more entries through the same\n // path). Empty list collapses cleanly to nothing.\n const svcName = serviceNodeName(pkg, serviceDir)\n const projectName = projectToken(pkg, serviceDir, project)\n const registrations = nonBundled.map((i) => i.registration)\n const generatedFiles: GeneratedFile[] = []\n const otelInitGen = await planOtelInitGeneration(\n otelInitFile,\n renderNodeOtelInit(otelInitContents(flavor), svcName, projectName, registrations),\n )\n if (otelInitGen) generatedFiles.push(otelInitGen)\n if (!(await exists(envNeatFile))) {\n generatedFiles.push({\n file: envNeatFile,\n contents: renderEnvNeat(svcName, projectName),\n skipIfExists: true,\n })\n }\n\n // ── Idempotency check (ADR-069 §6). ────────────────────────────────────\n // If the package is already instrumented end-to-end — deps present, entry\n // already injected, generated files already there — return an empty plan.\n if (\n dependencyEdits.length === 0 &&\n entrypointEdits.length === 0 &&\n generatedFiles.length === 0\n ) {\n return empty\n }\n\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits,\n entrypointEdits,\n envEdits: [OTEL_ENV],\n generatedFiles,\n entryFile,\n libOnly: false,\n }\n}\n\n// ADR-069 §7 + ADR-073 §1 + ADR-074 §3 — allowed write paths. Anything\n// outside this set inside an installer's apply phase is a contract violation.\nfunction isAllowedWritePath(serviceDir: string, target: string): boolean {\n const rel = path.relative(serviceDir, target)\n if (rel.startsWith('..')) return false\n const base = path.basename(target)\n if (base === 'package.json') return true\n if (base === '.env.neat') return true\n if (/^otel-init\\.(?:js|cjs|mjs|ts)$/.test(base)) return true\n // ADR-073 §1 / ADR-126 — Next framework files at the package root, or\n // under src/ when create-next-app's --src-dir layout is in use. The\n // instrumentation hook resolves from `src/` in that layout; routing files\n // there is the load-bearing fix for the src-dir shape. `.edge` joins\n // `.node` as the second runtime-scoped instrumentation file (ADR-126).\n const relPosix = rel.split(path.sep).join('/')\n if (/^instrumentation(?:\\.(?:node|edge))?\\.(?:js|cjs|mjs|ts)$/.test(base)) {\n if (relPosix === base) return true\n if (relPosix === `src/${base}`) return true\n return false\n }\n if (/^next\\.config\\.(?:js|mjs|ts)$/.test(base)) return true\n // ADR-074 §3 — meta-framework hook surfaces.\n if (relPosix === 'app/otel.server.ts' || relPosix === 'app/otel.server.js') return true\n if (/^app\\/entry\\.server\\.(?:tsx?|jsx?)$/.test(relPosix)) return true\n if (relPosix === 'src/otel-init.ts' || relPosix === 'src/otel-init.js') return true\n if (relPosix === 'src/hooks.server.ts' || relPosix === 'src/hooks.server.js') return true\n if (relPosix === 'server/plugins/otel.ts' || relPosix === 'server/plugins/otel.js') return true\n if (relPosix === 'server/plugins/otel-init.ts' || relPosix === 'server/plugins/otel-init.js') return true\n if (relPosix === 'src/middleware.ts' || relPosix === 'src/middleware.js') return true\n return false\n}\n\nasync function writeAtomic(file: string, contents: string): Promise<void> {\n // Meta-framework branches write to convention-driven subdirs that the user\n // may not have scaffolded yet (`server/plugins/`, `src/`, `app/`). Ensure\n // the parent directory exists before the atomic write; existing parents\n // are a no-op under `recursive: true`.\n await fs.mkdir(path.dirname(file), { recursive: true })\n const tmp = `${file}.${process.pid}.${Date.now()}.tmp`\n await fs.writeFile(tmp, contents, 'utf8')\n await fs.rename(tmp, file)\n}\n\nasync function apply(installPlan: InstallPlan): Promise<ApplyResult> {\n const { serviceDir } = installPlan\n if (installPlan.libOnly) {\n return {\n serviceDir,\n outcome: 'lib-only',\n reason: 'no resolvable entry point',\n writtenFiles: [],\n }\n }\n\n // Issue #370 — non-Node runtimes write nothing. The CLI surfaces the\n // outcome in the summary so the operator can see which packages were\n // skipped and why.\n if (installPlan.runtimeKind === 'browser-bundle') {\n return {\n serviceDir,\n outcome: 'browser-bundle',\n reason: 'browser bundle; Node OTel SDK cannot run here',\n writtenFiles: [],\n }\n }\n if (installPlan.runtimeKind === 'react-native') {\n return {\n serviceDir,\n outcome: 'react-native',\n reason: 'React Native / Expo target; Node OTel SDK cannot run here',\n writtenFiles: [],\n }\n }\n if (installPlan.runtimeKind === 'bun') {\n return { serviceDir, outcome: 'bun', reason: 'Bun runtime; use BYO-OTel', writtenFiles: [] }\n }\n if (installPlan.runtimeKind === 'deno') {\n return { serviceDir, outcome: 'deno', reason: 'Deno runtime; use BYO-OTel', writtenFiles: [] }\n }\n if (installPlan.runtimeKind === 'cloudflare-workers') {\n return {\n serviceDir,\n outcome: 'cloudflare-workers',\n reason: 'Cloudflare Workers runtime; use BYO-OTel',\n writtenFiles: [],\n }\n }\n if (installPlan.runtimeKind === 'electron') {\n return {\n serviceDir,\n outcome: 'electron',\n reason: 'Electron; use BYO-OTel',\n writtenFiles: [],\n }\n }\n\n // Already-instrumented check: an empty plan means there's nothing to do.\n if (\n installPlan.dependencyEdits.length === 0 &&\n installPlan.entrypointEdits.length === 0 &&\n (installPlan.generatedFiles?.length ?? 0) === 0 &&\n installPlan.nextConfigEdit === undefined\n ) {\n return {\n serviceDir,\n outcome: 'already-instrumented',\n writtenFiles: [],\n }\n }\n\n // Validate every target we plan to touch against the allowed-path set.\n // Bail out before any write if a violation slipped through.\n const allTargets = new Set<string>()\n for (const d of installPlan.dependencyEdits) allTargets.add(d.file)\n for (const e of installPlan.entrypointEdits) allTargets.add(e.file)\n for (const g of installPlan.generatedFiles ?? []) allTargets.add(g.file)\n if (installPlan.nextConfigEdit) allTargets.add(installPlan.nextConfigEdit.file)\n for (const target of allTargets) {\n // Entry-point edits land in user source files, not the allowed set —\n // they're explicitly carved out below.\n const isEntryEdit = installPlan.entrypointEdits.some((e) => e.file === target)\n if (isEntryEdit) continue\n if (!isAllowedWritePath(serviceDir, target)) {\n throw new Error(\n `javascript installer: refusing to write outside the allowed path set (ADR-069 §7): ${target}`,\n )\n }\n }\n\n // Snapshot every file we may touch so a partial failure can roll back the\n // batch (ADR-047 §7). Newly-generated files have no prior contents — they\n // get tracked separately so rollback unlinks them instead of restoring.\n const originals = new Map<string, string>()\n const createdFiles: string[] = []\n for (const target of allTargets) {\n if (await exists(target)) {\n try {\n originals.set(target, await fs.readFile(target, 'utf8'))\n } catch {\n // Best-effort. The mutation loop below will throw if this matters.\n }\n }\n }\n\n const writtenFiles: string[] = []\n try {\n // ── 1. Manifest edits (package.json) ─────────────────────────────────\n const manifestTargets = installPlan.dependencyEdits\n .reduce<Set<string>>((acc, e) => {\n acc.add(e.file)\n return acc\n }, new Set())\n for (const file of manifestTargets) {\n const raw = originals.get(file)\n if (raw === undefined) {\n throw new Error(`javascript installer: cannot read ${file} during apply`)\n }\n const pkg = JSON.parse(raw) as PackageJsonShape\n pkg.dependencies = pkg.dependencies ?? {}\n for (const dep of installPlan.dependencyEdits) {\n if (dep.file !== file) continue\n if (dep.kind === 'add') {\n if (!(dep.name in (pkg.dependencies ?? {}))) {\n pkg.dependencies[dep.name] = dep.version\n }\n } else if (dep.kind === 'upgrade') {\n pkg.dependencies[dep.name] = dep.version\n } else {\n delete pkg.dependencies[dep.name]\n }\n }\n const newRaw = JSON.stringify(pkg, null, 2) + '\\n'\n await writeAtomic(file, newRaw)\n writtenFiles.push(file)\n }\n\n // ── 2. Generated files (otel-init, .env.neat) ────────────────────────\n for (const gen of installPlan.generatedFiles ?? []) {\n if (gen.skipIfExists && (await exists(gen.file))) {\n // Skip silently; the contract treats this as part of the\n // already-instrumented path.\n continue\n }\n await writeAtomic(gen.file, gen.contents)\n if (!originals.has(gen.file)) createdFiles.push(gen.file)\n writtenFiles.push(gen.file)\n }\n\n // ── 3. Entry-point injection (require/import on first non-shebang line)\n for (const ep of installPlan.entrypointEdits) {\n const raw = originals.get(ep.file)\n if (raw === undefined) {\n throw new Error(`javascript installer: cannot read entry ${ep.file} during apply`)\n }\n const lines = raw.split(/\\r?\\n/)\n const hasShebang = lines[0]?.startsWith('#!') ?? false\n const insertAt = hasShebang ? 1 : 0\n // Idempotency: if the first non-shebang line already matches our\n // injection pattern, skip — never double-inject.\n const firstReal = lines[insertAt] ?? ''\n if (lineIsOtelInjection(firstReal)) continue\n lines.splice(insertAt, 0, ep.after)\n const newRaw = lines.join('\\n')\n await writeAtomic(ep.file, newRaw)\n writtenFiles.push(ep.file)\n }\n\n // ── 4. Next.js config flag (ADR-073 §1) — only present on the Next\n // path when the declared major is < 15 and the flag isn't already\n // mentioned in the file. Best-effort regex insertion into the first\n // config object literal; bails silently when the shape isn't\n // recognisable so we never corrupt a user-customised config.\n if (installPlan.nextConfigEdit) {\n const target = installPlan.nextConfigEdit.file\n const raw = originals.get(target)\n if (raw !== undefined && !raw.includes('instrumentationHook')) {\n const updated = injectInstrumentationHook(raw)\n if (updated !== null) {\n await writeAtomic(target, updated)\n writtenFiles.push(target)\n }\n }\n }\n } catch (err) {\n await rollback(installPlan, originals, createdFiles)\n throw err\n }\n\n return {\n serviceDir,\n outcome: 'instrumented',\n writtenFiles,\n }\n}\n\nasync function rollback(\n installPlan: InstallPlan,\n originals: Map<string, string>,\n createdFiles: string[],\n): Promise<void> {\n const restored: string[] = []\n const removed: string[] = []\n for (const [file, raw] of originals.entries()) {\n try {\n await fs.writeFile(file, raw, 'utf8')\n restored.push(file)\n } catch {\n // Best-effort: keep going so we restore as much as we can.\n }\n }\n for (const file of createdFiles) {\n try {\n await fs.unlink(file)\n removed.push(file)\n } catch {\n // Best-effort.\n }\n }\n const lines = [\n '# neat-rollback.patch',\n '',\n `# Generated after a partial apply failure in the ${installPlan.language} installer.`,\n '# Files listed below were restored to their pre-apply contents.',\n '',\n ...restored.map((f) => `restored: ${f}`),\n ...removed.map((f) => `removed: ${f}`),\n '',\n ]\n const rollbackPath = path.join(installPlan.serviceDir, 'neat-rollback.patch')\n await fs.writeFile(rollbackPath, lines.join('\\n'), 'utf8')\n}\n\n// ADR-073 §1 — best-effort injection of `experimental.instrumentationHook:\n// true` into a next.config.{js,ts,mjs}. Returns the rewritten contents on\n// success, or null when the config shape isn't recognisable (in which case\n// the apply phase leaves the file alone — partial Next coverage is fine,\n// silent corruption of a user's config is not).\n//\n// Recognised shapes:\n// - `module.exports = { ... }` (CJS)\n// - `module.exports = { ... } satisfies NextConfig` (TS-via-CJS)\n// - `export default { ... }` (ESM / TS)\n// - `const nextConfig = { ... }; module.exports = nextConfig` (named CJS)\n// - `const nextConfig: NextConfig = { ... }; export default nextConfig` (TS)\nexport function injectInstrumentationHook(raw: string): string | null {\n if (raw.includes('instrumentationHook')) return raw\n\n // Strategy: find the first config object literal whose contents we can\n // edit, then either merge into an existing `experimental: { ... }` block\n // or insert a fresh `experimental: { instrumentationHook: true }` entry.\n //\n // We look for one of four anchors near a top-level `{` and splice from\n // there. The regexes capture the `{` so we can splice right after it.\n const anchors: Array<{ pattern: RegExp; label: string }> = [\n { pattern: /(module\\.exports\\s*=\\s*\\{)/, label: 'cjs-default' },\n { pattern: /(export\\s+default\\s*\\{)/, label: 'esm-default' },\n { pattern: /(?:const|let|var)\\s+\\w+(?:\\s*:\\s*[^=]+)?\\s*=\\s*(\\{)/, label: 'named-config' },\n ]\n\n for (const { pattern } of anchors) {\n const match = pattern.exec(raw)\n if (!match) continue\n const insertAfter = match.index + match[0].length\n const before = raw.slice(0, insertAfter)\n const after = raw.slice(insertAfter)\n // Insert a leading newline so the injection sits on its own line and\n // doesn't fight any existing trailing-comma style. Two-space indent\n // covers most code-styled configs.\n const injection = '\\n experimental: { instrumentationHook: true },'\n return `${before}${injection}${after}`\n }\n\n return null\n}\n\nexport const javascriptInstaller: Installer = {\n name: 'javascript',\n detect,\n plan,\n apply,\n}\n\n// Re-exports used by the contract test surface.\nexport { NEXT_INSTRUMENTATION_HEADER, OTEL_INIT_HEADER }\n","/**\n * Generated-file templates for the Node SDK installer (ADR-069 §1).\n *\n * Three flavors so the inserted file matches the host package's module\n * system: CJS for `require`-based packages, ESM for `import`-based, TS for\n * TypeScript entries. Env vars are inlined as `process.env.X ||=` defaults\n * rather than loaded from `.env.neat` at runtime — `__dirname` /\n * `import.meta.url` resolve unpredictably once a bundler rewrites the\n * generated file (Brief-smoke evidence, issue #369), so we let the OTel SDK\n * read its config from the same `process.env` either way. Platform env\n * (Vercel / Railway / Fly / etc.) stays authoritative at deploy time;\n * `||=` keeps the local default for laptop dev only.\n */\n\n// Header comment that ships at the top of every generated otel-init. Stable\n// across flavors so a grep for the header line finds every generated file in\n// a target codebase. Used by the idempotency check too (ADR-069 §6).\nexport const OTEL_INIT_HEADER = '// Generated by `neat init --apply` (ADR-069). OpenTelemetry auto-instrumentation hook.'\n\n// Version stamp on the generated otel-init (file-awareness.md §4). A NEAT-owned\n// file carries OTEL_INIT_HEADER; the stamp records which template revision wrote\n// it. On re-run, an existing NEAT-owned file whose stamp is older than the\n// current one is regenerated (a hand-written init — no header — is never\n// touched). Bump the revision whenever the generated body changes shape.\nexport const OTEL_INIT_STAMP =\n '// neat-template-version: 6 — daemon.json endpoint resolution (ADR-096) + layered file-first capture (ADR-090).'\n\n// OTLP exporter auth (ADR-073 §3/§4, #410). When the operator runs the\n// instrumented app with `NEAT_OTEL_TOKEN` set — the same secret the daemon's\n// OTLP receiver reads (`NEAT_OTEL_TOKEN ?? NEAT_AUTH_TOKEN`) — the exporter\n// sends `Authorization: Bearer <token>` so a secured daemon accepts the spans.\n// Unset (laptop dev against a loopback daemon with no token) sends no header,\n// matching the daemon's unauthenticated loopback path. The token is the single\n// source: it lives in the environment, never inlined into the generated file.\n// `||=` keeps any platform-set header (Vercel / Railway / Fly) authoritative.\nexport const OTEL_OTLP_HEADERS_JS =\n \"if (process.env.NEAT_OTEL_TOKEN) process.env.OTEL_EXPORTER_OTLP_HEADERS ||= 'Authorization=Bearer ' + process.env.NEAT_OTEL_TOKEN\"\n\n// Export protocol pin (#468). The OTel JS SDK defaults to http/protobuf; NEAT's\n// receiver accepts both, but http/json is the wire format the smoke gates\n// validate hardest, so the generated init pins it. Same `||=` discipline as the\n// other inlined env: an operator who explicitly sets\n// OTEL_EXPORTER_OTLP_PROTOCOL (e.g. to route through a collector that insists\n// on protobuf) stays authoritative.\nexport const OTEL_OTLP_PROTOCOL_JS =\n \"process.env.OTEL_EXPORTER_OTLP_PROTOCOL ||= 'http/json'\"\n\n// OTLP endpoint resolution (ADR-096 / project-daemon contract). Under\n// one-daemon-per-project the daemon allocates its OTLP port once (canonical\n// 4318, stepping to the next free port when a sibling daemon already holds it)\n// and records it in `<project>/neat-out/daemon.json`. The instrumented app must\n// read THAT port back, or a second project's app — baked to a fixed 4318 —\n// sends its spans to the first project's daemon, which has no slot for them and\n// drops them: the second project's OBSERVED layer goes dark silently. That is\n// exactly the failure this code exists to kill, so the endpoint is resolved at\n// app boot from the daemon's own record rather than hardcoded.\n//\n// Precedence (highest first):\n// 1. An explicit OTEL_EXPORTER_OTLP_TRACES_ENDPOINT / _ENDPOINT env var —\n// the prod/hosted path where a platform or collector owns the target.\n// 2. `<project>/neat-out/daemon.json` → `ports.otlp` → the bare\n// `http://localhost:<otlp>/v1/traces` route the per-project daemon serves.\n// 3. The canonical `http://localhost:4318/v1/traces` default — the laptop\n// happy path where the daemon took its first-choice port.\n//\n// This is INJECTED into the user's app, so it is bulletproof: the whole thing\n// is wrapped in try/catch, a missing or malformed daemon.json falls through to\n// the canonical default, and it NEVER throws — a resolution failure must not\n// crash the host app's startup. The daemon.json path is resolved by walking up\n// from the app's runtime cwd looking for `neat-out/daemon.json`, which lands on\n// the project root whether the app boots from the project root (single package)\n// or a package subdirectory (monorepo).\n//\n// The endpoint matches the bare `/v1/traces` route the per-project daemon\n// serves (daemon.ts) — NOT the legacy `/projects/<name>/v1/traces` form, since\n// a daemon that hosts exactly one project needs no project name to disambiguate.\n\n// CJS flavor — `require('node:fs')` is available in the require-based template.\nexport const OTEL_ENDPOINT_RESOLVER_CJS = `;(function () {\n try {\n if (process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT || process.env.OTEL_EXPORTER_OTLP_ENDPOINT) return\n const __neatFs = require('node:fs')\n const __neatPath = require('node:path')\n let __neatDir = process.cwd()\n for (let __i = 0; __i < 8; __i++) {\n try {\n const __rec = JSON.parse(__neatFs.readFileSync(__neatPath.join(__neatDir, 'neat-out', 'daemon.json'), 'utf8'))\n if (__rec && __rec.ports && typeof __rec.ports.otlp === 'number') {\n process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = 'http://localhost:' + __rec.ports.otlp + '/v1/traces'\n break\n }\n } catch (_e) {}\n const __parent = __neatPath.dirname(__neatDir)\n if (__parent === __neatDir) break\n __neatDir = __parent\n }\n } catch (_e) {}\n process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||= 'http://localhost:4318/v1/traces'\n})()`\n\n// ESM/TS flavor — `require` is not defined in a pure-ESM module, so the\n// built-in fs/path come in via the hoisted `import` block\n// OTEL_ESM_NODE_IMPORTS adds to the top of the generated ESM/TS file. The\n// resolver references those bindings (`__neatReadFileSync` / `__neatJoin` /\n// `__neatDirname`) directly. ES import bindings are evaluated before this IIFE\n// runs, so they're always present.\nexport const OTEL_ESM_NODE_IMPORTS =\n \"import { readFileSync as __neatReadFileSync } from 'node:fs'\\n\" +\n \"import { join as __neatJoin, dirname as __neatDirname } from 'node:path'\"\n\nexport const OTEL_ENDPOINT_RESOLVER_ESM = `;(function () {\n try {\n if (process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT || process.env.OTEL_EXPORTER_OTLP_ENDPOINT) return\n let __neatDir = process.cwd()\n for (let __i = 0; __i < 8; __i++) {\n try {\n const __rec = JSON.parse(__neatReadFileSync(__neatJoin(__neatDir, 'neat-out', 'daemon.json'), 'utf8'))\n if (__rec && __rec.ports && typeof __rec.ports.otlp === 'number') {\n process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = 'http://localhost:' + __rec.ports.otlp + '/v1/traces'\n break\n }\n } catch (_e) {}\n const __parent = __neatDirname(__neatDir)\n if (__parent === __neatDir) break\n __neatDir = __parent\n }\n } catch (_e) {}\n process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||= 'http://localhost:4318/v1/traces'\n})()`\n\n// Inlined layered call-site capture (file-awareness.md §4–6, ADR-090). The\n// whole mechanism is self-contained — NEAT can't import its own package into a\n// user's generated file, so the runtime logic is inlined verbatim. The exact\n// bytes that ship are exercised by the capture spike\n// (test/callsite-processor.test.ts) so a regression here fails CI before it\n// ships. The `ts` flag adds the few type annotations a strict tsconfig needs;\n// the runtime logic is identical across flavors.\n//\n// Three layers land the user's `file:line:function` on every CLIENT / PRODUCER\n// / SERVER span:\n// 1. Synchronous stack walk at span start — covers the sync-wrapper majority.\n// 2. Handler-entry attribution — stamps the framework SERVER span and pushes\n// the handler frame into the active context so downstream CLIENT/PRODUCER\n// spans inherit it (the floor).\n// 3. Off-stack facades — undici / built-in `fetch` (diagnostics_channel) and\n// Prisma (backdated dispatch) push the call-site frame into context for\n// the inner call; the processor reads it as a fallback.\nfunction neatCaptureSource(ts: boolean): string {\n const spanT = ts ? ': any' : ''\n const strOpt = ts ? ': string | undefined' : ''\n const anyT = ts ? ': any' : ''\n const fnT = ts ? ': any' : ''\n const arrAny = ts ? ': any[]' : ''\n return `// Context key shared by the facade/handler wraps (writers) and the\n// processor fallback (reader). Symbol.for keeps it stable even if the wraps\n// and the processor end up in different module instances.\nconst NEAT_USER_FRAME = Symbol.for('neat.user-frame')\n\nfunction __neatPickUserFrame(stack${strOpt}) {\n const lines = String(stack || '').split('\\\\n')\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i].trim()\n if (raw.indexOf('at ') !== 0) continue\n if (raw.indexOf('node_modules') !== -1) continue\n if (raw.indexOf('@opentelemetry') !== -1) continue\n if (raw.indexOf('node:') !== -1) continue\n if (raw.indexOf('NeatCallSiteSpanProcessor') !== -1) continue\n // Skip NEAT's own inlined wraps/helpers (all carry the __neat prefix) so a\n // facade frame never masquerades as the user's call site.\n if (raw.indexOf('__neat') !== -1) continue\n const bodyText = raw.slice(3)\n const loc = bodyText.match(/:(\\\\d+):(\\\\d+)\\\\)?$/)\n if (!loc) continue\n const paren = bodyText.lastIndexOf('(')\n let filepath${strOpt}\n let fn${strOpt}\n if (paren !== -1) {\n fn = bodyText.slice(0, paren).trim()\n if (fn.indexOf('async ') === 0) fn = fn.slice(6)\n if (fn.indexOf('new ') === 0) fn = fn.slice(4)\n filepath = bodyText.slice(paren + 1, bodyText.length - loc[0].length)\n } else {\n filepath = bodyText.slice(0, bodyText.length - loc[0].length)\n }\n if (filepath.indexOf('file://') === 0) filepath = filepath.slice(7)\n if (!filepath) continue\n return { filepath: filepath, lineno: Number(loc[1]), function: fn || undefined }\n }\n return null\n}\n\n// Layer 2/3 fallback source: the frame a handler-entry or facade wrap pushed\n// into context. Reads the span's own parent context first, then the active\n// context — the capture spike confirmed both return the value for undici.\nfunction __neatFrameFromContext(parentContext${anyT}) {\n try {\n const fromParent =\n parentContext && typeof parentContext.getValue === 'function'\n ? parentContext.getValue(NEAT_USER_FRAME)\n : undefined\n return fromParent || context.active().getValue(NEAT_USER_FRAME) || null\n } catch (_e) {\n return null\n }\n}\n\nfunction __neatSetCodeAttrs(span${spanT}, frame${anyT}) {\n span.setAttribute('code.filepath', frame.filepath)\n if (typeof frame.lineno === 'number') span.setAttribute('code.lineno', frame.lineno)\n if (frame.function) span.setAttribute('code.function', frame.function)\n}\n\nclass NeatCallSiteSpanProcessor {\n onStart(span${spanT}, parentContext${anyT}) {\n if (!span || (span.kind !== 2 && span.kind !== 3)) return\n // Layer 1 — synchronous stack walk (sync-wrapper instrumentations).\n let frame = __neatPickUserFrame(new Error().stack)\n // Layer 2/3 — the handler-entry or off-stack-facade frame from context.\n if (!frame) frame = __neatFrameFromContext(parentContext)\n if (!frame) return\n __neatSetCodeAttrs(span, frame)\n }\n onEnd() {}\n forceFlush() { return Promise.resolve() }\n shutdown() { return Promise.resolve() }\n}\n\n// Capture the caller's synchronous frame at the wrap point and run \\`fn\\` with\n// that frame pushed into the active context (file-awareness.md §4 layer 3). An\n// off-stack instrumentation that creates its span inside \\`fn\\` inherits the\n// frame; the processor reads it via __neatFrameFromContext.\nfunction __neatRunWithUserFrame(fn${fnT}) {\n const frame = __neatPickUserFrame(new Error().stack)\n if (!frame) return fn()\n return context.with(context.active().setValue(NEAT_USER_FRAME, frame), fn)\n}\n\n// Handler-entry attribution (file-awareness.md §4 layer 2). Stamp the framework\n// SERVER span with the handler frame captured at route registration, and push\n// the same frame into context so downstream CLIENT/PRODUCER spans inherit the\n// handler-file floor when their own stack carries none.\nfunction __neatStampHandler(frame${anyT}, run${fnT}) {\n try {\n const active = trace.getActiveSpan()\n if (active && active.kind === 1 && typeof active.setAttribute === 'function') {\n __neatSetCodeAttrs(active, frame)\n }\n } catch (_e) {}\n try {\n return context.with(context.active().setValue(NEAT_USER_FRAME, frame), run)\n } catch (_e) {\n return run()\n }\n}\n\n// require-in-the-middle is a transitive dependency of the OTel instrumentation\n// packages NEAT installs, so it resolves in any instrumented CJS service.\n// Guarded: when it's absent (or the host runs as pure ESM, where require isn't\n// defined) the off-stack/handler wraps degrade to the stack walk + context\n// floor, never to a crash.\nfunction __neatHook(modules${arrAny}, onload${fnT}) {\n try {\n const RITM = require('require-in-the-middle')\n const Hook = RITM && RITM.Hook ? RITM.Hook : RITM\n new Hook(modules, { internals: false }, onload)\n return true\n } catch (_e) {\n return false\n }\n}\n\n// Off-stack facade: Node's built-in fetch / undici. The instrumentation creates\n// the CLIENT span inside a diagnostics_channel handler detached from the\n// caller's stack, so wrap the global so the user frame is in context when the\n// span is created. The capture spike (2026-05-28) validated this on real\n// undici. .name is restored to 'fetch' for ecosystem compatibility; the inner\n// __neat name is what the frame skip keys on.\nfunction __neatWrapFetch() {\n try {\n const g${anyT} = globalThis\n if (typeof g.fetch === 'function' && !g.fetch.__neatWrapped) {\n const realFetch = g.fetch\n // The wrapper keeps its __neat-prefixed name so the frame skip in\n // __neatPickUserFrame never mistakes the wrapper's own frame for the\n // user's call site (renaming it to 'fetch' would defeat the skip).\n const __neatFetch${anyT} = function (input${anyT}, init${anyT}) {\n return __neatRunWithUserFrame(function () { return realFetch(input, init) })\n }\n __neatFetch.__neatWrapped = true\n g.fetch = __neatFetch\n }\n } catch (_e) {}\n}\n\n// Off-stack facade: @prisma/client. Prisma's query engine backdates its spans\n// from Rust, off the caller's stack. Wrap the model methods on the client\n// prototype so the call-site frame (still synchronous at \\`prisma.user.find\\`)\n// is pushed into context for the engine dispatch.\nfunction __neatWrapPrisma() {\n __neatHook(['@prisma/client'], function (exports${anyT}) {\n try {\n const Client = exports && exports.PrismaClient\n if (typeof Client === 'function' && !Client.__neatWrapped) {\n const ops = ['findUnique','findUniqueOrThrow','findFirst','findFirstOrThrow','findMany','create','createMany','update','updateMany','upsert','delete','deleteMany','count','aggregate','groupBy']\n const __neatPrismaWrapModel = function (model${anyT}) {\n if (!model || model.__neatWrapped) return model\n for (let i = 0; i < ops.length; i++) {\n const op = ops[i]\n const orig = model[op]\n if (typeof orig !== 'function') continue\n model[op] = function __neatPrismaOp(${ts ? '...args: any[]' : '...args'}) {\n const self = this\n return __neatRunWithUserFrame(function () { return orig.apply(self, args) })\n }\n }\n model.__neatWrapped = true\n return model\n }\n const proto = Client.prototype\n const handler = function (model${anyT}) { return __neatPrismaWrapModel(model) }\n // Model accessors are lazily created getters on the instance; wrap the\n // \\`$extends\\`-free common path by trapping property access via a proxy\n // on each constructed client.\n exports.PrismaClient = new Proxy(Client, {\n construct(Target${anyT}, argList${anyT}, NewTarget${anyT}) {\n const instance = Reflect.construct(Target, argList, NewTarget)\n return new Proxy(instance, {\n get(target${anyT}, prop${anyT}, receiver${anyT}) {\n const value = Reflect.get(target, prop, receiver)\n if (value && typeof value === 'object' && typeof prop === 'string' && prop[0] !== '$' && prop[0] !== '_') {\n return handler(value)\n }\n return value\n },\n })\n },\n })\n exports.PrismaClient.__neatWrapped = true\n void proto\n }\n } catch (_e) {}\n return exports\n })\n}\n\n// Handler-entry facades. express / connect share the Layer model (each route\n// handler is a function registered on a Router); the wrap captures the\n// registration frame and stamps + propagates it when the handler runs. The\n// registry is the extensibility seam — koa, fastify (via @fastify/otel),\n// nestjs, restify, and hapi add an entry as their patch surface is wired.\nfunction __neatWrapConnectStyle(mod${anyT}) {\n try {\n // express() returns an app whose route verbs live on Router.prototype and\n // the application proto; connect apps expose \\`use\\`. Wrap the registration\n // verbs so the user handler is wound with its registration frame.\n const verbs = ['use','get','post','put','delete','patch','all','options','head']\n const wrapTarget = function (target${anyT}) {\n if (!target || target.__neatVerbsWrapped) return\n for (let i = 0; i < verbs.length; i++) {\n const verb = verbs[i]\n const orig = target[verb]\n if (typeof orig !== 'function') continue\n target[verb] = function __neatVerb(${ts ? '...args: any[]' : '...args'}) {\n const frame = __neatPickUserFrame(new Error().stack)\n if (frame) {\n for (let a = 0; a < args.length; a++) {\n const h = args[a]\n if (typeof h === 'function' && !h.__neatHandlerWrapped && h.length <= 4) {\n const inner = h\n const __neatHandler${anyT} = function (${ts ? '...hargs: any[]' : '...hargs'}) {\n const self = this\n return __neatStampHandler(frame, function () { return inner.apply(self, hargs) })\n }\n __neatHandler.__neatHandlerWrapped = true\n args[a] = __neatHandler\n }\n }\n }\n return orig.apply(this, args)\n }\n }\n target.__neatVerbsWrapped = true\n }\n if (mod && mod.Router && mod.Router.prototype) wrapTarget(mod.Router.prototype)\n if (mod && mod.application) wrapTarget(mod.application)\n if (mod && mod.prototype) wrapTarget(mod.prototype)\n } catch (_e) {}\n}\n\nfunction __neatInstallHandlerEntry() {\n __neatHook(['express'], function (exports${anyT}) { __neatWrapConnectStyle(exports); return exports })\n __neatHook(['connect'], function (exports${anyT}) { __neatWrapConnectStyle(exports); return exports })\n}\n\n// Install every off-stack and handler-entry wrap. Called once after sdk.start()\n// — before user code requires the framework / Prisma modules, so the hooks land\n// on first require. Each wrap is independently guarded.\nfunction __neatInstallFacades() {\n __neatWrapFetch()\n __neatWrapPrisma()\n __neatInstallHandlerEntry()\n}`\n}\n\n// The runtime capture source, exported so the capture spike can materialise and\n// exercise the exact bytes that ship in the generated file.\nexport const CALLSITE_PROCESSOR_JS = neatCaptureSource(false)\nexport const CALLSITE_PROCESSOR_TS = neatCaptureSource(true)\n\n// Post-`sdk.start()` wiring. NodeSDK keeps its env-configured OTLP exporter\n// (passing `spanProcessors` to the constructor would replace it); we add the\n// call-site processor to the started provider via the public `getDelegate()` +\n// `addSpanProcessor()` surface, then assert it actually attached (file-\n// awareness.md §4 / ADR-090). A wiring regression that would silently drop\n// file-first capture throws loudly at boot instead of shipping service-level-\n// only spans. The facade/handler wraps install last, so a span export path is\n// live before any user module loads.\nfunction neatWireCaptureSource(ts: boolean): string {\n const providerT = ts ? ': any' : ''\n return `try {\n const provider${providerT} = trace.getTracerProvider()\n const delegate = provider && typeof provider.getDelegate === 'function' ? provider.getDelegate() : provider\n if (!delegate || typeof delegate.addSpanProcessor !== 'function') {\n throw new Error('[neat] could not resolve a TracerProvider to attach the call-site processor; file-first OBSERVED capture would be silent (file-awareness.md §4)')\n }\n const __neatProcessor = new NeatCallSiteSpanProcessor()\n delegate.addSpanProcessor(__neatProcessor)\n // Post-init assertion: confirm attachment on providers that expose their\n // processor list. An un-introspectable provider is trusted (we just called\n // its addSpanProcessor); a list that exists and lacks our processor throws.\n const registered = delegate._registeredSpanProcessors\n if (Array.isArray(registered) && registered.indexOf(__neatProcessor) === -1) {\n throw new Error('[neat] call-site processor did not attach to the active TracerProvider (file-awareness.md §4)')\n }\n} catch (err) {\n throw err\n}\ntry {\n __neatInstallFacades()\n} catch (_e) {\n // Facade install is best-effort: the stack-walk + handler-entry floor still\n // attribute the sync-wrapper majority even if an off-stack wrap fails.\n}`\n}\n\n// __SERVICE_NAME__ → the ServiceNode id (the package's `pkg.name`, or the\n// directory basename for nameless packages); __PROJECT__ → the registered\n// project basename; __INSTRUMENTATION_BLOCK__ → a (possibly empty) sequence\n// of `instrumentations.push(...)` lines for non-bundled instrumentations\n// (Prisma for v0.4.5; more libraries via the v0.5.0 registry). All three are\n// substituted at apply time via renderNodeOtelInit().\n//\n// v0.4.5 — explicit `NodeSDK` construction replaces the\n// `auto-instrumentations-node/register` shorthand so non-bundled libraries\n// (Prisma's Rust query engine bypasses node-pg; Drizzle, BetterAuth, etc.\n// have their own packages) can compose into the same `instrumentations`\n// array without templating a different file shape per library.\nexport const OTEL_INIT_CJS = `${OTEL_INIT_HEADER}\n${OTEL_INIT_STAMP}\nprocess.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'\n${OTEL_ENDPOINT_RESOLVER_CJS}\n${OTEL_OTLP_PROTOCOL_JS}\n${OTEL_OTLP_HEADERS_JS}\n\nconst { NodeSDK } = require('@opentelemetry/sdk-node')\nconst { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node')\nconst { trace, context } = require('@opentelemetry/api')\n\n${CALLSITE_PROCESSOR_JS}\n\nconst instrumentations = [getNodeAutoInstrumentations()]\n__INSTRUMENTATION_BLOCK__\nconst sdk = new NodeSDK({ instrumentations })\nsdk.start()\n${neatWireCaptureSource(false)}\n`\n\nexport const OTEL_INIT_ESM = `${OTEL_INIT_HEADER}\n${OTEL_INIT_STAMP}\n${OTEL_ESM_NODE_IMPORTS}\nprocess.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'\n${OTEL_ENDPOINT_RESOLVER_ESM}\n${OTEL_OTLP_PROTOCOL_JS}\n${OTEL_OTLP_HEADERS_JS}\n\nimport { NodeSDK } from '@opentelemetry/sdk-node'\nimport { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'\nimport { trace, context } from '@opentelemetry/api'\n\n${CALLSITE_PROCESSOR_JS}\n\nconst instrumentations = [getNodeAutoInstrumentations()]\n__INSTRUMENTATION_BLOCK__\nconst sdk = new NodeSDK({ instrumentations })\nsdk.start()\n${neatWireCaptureSource(false)}\n`\n\nexport const OTEL_INIT_TS = `${OTEL_INIT_HEADER}\n${OTEL_INIT_STAMP}\n// @ts-nocheck — generated runtime shim. The layered capture mechanism uses\n// dynamic patterns (facade wraps, Proxy traps, a createRequire bridge) that a\n// strict user tsconfig would reject; suppressing type-checking here keeps the\n// generated file from breaking the host project's \\`tsc\\` gate (#427) without\n// constraining the runtime logic. The file is regenerated, never hand-edited.\n${OTEL_ESM_NODE_IMPORTS}\nprocess.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'\n${OTEL_ENDPOINT_RESOLVER_ESM}\n${OTEL_OTLP_PROTOCOL_JS}\n${OTEL_OTLP_HEADERS_JS}\n\nimport { NodeSDK } from '@opentelemetry/sdk-node'\nimport { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'\nimport { trace, context } from '@opentelemetry/api'\n\n${CALLSITE_PROCESSOR_TS}\n\nconst instrumentations = [getNodeAutoInstrumentations()]\n__INSTRUMENTATION_BLOCK__\nconst sdk = new NodeSDK({ instrumentations })\nsdk.start()\n${neatWireCaptureSource(true)}\n`\n\n// Substitute __SERVICE_NAME__, __PROJECT__, and __INSTRUMENTATION_BLOCK__\n// at apply time. The third arg is a list of registration snippets — one per\n// non-bundled instrumentation the installer detected (e.g. Prisma). An empty\n// list collapses the placeholder to nothing so the generated file stays\n// readable on the common \"auto-instrumentations covers everything\" path.\nexport function renderNodeOtelInit(\n template: string,\n serviceName: string,\n projectName: string,\n registrations: readonly string[] = [],\n): string {\n const block = registrations.length === 0 ? '' : `\\n${registrations.join('\\n')}\\n`\n return template\n .replace(/__SERVICE_NAME__/g, serviceName)\n .replace(/__PROJECT__/g, projectName)\n .replace(/__INSTRUMENTATION_BLOCK__\\n?/g, block)\n}\n\n// .env.neat shape (ADR-069 §4, amended v0.4.1 — refs #339, v0.4.4 — refs\n// #367 + #369, v0.4.8 — refs #410, ADR-096). Two keys: OTEL_SERVICE_NAME (the\n// ServiceNode id — the package's own name, scope-preserved, so spans land on\n// per-service nodes inside the project's graph) and\n// OTEL_EXPORTER_OTLP_TRACES_ENDPOINT. Under one-daemon-per-project (ADR-096)\n// the daemon serves a bare `/v1/traces` route and allocates its OTLP port once,\n// recording it in `<project>/neat-out/daemon.json`; the generated `otel-init`\n// reads that record at boot and ignores this file, so the value here is purely\n// the canonical-default advisory the operator sees when grepping for the\n// service.name → endpoint mapping. Both env vars are advisory only — the\n// generated `otel-init` inlines/derives them so bundlers can't lose them. A\n// commented `NEAT_OTEL_TOKEN` hint documents the single source of the OTLP\n// bearer (#410): set it to the secret the daemon's receiver expects and the\n// generated init sends `Authorization: Bearer <token>`.\nexport function renderEnvNeat(serviceName: string, _projectName: string): string {\n return [\n '# Generated by `neat init --apply` (ADR-069).',\n `OTEL_SERVICE_NAME=${serviceName}`,\n '# Advisory only — the generated otel-init resolves the live endpoint from',\n '# <project>/neat-out/daemon.json (ports.otlp) at boot (ADR-096). This is the',\n '# canonical default the daemon takes when its first-choice OTLP port is free.',\n 'OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4318/v1/traces',\n 'OTEL_EXPORTER_OTLP_PROTOCOL=http/json',\n '# Set NEAT_OTEL_TOKEN to the daemon\\'s OTLP secret to authenticate exported spans (#410).',\n '# NEAT_OTEL_TOKEN=',\n '',\n ].join('\\n')\n}\n\n// ── Next.js framework-aware templates (ADR-073 §1, ADR-069 §3, ADR-126). ─\n//\n// Next.js owns its own boot — `pkg.main` is unused, and the auto-instrumentation\n// register hook can't run before user code. Next 13+ ships an `instrumentation`\n// file at the project root with an async `register()` export the framework\n// invokes during server start, once per runtime it boots. Browser bundles\n// still never load this file.\n//\n// Three-file shape: `instrumentation.{ts,js}` is the runtime gate, dispatching\n// to `instrumentation.node.{ts,js}` (the Node SDK init) on the nodejs runtime\n// and `instrumentation.edge.{ts,js}` (`@vercel/otel`, ADR-126) on the edge\n// runtime — the standard Node SDK can't execute inside Next's Edge runtime at\n// all, so the edge file leans on a runtime-aware package instead. All three\n// files sit at the project root (or under `src/` for `--src-dir` layouts).\n\nexport const NEXT_INSTRUMENTATION_HEADER =\n '// Generated by `neat init --apply` (ADR-073). Next.js instrumentation hook.'\n\nexport const NEXT_INSTRUMENTATION_TS = `${NEXT_INSTRUMENTATION_HEADER}\nexport async function register() {\n if (process.env.NEXT_RUNTIME === 'nodejs') {\n await import('./instrumentation.node')\n }\n if (process.env.NEXT_RUNTIME === 'edge') {\n await import('./instrumentation.edge')\n }\n}\n`\n\nexport const NEXT_INSTRUMENTATION_JS = `${NEXT_INSTRUMENTATION_HEADER}\nexport async function register() {\n if (process.env.NEXT_RUNTIME === 'nodejs') {\n await import('./instrumentation.node')\n }\n if (process.env.NEXT_RUNTIME === 'edge') {\n await import('./instrumentation.edge')\n }\n}\n`\n\n// Env vars are inlined as process.env defaults so they survive Turbopack /\n// Webpack bundling — `import.meta.url` resolves to a path under .next/dev/\n// server/chunks/ once Next compiles this file, which would miss .env.neat.\n// `process.env.X ||=` keeps platform env (Vercel / Railway / Fly / etc.)\n// authoritative at deploy time while the local default carries the routing\n// key the daemon needs to map spans back to this project. The endpoint uses\n// the project-scoped URL form so the daemon never has to guess which project\n// owns the span (issue #367); the OTel SDK reads the env vars from\n// process.env directly, so no file-system lookup is required at runtime.\nexport const NEXT_INSTRUMENTATION_NODE_TS = `${NEXT_INSTRUMENTATION_HEADER}\n${OTEL_ESM_NODE_IMPORTS}\nprocess.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'\n${OTEL_ENDPOINT_RESOLVER_ESM}\n${OTEL_OTLP_PROTOCOL_JS}\n${OTEL_OTLP_HEADERS_JS}\n\nimport { NodeSDK } from '@opentelemetry/sdk-node'\nimport { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'\n\nconst instrumentations = [getNodeAutoInstrumentations()]\n__INSTRUMENTATION_BLOCK__\nnew NodeSDK({ instrumentations }).start()\n`\n\nexport const NEXT_INSTRUMENTATION_NODE_JS = `${NEXT_INSTRUMENTATION_HEADER}\nprocess.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'\n${OTEL_ENDPOINT_RESOLVER_CJS}\n${OTEL_OTLP_PROTOCOL_JS}\n${OTEL_OTLP_HEADERS_JS}\n\nconst { NodeSDK } = require('@opentelemetry/sdk-node')\nconst { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node')\n\nconst instrumentations = [getNodeAutoInstrumentations()]\n__INSTRUMENTATION_BLOCK__\nnew NodeSDK({ instrumentations }).start()\n`\n\n// Substitute the placeholders at apply time so the generated file carries the\n// ServiceNode id (`__SERVICE_NAME__`) and the registered project name\n// (`__PROJECT__`) verbatim. The two roles diverged in v0.4.4: the service name\n// names the ServiceNode inside one project's graph, the project basename is\n// the URL routing key. v0.4.5 adds __INSTRUMENTATION_BLOCK__ — a (possibly\n// empty) sequence of `instrumentations.push(...)` calls for non-bundled\n// libraries like Prisma whose query engines bypass the auto-instrumentation\n// set's coverage.\nexport function renderNextInstrumentationNode(\n template: string,\n serviceName: string,\n projectName: string,\n registrations: readonly string[] = [],\n): string {\n const block = registrations.length === 0 ? '' : `\\n${registrations.join('\\n')}\\n`\n return template\n .replace(/__SERVICE_NAME__/g, serviceName)\n .replace(/__PROJECT__/g, projectName)\n .replace(/__INSTRUMENTATION_BLOCK__\\n?/g, block)\n}\n\n// ── Next.js edge-runtime template (ADR-126). ─────────────────────────────\n//\n// `@opentelemetry/sdk-node` cannot run inside Next's Edge runtime — a V8\n// isolate with no Node.js API surface (no `node:fs`, no `node:net`). Next's\n// own build-time analysis rejects an edge bundle that imports `node:fs`, so\n// this file cannot reuse the `OTEL_ENDPOINT_RESOLVER_ESM` daemon.json walk\n// the Node file relies on — that walk is exactly the kind of Node API access\n// the Edge runtime forbids. `@vercel/otel`'s `registerOTel()` is runtime-aware\n// and built on web-standard APIs instead, so one call covers the Edge runtime\n// (and, on Vercel, gets Vercel's own OTel integration for free when present).\n//\n// The endpoint still resolves from the same `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`\n// env var every other generated init reads, defaulting to the same canonical\n// `http://localhost:4318/v1/traces` — no new env var, no new config surface\n// (framework-installers.md §7, ADR-126). `registerOTel` reads OTLP\n// endpoint/protocol/headers from `process.env` itself when `traceExporter`\n// is left at its \"auto\" default, so setting the env vars ahead of the call\n// is enough; unlike the Node file there's no filesystem probe to run first.\nexport const NEXT_INSTRUMENTATION_EDGE_HEADER =\n '// Generated by `neat init --apply` (ADR-126). Next.js edge-runtime instrumentation via @vercel/otel.'\n\nexport const NEXT_INSTRUMENTATION_EDGE_TS = `${NEXT_INSTRUMENTATION_EDGE_HEADER}\nimport { registerOTel } from '@vercel/otel'\n\nprocess.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'\nprocess.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||= 'http://localhost:4318/v1/traces'\n${OTEL_OTLP_PROTOCOL_JS}\n${OTEL_OTLP_HEADERS_JS}\n\nregisterOTel({ serviceName: process.env.OTEL_SERVICE_NAME })\n`\n\n// Edge bundles are ESM-only (Next.js requires `import`/`export` syntax for\n// any file it loads into the Edge runtime), so the JS flavor is identical to\n// the TS flavor byte-for-byte — there's no CJS variant to diverge from, same\n// as the top-level instrumentation.{ts,js} gate above.\nexport const NEXT_INSTRUMENTATION_EDGE_JS = NEXT_INSTRUMENTATION_EDGE_TS\n\n// ── Meta-framework templates (ADR-074 §3). ──────────────────────────────\n//\n// Remix, SvelteKit, Nuxt, and Astro each own their boot path. The installer\n// emits one OTel-init module that loads `.env.neat` and starts the Node SDK,\n// then either creates or injects an import into the framework's canonical\n// hook file. Templates mirror the Next.js pair in shape — one generated init\n// module, one optional framework-hook stub for the absent-file case.\n\nexport const FRAMEWORK_OTEL_INIT_HEADER =\n '// Generated by `neat init --apply` (ADR-074). OpenTelemetry SDK hook.'\n\n// Same inline-defaults pattern as the plain-Node + Next templates: env vars\n// arrive on `process.env` via the apply-time substitution below so bundler\n// path mangling (issue #369) can't lose them. `__SERVICE_NAME__` /\n// `__PROJECT__` are substituted via renderFrameworkOtelInit().\nconst FRAMEWORK_OTEL_INIT_TS_BODY = `${FRAMEWORK_OTEL_INIT_HEADER}\n${OTEL_ESM_NODE_IMPORTS}\nprocess.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'\n${OTEL_ENDPOINT_RESOLVER_ESM}\n${OTEL_OTLP_PROTOCOL_JS}\n${OTEL_OTLP_HEADERS_JS}\n\nimport { NodeSDK } from '@opentelemetry/sdk-node'\nimport { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'\n\nconst sdk = new NodeSDK({\n serviceName: process.env.OTEL_SERVICE_NAME,\n instrumentations: [getNodeAutoInstrumentations()],\n})\nsdk.start()\n`\n\nconst FRAMEWORK_OTEL_INIT_JS_BODY = `${FRAMEWORK_OTEL_INIT_HEADER}\nprocess.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'\n${OTEL_ENDPOINT_RESOLVER_CJS}\n${OTEL_OTLP_PROTOCOL_JS}\n${OTEL_OTLP_HEADERS_JS}\n\nconst { NodeSDK } = require('@opentelemetry/sdk-node')\nconst { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node')\n\nconst sdk = new NodeSDK({\n serviceName: process.env.OTEL_SERVICE_NAME,\n instrumentations: [getNodeAutoInstrumentations()],\n})\nsdk.start()\n`\n\nexport function renderFrameworkOtelInit(\n template: string,\n serviceName: string,\n projectName: string,\n): string {\n return template\n .replace(/__SERVICE_NAME__/g, serviceName)\n .replace(/__PROJECT__/g, projectName)\n}\n\n// Remix — `app/otel.server.{ts,js}` carries the SDK bootstrap. The framework\n// loads `entry.server.*` at server-process start, and a top-of-module import\n// of `./otel.server` runs the bootstrap before any request handler imports.\nexport const REMIX_OTEL_SERVER_TS = FRAMEWORK_OTEL_INIT_TS_BODY\nexport const REMIX_OTEL_SERVER_JS = FRAMEWORK_OTEL_INIT_JS_BODY\n\n// SvelteKit — `src/otel-init.{ts,js}` carries the SDK bootstrap; the\n// framework's `src/hooks.server.{ts,js}` imports it. When hooks.server is\n// absent, the installer writes the stub below alongside the import.\nexport const SVELTEKIT_OTEL_INIT_TS = FRAMEWORK_OTEL_INIT_TS_BODY\nexport const SVELTEKIT_OTEL_INIT_JS = FRAMEWORK_OTEL_INIT_JS_BODY\n\nexport const SVELTEKIT_HOOKS_SERVER_TS = `${FRAMEWORK_OTEL_INIT_HEADER}\nimport './otel-init'\n\nimport type { Handle } from '@sveltejs/kit'\n\nexport const handle: Handle = async ({ event, resolve }) => {\n return resolve(event)\n}\n`\n\nexport const SVELTEKIT_HOOKS_SERVER_JS = `${FRAMEWORK_OTEL_INIT_HEADER}\nimport './otel-init'\n\n/** @type {import('@sveltejs/kit').Handle} */\nexport const handle = async ({ event, resolve }) => {\n return resolve(event)\n}\n`\n\n// Nuxt — `server/plugins/otel.{ts,js}` is the convention-loaded plugin file;\n// it imports the sibling `otel-init.{ts,js}` which carries the SDK bootstrap.\nexport const NUXT_OTEL_INIT_TS = FRAMEWORK_OTEL_INIT_TS_BODY\nexport const NUXT_OTEL_INIT_JS = FRAMEWORK_OTEL_INIT_JS_BODY\n\nexport const NUXT_OTEL_PLUGIN_TS = `${FRAMEWORK_OTEL_INIT_HEADER}\nimport './otel-init'\n\nexport default defineNitroPlugin(() => {\n // OTel SDK is initialised at module-load via the side-effect import above.\n})\n`\n\nexport const NUXT_OTEL_PLUGIN_JS = `${FRAMEWORK_OTEL_INIT_HEADER}\nrequire('./otel-init')\n\nmodule.exports = defineNitroPlugin(() => {\n // OTel SDK is initialised at module-load via the side-effect import above.\n})\n`\n\n// Astro — `src/middleware.{ts,js}` runs once at module-load (and then per\n// request via onRequest). The top-of-module import of `./otel-init` boots\n// the SDK before the first request lands.\nexport const ASTRO_OTEL_INIT_TS = FRAMEWORK_OTEL_INIT_TS_BODY\nexport const ASTRO_OTEL_INIT_JS = FRAMEWORK_OTEL_INIT_JS_BODY\n\nexport const ASTRO_MIDDLEWARE_TS = `${FRAMEWORK_OTEL_INIT_HEADER}\nimport './otel-init'\n\nimport { defineMiddleware } from 'astro:middleware'\n\nexport const onRequest = defineMiddleware(async (context, next) => {\n return next()\n})\n`\n\nexport const ASTRO_MIDDLEWARE_JS = `${FRAMEWORK_OTEL_INIT_HEADER}\nimport './otel-init'\n\nimport { defineMiddleware } from 'astro:middleware'\n\nexport const onRequest = defineMiddleware(async (context, next) => {\n return next()\n})\n`\n","/**\n * Python SDK installer (ADR-047).\n *\n * `detect` matches on the canonical Python project markers — requirements.txt,\n * pyproject.toml, setup.py. `plan` produces dependency edits against the\n * primary manifest and entrypoint edits against a Procfile when one exists.\n *\n * MVP scope:\n * - requirements.txt is the full-fidelity manifest (read / append).\n * - pyproject.toml dependencies live inside a TOML `dependencies = [...]`\n * block; we line-insert into that block when found, otherwise hold off\n * on rewriting until a successor ADR addresses TOML editing properly.\n * - Procfile lines starting with `python` get prefixed with\n * `opentelemetry-instrument`.\n *\n * Lockfiles (poetry.lock, Pipfile.lock) are never touched. After `--apply`,\n * init's summary tells the user to run `pip install -r requirements.txt`\n * (or `poetry lock && poetry install`) so they own the lockfile commit.\n */\n\nimport { promises as fs } from 'node:fs'\nimport path from 'node:path'\nimport type {\n ApplyResult,\n DependencyEdit,\n EntrypointEdit,\n EnvEdit,\n Installer,\n InstallPlan,\n} from './shared.js'\n\nconst SDK_PACKAGES = [\n { name: 'opentelemetry-distro', version: '>=0.49b0' },\n { name: 'opentelemetry-exporter-otlp', version: '>=1.28.0' },\n] as const\n\nconst OTEL_ENV: EnvEdit = {\n file: null,\n key: 'OTEL_EXPORTER_OTLP_ENDPOINT',\n value: 'http://localhost:4318',\n}\n\nasync function exists(p: string): Promise<boolean> {\n try {\n await fs.stat(p)\n return true\n } catch {\n return false\n }\n}\n\nasync function detect(serviceDir: string): Promise<boolean> {\n const markers = ['requirements.txt', 'pyproject.toml', 'setup.py']\n for (const m of markers) {\n if (await exists(path.join(serviceDir, m))) return true\n }\n return false\n}\n\n// Strip a requirements.txt line down to its lower-cased package name.\n// `flask==3.0.0` → `flask`, `Flask>=2 ; python_version>\"3.6\"` → `flask`.\nfunction reqPackageName(line: string): string {\n const stripped = line.split('#')[0]?.trim() ?? ''\n const head = stripped.split(/[\\s;]/)[0] ?? ''\n return head.replace(/[<>=!~].*$/, '').toLowerCase()\n}\n\nasync function planRequirementsTxtEdits(\n serviceDir: string,\n): Promise<{ manifest: string; missing: typeof SDK_PACKAGES[number][] } | null> {\n const file = path.join(serviceDir, 'requirements.txt')\n if (!(await exists(file))) return null\n const raw = await fs.readFile(file, 'utf8')\n const presentNames = new Set(\n raw\n .split(/\\r?\\n/)\n .map(reqPackageName)\n .filter((n) => n.length > 0),\n )\n const missing = SDK_PACKAGES.filter((p) => !presentNames.has(p.name.toLowerCase()))\n return { manifest: file, missing: [...missing] }\n}\n\nasync function planProcfileEdits(serviceDir: string): Promise<EntrypointEdit[]> {\n const procfile = path.join(serviceDir, 'Procfile')\n if (!(await exists(procfile))) return []\n const raw = await fs.readFile(procfile, 'utf8')\n const edits: EntrypointEdit[] = []\n for (const line of raw.split(/\\r?\\n/)) {\n if (line.length === 0) continue\n // Procfile lines look like `<process>: <cmd>`. Prefix the cmd when it\n // starts with python and isn't already wrapped.\n const m = line.match(/^([a-zA-Z0-9_-]+):\\s*(.+)$/)\n if (!m) continue\n const cmd = m[2]!\n if (!/^python\\b/.test(cmd)) continue\n if (cmd.startsWith('opentelemetry-instrument ')) continue\n const after = `${m[1]}: opentelemetry-instrument ${cmd}`\n edits.push({ file: procfile, before: line, after })\n }\n return edits\n}\n\nasync function plan(serviceDir: string): Promise<InstallPlan> {\n const empty: InstallPlan = {\n language: 'python',\n serviceDir,\n dependencyEdits: [],\n entrypointEdits: [],\n envEdits: [],\n }\n\n const dependencyEdits: DependencyEdit[] = []\n const reqs = await planRequirementsTxtEdits(serviceDir)\n if (reqs) {\n for (const sdk of reqs.missing) {\n dependencyEdits.push({\n file: reqs.manifest,\n kind: 'add',\n name: sdk.name,\n version: sdk.version,\n })\n }\n }\n // pyproject.toml / setup.py without requirements.txt: deferred to a\n // successor ADR. The patch will note it; apply is a no-op for those\n // manifests in the MVP.\n\n const entrypointEdits = await planProcfileEdits(serviceDir)\n\n if (dependencyEdits.length === 0 && entrypointEdits.length === 0) {\n return empty\n }\n return {\n language: 'python',\n serviceDir,\n dependencyEdits,\n entrypointEdits,\n envEdits: [OTEL_ENV],\n }\n}\n\nasync function applyRequirementsTxt(\n manifest: string,\n edits: DependencyEdit[],\n original: string,\n): Promise<void> {\n // Append missing packages on their own lines. Preserve a trailing newline.\n const newlines = edits\n .filter((e) => e.kind === 'add')\n .map((e) => `${e.name}${e.version}`)\n const trailing = original.endsWith('\\n') ? '' : '\\n'\n const next = `${original}${trailing}${newlines.join('\\n')}\\n`\n const tmp = `${manifest}.${process.pid}.${Date.now()}.tmp`\n await fs.writeFile(tmp, next, 'utf8')\n await fs.rename(tmp, manifest)\n}\n\nasync function applyProcfile(\n procfile: string,\n edits: EntrypointEdit[],\n original: string,\n): Promise<void> {\n let next = original\n for (const e of edits) {\n if (!next.includes(e.before)) continue\n next = next.replace(e.before, e.after)\n }\n const tmp = `${procfile}.${process.pid}.${Date.now()}.tmp`\n await fs.writeFile(tmp, next, 'utf8')\n await fs.rename(tmp, procfile)\n}\n\nasync function apply(installPlan: InstallPlan): Promise<ApplyResult> {\n const { serviceDir } = installPlan\n const touched = new Set<string>()\n for (const e of installPlan.dependencyEdits) touched.add(e.file)\n for (const e of installPlan.entrypointEdits) touched.add(e.file)\n if (touched.size === 0) {\n return { serviceDir, outcome: 'already-instrumented', writtenFiles: [] }\n }\n\n const originals = new Map<string, string>()\n for (const file of touched) {\n try {\n originals.set(file, await fs.readFile(file, 'utf8'))\n } catch {\n // Mutation will fail loudly below; rollback covers what did land.\n }\n }\n\n const writtenFiles: string[] = []\n try {\n for (const file of touched) {\n const raw = originals.get(file)\n if (raw === undefined) {\n throw new Error(`python installer: cannot read ${file} during apply`)\n }\n const base = path.basename(file)\n if (base === 'requirements.txt') {\n const edits = installPlan.dependencyEdits.filter((e) => e.file === file)\n if (edits.length > 0) {\n await applyRequirementsTxt(file, edits, raw)\n writtenFiles.push(file)\n }\n } else if (base === 'Procfile') {\n const edits = installPlan.entrypointEdits.filter((e) => e.file === file)\n if (edits.length > 0) {\n await applyProcfile(file, edits, raw)\n writtenFiles.push(file)\n }\n }\n // pyproject.toml / setup.py: MVP no-op as planned above.\n }\n } catch (err) {\n await rollback(installPlan, originals)\n throw err\n }\n\n return { serviceDir, outcome: 'instrumented', writtenFiles }\n}\n\nasync function rollback(\n installPlan: InstallPlan,\n originals: Map<string, string>,\n): Promise<void> {\n const restored: string[] = []\n for (const [file, raw] of originals.entries()) {\n try {\n await fs.writeFile(file, raw, 'utf8')\n restored.push(file)\n } catch {\n // Best-effort.\n }\n }\n const lines = [\n '# neat-rollback.patch',\n '',\n `# Generated after a partial apply failure in the ${installPlan.language} installer.`,\n '# Files listed below were restored to their pre-apply contents.',\n '',\n ...restored.map((f) => `restored: ${f}`),\n '',\n ]\n const rollbackPath = path.join(installPlan.serviceDir, 'neat-rollback.patch')\n await fs.writeFile(rollbackPath, lines.join('\\n'), 'utf8')\n}\n\nexport const pythonInstaller: Installer = {\n name: 'python',\n detect,\n plan,\n apply,\n}\n","/**\n * Shared types for SDK installer modules (ADR-047).\n *\n * Each language has its own installer at `installers/<language>.ts` exporting\n * a `detect / plan / apply` triple. Plans are pure data — no fs side effects\n * during planning — so `init --dry-run` can render a patch without ever\n * touching the project. `apply` runs the codemod in place.\n *\n * Step 2 (this PR) ships the interface and an empty registry. Step 3 (Node\n * installer) and step 4 (Python installer) populate it.\n */\n\n// Field names match ADR-047's documented patch shape exactly: `file`, `kind`,\n// `name`, `version`. Patches will be reviewed by humans and matched in tests\n// by name; renaming for clarity would have cost more than it bought.\n\nexport interface DependencyEdit {\n file: string\n kind: 'add' | 'remove' | 'upgrade'\n name: string\n version: string\n fromVersion?: string\n}\n\nexport interface EntrypointEdit {\n file: string\n before: string\n after: string\n}\n\nexport interface EnvEdit {\n // `null` denotes a recommendation only — the user will set the env var in\n // their orchestration layer, NEAT does not write a `.env` file.\n file: string | null\n key: string\n value: string\n}\n\n// Files the installer generates from scratch (ADR-069 §1). The generated\n// `otel-init.{js,ts}` for the Node installer rides here, along with the\n// per-package `.env.neat` (ADR-069 §4). Treated as additive writes — the\n// apply phase skips any file already present (ADR-069 §6).\nexport interface GeneratedFile {\n file: string\n contents: string\n // When true, write only if the file does not already exist. The apply\n // phase logs an `already instrumented` / `already present` notice instead\n // of overwriting (ADR-069 §6).\n skipIfExists?: boolean\n}\n\nexport interface InstallPlan {\n // Free-form language tag matching the service node's language: `'javascript'`,\n // `'python'`, …\n language: string\n // Service directory the plan targets. Absolute path.\n serviceDir: string\n dependencyEdits: DependencyEdit[]\n entrypointEdits: EntrypointEdit[]\n envEdits: EnvEdit[]\n // ADR-069 §1, §4 — generated files (otel-init, .env.neat). Optional so\n // installers that don't generate files (the Python installer at MVP) can\n // omit it.\n generatedFiles?: GeneratedFile[]\n // ADR-069 §2 — flagged when entry-point resolution found nothing.\n // The apply phase records this in the summary and skips all file writes\n // for the package.\n libOnly?: boolean\n // ADR-069 §2 — resolved entry-point path (absolute). Present when the\n // installer is going to inject the require/import. Absent for libOnly\n // packages and for the Python installer.\n entryFile?: string\n // ADR-073 §1 + ADR-074 §3 — when a framework owns its own boot, the\n // installer skips `pkg.main` injection and emits framework-native\n // instrumentation files instead. Five values today: Next.js from v0.3.8,\n // then Remix / SvelteKit / Nuxt / Astro from v0.3.9.\n framework?: 'next' | 'remix' | 'sveltekit' | 'nuxt' | 'astro'\n // v0.4.4 / issue #370 — when a JavaScript package isn't a Node service\n // (browser bundle, React Native), the installer records the runtime here\n // and writes nothing. Absent → vanilla Node default (the existing apply\n // path). Browser-side OTel support (`@opentelemetry/sdk-trace-web`) lands\n // in a future release.\n runtimeKind?: 'browser-bundle' | 'react-native' | 'bun' | 'deno' | 'cloudflare-workers' | 'electron'\n // ADR-073 §1 — Next.js' `next.config.{js,ts,mjs}` may need the\n // `experimental.instrumentationHook: true` flag set when the major\n // version is < 15. The apply phase mutates the file in place when this\n // field is set. Absent → no config mutation planned.\n nextConfigEdit?: {\n file: string\n // Reason this edit is queued — surfaces in the dry-run patch and the\n // apply summary so the operator knows why their next.config moved.\n reason: string\n }\n}\n\n// ADR-069 §9 — apply outcome per service. The CLI surfaces these counts\n// at the end of `neat init --apply`. v0.4.4 / issue #370 — two new buckets\n// for non-Node JavaScript runtimes: `browser-bundle` (Vite, esbuild-shipped\n// SPAs) and `react-native` (Expo / RN bare). The Node SDK can't run in\n// either; both buckets skip every write and surface the package in the\n// summary so the operator knows the frontend wasn't instrumented.\nexport type ApplyOutcome =\n | 'instrumented'\n | 'already-instrumented'\n | 'lib-only'\n | 'failed'\n | 'browser-bundle'\n | 'react-native'\n | 'bun'\n | 'deno'\n | 'cloudflare-workers'\n | 'electron'\n\nexport interface ApplyResult {\n serviceDir: string\n outcome: ApplyOutcome\n // Free-form reason string for `lib-only` / `failed` outcomes. Surfaced\n // in the CLI summary so the user knows why a package was skipped.\n reason?: string\n // Absolute paths the apply phase actually wrote to. Used by the contract\n // test that asserts the allowed-path-set restriction (ADR-069 §7).\n writtenFiles: string[]\n}\n\n// Plan-time inputs the orchestrator threads through (v0.4.1 — refs #339).\n// `project` is the registered project name — the routing key the daemon\n// owns. When present the installer writes it as `OTEL_SERVICE_NAME` so the\n// OTLP wire and the registry agree end-to-end. Absent → installers fall\n// back to a package-local default for ad-hoc / test usage.\nexport interface PlanOptions {\n project?: string\n}\n\nexport interface Installer {\n // Free-form module name. Used for the patch header and for diagnostics.\n name: string\n // Returns true if the installer thinks `serviceDir` is shaped like a project\n // it can instrument. Cheap; no fs writes.\n detect(serviceDir: string): boolean | Promise<boolean>\n // Builds an `InstallPlan` describing the edits the installer would make.\n // Pure data; no fs writes. An empty plan (every edits array empty) means\n // the SDK is already installed and there is nothing to do.\n plan(serviceDir: string, opts?: PlanOptions): InstallPlan | Promise<InstallPlan>\n // Apply a previously-produced plan. Mutates files in place. On failure,\n // produces `<serviceDir>/neat-rollback.patch` per ADR-047 #7. Returns a\n // structured outcome so the CLI can surface coverage (ADR-069 §9).\n apply(plan: InstallPlan): Promise<ApplyResult>\n}\n\nexport function isEmptyPlan(plan: InstallPlan): boolean {\n return (\n plan.dependencyEdits.length === 0 &&\n plan.entrypointEdits.length === 0 &&\n plan.envEdits.length === 0 &&\n (plan.generatedFiles?.length ?? 0) === 0 &&\n plan.nextConfigEdit === undefined\n )\n}\n","/**\n * Installer registry. v0.2.5 step 2 ships the scaffolding; the JavaScript\n * installer (step 3) and Python installer (step 4) populate `INSTALLERS`.\n */\n\nimport type { Installer, InstallPlan } from './shared.js'\nimport { javascriptInstaller } from './javascript.js'\nimport { pythonInstaller } from './python.js'\nexport { isEmptyPlan } from './shared.js'\nexport { javascriptInstaller } from './javascript.js'\nexport { pythonInstaller } from './python.js'\nexport type {\n ApplyOutcome,\n ApplyResult,\n DependencyEdit,\n EntrypointEdit,\n EnvEdit,\n GeneratedFile,\n Installer,\n InstallPlan,\n} from './shared.js'\n\n// Lockfile basenames installers must never write to (ADR-047 — \"lockfiles\n// never touched\"). Used by the patch renderer's safety check below.\nexport const FORBIDDEN_LOCKFILES: ReadonlySet<string> = new Set([\n 'package-lock.json',\n 'pnpm-lock.yaml',\n 'yarn.lock',\n 'poetry.lock',\n 'Pipfile.lock',\n 'Gemfile.lock',\n 'Cargo.lock',\n 'go.sum',\n])\n\n// Order is priority — first match wins per service. JavaScript leads because\n// it's the most common shape in the projects NEAT targets; Python follows.\nexport const INSTALLERS: Installer[] = [javascriptInstaller, pythonInstaller]\n\n/**\n * Resolve the first installer that claims a given service directory. Returns\n * `null` if none match.\n *\n * Per language, the first matching installer wins. Order in `INSTALLERS`\n * defines that priority — declarations are explicit, not alphabetical.\n */\nexport async function pickInstaller(serviceDir: string): Promise<Installer | null> {\n for (const inst of INSTALLERS) {\n if (await inst.detect(serviceDir)) return inst\n }\n return null\n}\n\nexport interface PatchSection {\n installer: string\n plan: InstallPlan\n}\n\n/**\n * Render install plans into a single review-friendly text patch. The format\n * is intentionally human-shaped, not unified-diff: agents and humans both\n * read this. Determinism — same input, byte-identical output — is the\n * load-bearing property (ADR-047 #6).\n */\nexport function renderPatch(sections: PatchSection[]): string {\n if (sections.length === 0) {\n return [\n '# neat install plan',\n '',\n 'No SDK installers matched the discovered services. Two reasons this',\n 'normally happens:',\n ' - the project uses a language NEAT does not yet instrument',\n ' (Java / Ruby / .NET / Go / Rust are out of MVP scope per ADR-047);',\n ' - the SDK is already installed, so the installer returned an empty',\n ' plan.',\n '',\n 'You can re-run `neat init --apply` later to pick up new services.',\n '',\n ].join('\\n')\n }\n\n const lines: string[] = ['# neat install plan', '']\n for (const section of sections) {\n const { installer, plan } = section\n lines.push(`## ${installer} (${plan.language}) — ${plan.serviceDir}`)\n lines.push('')\n\n if (plan.libOnly) {\n lines.push('### skipped — no resolvable entry point (lib-only)')\n lines.push('')\n continue\n }\n\n if (plan.entryFile) {\n lines.push(`entry: ${plan.entryFile}`)\n lines.push('')\n }\n\n if (plan.dependencyEdits.length > 0) {\n lines.push('### dependencies')\n // Group by manifest file so each section names the path the apply phase\n // will write, satisfying the dry-run/apply path-parity contract\n // (ADR-069 §8).\n const byFile = new Map<string, typeof plan.dependencyEdits>()\n for (const dep of plan.dependencyEdits) {\n // Hard-fail rather than render a patch that could mislead the user\n // into thinking NEAT touches lockfiles.\n const base = dep.file.split(/[\\\\/]/).pop() ?? dep.file\n if (FORBIDDEN_LOCKFILES.has(base)) {\n throw new Error(\n `installer \"${installer}\" produced a dependency edit against a lockfile (${dep.file}); ` +\n `lockfiles must never be touched (ADR-047).`,\n )\n }\n const existing = byFile.get(dep.file) ?? []\n existing.push(dep)\n byFile.set(dep.file, existing)\n }\n for (const [file, deps] of byFile) {\n lines.push(`--- ${file}`)\n for (const dep of deps) {\n lines.push(`+ \"${dep.name}\": \"${dep.version}\"`)\n }\n }\n lines.push('')\n }\n\n if (plan.generatedFiles && plan.generatedFiles.length > 0) {\n lines.push('### generated files')\n for (const gen of plan.generatedFiles) {\n lines.push(`--- (new file) ${gen.file}`)\n for (const ln of gen.contents.split(/\\r?\\n/)) {\n lines.push(`+ ${ln}`)\n }\n }\n lines.push('')\n }\n\n if (plan.entrypointEdits.length > 0) {\n lines.push('### entry-point injection')\n for (const e of plan.entrypointEdits) {\n lines.push(`--- ${e.file}`)\n lines.push(`+ ${e.after}`)\n lines.push(` ${e.before}`)\n }\n lines.push('')\n }\n\n if (plan.envEdits.length > 0) {\n lines.push('### env (written to <package-dir>/.env.neat)')\n for (const env of plan.envEdits) {\n lines.push(`- ${env.key}=${env.value}`)\n }\n lines.push('')\n }\n\n // ADR-073 §1 — surface the next.config edit in the dry-run patch so the\n // operator can review the framework-flag change before it lands.\n if (plan.nextConfigEdit) {\n lines.push('### next.config (framework flag)')\n lines.push(`--- ${plan.nextConfigEdit.file}`)\n lines.push(`+ experimental: { instrumentationHook: true }, // ${plan.nextConfigEdit.reason}`)\n lines.push('')\n }\n }\n return lines.join('\\n')\n}\n","/**\n * One-command orchestrator (ADR-073 §1).\n *\n * Bare `neat <path>` dispatches here when the first positional argument\n * resolves to a directory and doesn't match a registered verb. Six steps,\n * in order:\n *\n * 1. Discovery + extraction (per static-extraction contract).\n * 2. `.gitignore` automation (ADR-073 §6) + project registration.\n * 3. SDK install apply — patches manifests + writes otel-init + writes\n * `.env.neat`. Default yes; `--no-instrument` opts out.\n * 4. Daemon spawn — `neatd start --detach` if no daemon is running.\n * Polls `/health` up to 15s for readiness.\n * 5. Browser open against the web UI on port 6328 (T9 NEAT).\n * Default yes; `--no-open` and headless runs skip the launch.\n * 6. Summary block — value-forward findings + OTel env-vars block.\n *\n * `neat init` retains its patch-by-default contract (ADR-046 §5). The\n * orchestrator runs apply unconditionally because the bare-`<path>` shape's\n * user intent is \"make this work end-to-end.\"\n */\n\nimport { promises as fs } from 'node:fs'\nimport http from 'node:http'\nimport net from 'node:net'\nimport path from 'node:path'\nimport { spawn } from 'node:child_process'\nimport readline from 'node:readline'\nimport type { GraphEdge, GraphNode } from '@neat.is/types'\nimport { DEFAULT_PROJECT, getGraph, resetGraph } from './graph.js'\nimport { extractFromDirectory } from './extract.js'\nimport { discoverServices } from './extract/services.js'\nimport { ensureNeatOutIgnored } from './gitignore.js'\nimport { saveGraphToDisk } from './persist.js'\nimport { pathsForProject } from './projects.js'\nimport { addProject, listProjects, ProjectNameCollisionError, setStatus } from './registry.js'\nimport { readDaemonRecord, resolveHost, type DaemonPorts } from './daemon.js'\nimport { printBanner } from './banner.js'\nimport {\n isEmptyPlan,\n pickInstaller,\n type InstallPlan,\n} from './installers/index.js'\nimport { appFrameworkDependencies, uninstrumentedLibraries } from './installers/javascript.js'\nimport {\n detectPackageManager,\n runPackageManagerInstall,\n type PackageManager,\n type PackageManagerInvocation,\n} from './installers/package-manager.js'\n\nexport interface OrchestratorOptions {\n scanPath: string\n // Project name resolution mirrors `neat init` — basename of the scan\n // path unless overridden via --project.\n project: string\n projectExplicit: boolean\n // Skip step 3 (SDK install apply).\n noInstrument: boolean\n // Skip step 5 (browser open).\n noOpen: boolean\n // Skip the interactive prompt (CI invocation flag — implied when\n // stdin/stdout aren't a TTY).\n yes: boolean\n // Dashboard URL — defaults to http://localhost:6328 (T9 NEAT, ADR-059).\n dashboardUrl?: string\n // Health-check timeout in ms. Default 15s.\n daemonReadyTimeoutMs?: number\n}\n\nexport interface OrchestratorResult {\n exitCode: number\n // High-level step-by-step status for the test surface.\n steps: {\n discovery: { services: number; languages: string[] }\n extraction: { nodesAdded: number; edgesAdded: number }\n gitignore: 'added' | 'created' | 'unchanged'\n apply: {\n instrumented: number\n alreadyInstrumented: number\n libOnly: number\n skipped: boolean\n bun?: number\n deno?: number\n cloudflareWorkers?: number\n electron?: number\n // Issue #381 — package-manager invocations the orchestrator ran\n // after apply() mutated package.json. Absent for `--no-instrument`\n // runs and runs where every plan was empty.\n packageManagerInstalls?: PackageManagerInvocation[]\n }\n daemon: 'spawned' | 'already-running' | 'timed-out' | 'skipped'\n browser: 'opened' | 'skipped' | 'failed'\n }\n}\n\n// Shared sub-pipeline `neat sync` re-uses (ADR-074 §1). Discovery + extract\n// + snapshot write. Distinct from the first-run-only steps (registry add,\n// daemon spawn, browser open, summary block) that the orchestrator owns\n// directly.\nexport interface ExtractAndPersistOptions {\n scanPath: string\n project: string\n projectExplicit: boolean\n // When true, skip persisting to disk — for `neat sync --dry-run`.\n dryRun?: boolean\n}\n\nexport interface ExtractAndPersistResult {\n graph: ReturnType<typeof getGraph>\n graphKey: string\n services: Awaited<ReturnType<typeof discoverServices>>\n languages: string[]\n nodesAdded: number\n edgesAdded: number\n snapshotPath: string\n errorsPath: string\n}\n\nexport async function extractAndPersist(\n opts: ExtractAndPersistOptions,\n): Promise<ExtractAndPersistResult> {\n const services = await discoverServices(opts.scanPath)\n const languages = [...new Set(services.map((s) => s.node.language))].sort()\n\n const graphKey = opts.projectExplicit ? opts.project : DEFAULT_PROJECT\n resetGraph(graphKey)\n const graph = getGraph(graphKey)\n const projectPaths = pathsForProject(graphKey, path.join(opts.scanPath, 'neat-out'))\n const extraction = await extractFromDirectory(graph, opts.scanPath, {\n errorsPath: projectPaths.errorsPath,\n })\n if (!opts.dryRun) {\n await saveGraphToDisk(graph, projectPaths.snapshotPath)\n }\n return {\n graph,\n graphKey,\n services,\n languages,\n nodesAdded: extraction.nodesAdded,\n edgesAdded: extraction.edgesAdded,\n snapshotPath: projectPaths.snapshotPath,\n errorsPath: projectPaths.errorsPath,\n }\n}\n\n// SDK-install apply over a discovered service list. Returns the same shape\n// the orchestrator's result.steps.apply uses so callers (orchestrator + sync)\n// share the rollup logic. v0.4.1 / refs #339 — `project` is threaded through\n// to the installer so the per-package `.env.neat` carries\n// `OTEL_SERVICE_NAME=<project>`, matching the daemon's routing key.\nexport interface ApplyInstallersTally {\n instrumented: number\n alreadyInstrumented: number\n libOnly: number\n browserBundle: number\n reactNative: number\n // Issues #389 #390 — BYO-OTel out-of-scope runtime counters.\n bun: number\n deno: number\n cloudflareWorkers: number\n electron: number\n // Issue #381 — package-manager invocations the orchestrator ran after\n // apply() mutated package.json. One entry per distinct lockfile-owning\n // directory (monorepos share a single install run regardless of how\n // many sub-packages got instrumented). Empty when nothing was added to\n // any package.json.\n packageManagerInstalls: PackageManagerInvocation[]\n}\n\n// Knobs the test surface uses to swap the real spawn for a no-op. Default\n// uses the real installer; the contract suite passes a stub so the wiring\n// can be asserted without spawning npm against an unreliable registry.\nexport interface ApplyInstallersOptions {\n runInstall?: (cmd: { pm: PackageManager; cwd: string; args: string[] }) => Promise<PackageManagerInvocation>\n resolveManager?: (serviceDir: string) => Promise<{ pm: PackageManager; cwd: string; args: string[] }>\n}\n\nexport async function applyInstallersOver(\n services: Awaited<ReturnType<typeof discoverServices>>,\n project: string,\n options: ApplyInstallersOptions = {},\n): Promise<ApplyInstallersTally> {\n const resolveManager = options.resolveManager ?? detectPackageManager\n const runInstall = options.runInstall ?? runPackageManagerInstall\n let instrumented = 0\n let already = 0\n let libOnly = 0\n let browserBundle = 0\n let reactNative = 0\n let bun = 0\n let deno = 0\n let cloudflareWorkers = 0\n let electron = 0\n // Distinct install commands keyed by `<pm>:<cwd>` so a monorepo with\n // multiple instrumented sub-packages still runs install exactly once at\n // its workspace root. The first plan that landed a dep edit for a given\n // root wins; later sub-packages skip the re-run.\n const installPlans = new Map<string, { pm: PackageManager; cwd: string; args: string[] }>()\n for (const svc of services) {\n const installer = await pickInstaller(svc.dir)\n if (!installer) continue\n const plan: InstallPlan = await installer.plan(svc.dir, { project })\n if (isEmptyPlan(plan) && !plan.libOnly && plan.runtimeKind === undefined) {\n already++\n continue\n }\n const outcome = await installer.apply(plan)\n if (outcome.outcome === 'instrumented') {\n instrumented++\n // Schedule an install whenever apply() actually added deps. The\n // generated otel-init file lives under the service dir but the\n // packages the user must resolve at runtime (`@opentelemetry/sdk-node`,\n // `@prisma/instrumentation`) live in package.json — without the\n // install, the next `npm run dev` throws `Cannot find module ...`\n // before any of NEAT's code even loads.\n if (plan.dependencyEdits.length > 0) {\n const cmd = await resolveManager(svc.dir)\n const key = `${cmd.pm}:${cmd.cwd}`\n if (!installPlans.has(key)) installPlans.set(key, cmd)\n }\n } else if (outcome.outcome === 'already-instrumented') already++\n else if (outcome.outcome === 'lib-only') {\n libOnly++\n // Issue #545 / #570 — a lib-only package that carries a web-framework or\n // background-worker dependency is almost certainly a runnable app whose\n // entry the installer couldn't find, not a true library. Left in the\n // `lib-only N` tally it's silent; the runtime layer never engages and the\n // user has no idea why. Name the dependency we found and the recovery path\n // loudly. A genuine library with no app signal stays quiet — there's\n // nothing for its runtime layer to engage.\n const appDeps = svc.pkg ? appFrameworkDependencies(svc.pkg) : []\n if (appDeps.length > 0) {\n const svcName = path.basename(svc.dir)\n const list = appDeps.join(', ')\n console.warn(\n `neat: runtime layer won't engage for ${svcName}: no entry point found.\\n` +\n ` ${svc.dir} depends on ${list} — a runnable app — but neat couldn't resolve an entry to instrument.\\n` +\n ` Add a \"start\" script to package.json, or point neat at the entry file directly.`,\n )\n }\n }\n else if (outcome.outcome === 'browser-bundle') {\n browserBundle++\n console.log(`skipping ${svc.dir}: browser bundle; browser-OTel support lands in a future release.`)\n } else if (outcome.outcome === 'react-native') {\n reactNative++\n const svcName = path.basename(svc.dir)\n console.log(\n `neat: ${svc.dir} detected as React Native / Expo\\n` +\n ` The installer doesn't cover this runtime deterministically.\\n` +\n ` Configure your OTel binding to send spans to:\\n` +\n ` http://localhost:4318/projects/${project}/v1/traces\\n` +\n ` Set OTEL_SERVICE_NAME=${svcName}\\n` +\n ` See docs/installer-scope.md → \"Manual setup for out-of-scope runtimes\"`,\n )\n } else if (outcome.outcome === 'bun') {\n bun++\n const svcName = path.basename(svc.dir)\n console.log(\n `neat: ${svc.dir} detected as Bun\\n` +\n ` The installer doesn't cover this runtime deterministically.\\n` +\n ` Configure your OTel binding to send spans to:\\n` +\n ` http://localhost:4318/projects/${project}/v1/traces\\n` +\n ` Set OTEL_SERVICE_NAME=${svcName}\\n` +\n ` See docs/installer-scope.md → \"Manual setup for out-of-scope runtimes\"`,\n )\n } else if (outcome.outcome === 'deno') {\n deno++\n const svcName = path.basename(svc.dir)\n console.log(\n `neat: ${svc.dir} detected as Deno\\n` +\n ` The installer doesn't cover this runtime deterministically.\\n` +\n ` Configure your OTel binding to send spans to:\\n` +\n ` http://localhost:4318/projects/${project}/v1/traces\\n` +\n ` Set OTEL_SERVICE_NAME=${svcName}\\n` +\n ` See docs/installer-scope.md → \"Manual setup for out-of-scope runtimes\"`,\n )\n } else if (outcome.outcome === 'cloudflare-workers') {\n cloudflareWorkers++\n const svcName = path.basename(svc.dir)\n console.log(\n `neat: ${svc.dir} detected as Cloudflare Workers\\n` +\n ` The installer doesn't cover this runtime deterministically.\\n` +\n ` Configure your OTel binding to send spans to:\\n` +\n ` http://localhost:4318/projects/${project}/v1/traces\\n` +\n ` Set OTEL_SERVICE_NAME=${svcName}\\n` +\n ` See docs/installer-scope.md → \"Manual setup for out-of-scope runtimes\"`,\n )\n } else if (outcome.outcome === 'electron') {\n electron++\n const svcName = path.basename(svc.dir)\n console.log(\n `neat: ${svc.dir} detected as Electron\\n` +\n ` The installer doesn't cover this runtime deterministically.\\n` +\n ` Configure your OTel binding to send spans to:\\n` +\n ` http://localhost:4318/projects/${project}/v1/traces\\n` +\n ` Set OTEL_SERVICE_NAME=${svcName}\\n` +\n ` See docs/installer-scope.md → \"Manual setup for out-of-scope runtimes\"`,\n )\n }\n\n // Issue #546 — a service can be fully instrumented and still produce an\n // empty OBSERVED layer when it leans on a library the default\n // auto-instrumentation set doesn't cover (sqlite3 is the motivating case:\n // an in-process driver whose calls never cross an instrumented wire). The\n // differentiator goes silently empty. Name the libraries and point at the\n // extend path so the user knows why and what to do. Skip the lib-only and\n // out-of-scope buckets — there's no OBSERVED layer for them to be missing\n // from yet.\n if (svc.pkg && (outcome.outcome === 'instrumented' || outcome.outcome === 'already-instrumented')) {\n const gaps = uninstrumentedLibraries(svc.pkg)\n if (gaps.length > 0) {\n const svcName = path.basename(svc.dir)\n const list = gaps.join(', ')\n const subject = gaps.length === 1 ? 'this library' : 'these libraries'\n const aux = gaps.length === 1 ? \"isn't\" : \"aren't\"\n console.warn(\n `neat: calls to ${list} won't be observed by default in ${svcName}.\\n` +\n ` ${subject} ${aux} in the default instrumentation set, so they produce no OBSERVED edges.\\n` +\n ` Run \\`neat list-uninstrumented\\` to review them, then \\`neat extend\\` to capture them.`,\n )\n }\n }\n }\n\n // Run each distinct install command serially. Parallelism would race the\n // lockfile in the rare monorepo-of-monorepos case and most package\n // managers serialise themselves internally anyway — the time saving is\n // tiny next to the operator-trust cost of a corrupted lockfile.\n const packageManagerInstalls: PackageManagerInvocation[] = []\n for (const cmd of installPlans.values()) {\n console.log(`running \\`${cmd.pm} ${cmd.args.join(' ')}\\` in ${cmd.cwd}`)\n const result = await runInstall(cmd)\n packageManagerInstalls.push(result)\n if (result.exitCode !== 0) {\n console.error(\n `neat: ${cmd.pm} install failed in ${cmd.cwd} (exit ${result.exitCode}); run it manually to surface the error.`,\n )\n if (result.stderr.length > 0) {\n for (const line of result.stderr.split(/\\r?\\n/).slice(0, 20)) {\n console.error(` ${line}`)\n }\n }\n }\n }\n\n return {\n instrumented,\n alreadyInstrumented: already,\n libOnly,\n browserBundle,\n reactNative,\n bun,\n deno,\n cloudflareWorkers,\n electron,\n packageManagerInstalls,\n }\n}\n\nasync function promptYesNo(question: string): Promise<boolean> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout })\n return new Promise((resolve) => {\n rl.question(`${question} [Y/n] `, (answer) => {\n rl.close()\n const trimmed = answer.trim().toLowerCase()\n resolve(trimmed === '' || trimmed === 'y' || trimmed === 'yes')\n })\n })\n}\n\n// 60s covers boot + per-project graph load across a registry with several\n// sibling projects. Issue #340 — `app.listen()` now returns the moment the\n// socket binds, so the steady-state happy path lands well inside the first\n// second; the longer ceiling is the cold-clone window where multi-project\n// bootstraps run in the background after listen.\nconst DEFAULT_DAEMON_READY_TIMEOUT_MS = 60_000\n\n// 500ms poll cadence — responsive enough that the operator sees a fresh\n// status line on every transition without spamming the daemon.\nconst PROBE_INTERVAL_MS = 500\n\ninterface DaemonHealthResponse {\n ok?: boolean\n uptimeMs?: number\n projects?: Array<{\n name: string\n status?: 'bootstrapping' | 'active' | 'broken'\n elapsedMs?: number\n }>\n}\n\nasync function fetchDaemonHealth(restPort: number): Promise<DaemonHealthResponse | null> {\n return new Promise((resolve) => {\n const req = http.get(`http://127.0.0.1:${restPort}/health`, (res) => {\n const ok = res.statusCode !== undefined && res.statusCode >= 200 && res.statusCode < 300\n if (!ok) {\n res.resume()\n resolve(null)\n return\n }\n let body = ''\n res.setEncoding('utf8')\n res.on('data', (chunk: string) => { body += chunk })\n res.on('end', () => {\n try {\n resolve(JSON.parse(body) as DaemonHealthResponse)\n } catch {\n resolve({ ok: true })\n }\n })\n })\n req.on('error', () => resolve(null))\n req.setTimeout(1000, () => {\n req.destroy()\n resolve(null)\n })\n })\n}\n\n\nasync function probeProjectHealth(\n restPort: number,\n name: string,\n): Promise<'bootstrapping' | 'active' | 'broken'> {\n return new Promise((resolve) => {\n const req = http.get(\n `http://127.0.0.1:${restPort}/projects/${encodeURIComponent(name)}/health`,\n (res) => {\n const code = res.statusCode ?? 0\n res.resume()\n if (code >= 200 && code < 300) resolve('active')\n else resolve('bootstrapping')\n },\n )\n req.on('error', () => resolve('bootstrapping'))\n req.setTimeout(1000, () => {\n req.destroy()\n resolve('bootstrapping')\n })\n })\n}\n\n// Resolve the status of the one project this run just started — and only that\n// project (ADR-096: the orchestrator spawns a daemon scoped to a single\n// project, so readiness is a single-project question). A broken or stale\n// sibling sitting in the machine registry must never gate this run; it\n// belongs to a different daemon and would otherwise poison an otherwise-healthy\n// start. Prefers the daemon-wide /health entry for the project when one is\n// carried (the legacy multi-project shape); otherwise probes that project's\n// per-project /health directly. The registry is not consulted — siblings are\n// out of scope by construction.\nasync function snapshotProjectStatus(\n restPort: number,\n project: string,\n body: DaemonHealthResponse,\n): Promise<Array<{ name: string; status: 'bootstrapping' | 'active' | 'broken' }>> {\n if (body.projects && body.projects.length > 0) {\n const mine = body.projects.filter((p) => p.name === project)\n if (mine.length > 0) {\n return mine.map((p) => ({ name: p.name, status: p.status ?? 'active' }))\n }\n }\n return [{ name: project, status: await probeProjectHealth(restPort, project) }]\n}\n\ninterface DaemonReadyResult {\n ready: boolean\n brokenProjects: string[]\n stillBootstrapping: string[]\n}\n\nasync function waitForDaemonReady(\n restPort: number,\n project: string,\n timeoutMs: number,\n): Promise<DaemonReadyResult> {\n const deadline = Date.now() + timeoutMs\n let lastBootstrapping: string[] = []\n while (Date.now() < deadline) {\n const body = await fetchDaemonHealth(restPort)\n if (body !== null) {\n const projects = await snapshotProjectStatus(restPort, project, body)\n const bootstrapping = projects\n .filter((p) => p.status === 'bootstrapping')\n .map((p) => p.name)\n const broken = projects.filter((p) => p.status === 'broken').map((p) => p.name)\n if (bootstrapping.length === 0) {\n return { ready: true, brokenProjects: broken, stillBootstrapping: [] }\n }\n const key = bootstrapping.slice().sort().join(',')\n const prevKey = lastBootstrapping.slice().sort().join(',')\n if (key !== prevKey) {\n const plural = bootstrapping.length === 1 ? '' : 's'\n console.log(\n `neat: waiting on ${bootstrapping.length} project${plural}: ${bootstrapping.join(', ')}`,\n )\n lastBootstrapping = bootstrapping\n }\n }\n await new Promise((r) => setTimeout(r, PROBE_INTERVAL_MS))\n }\n const final = await fetchDaemonHealth(restPort)\n const projects = final ? await snapshotProjectStatus(restPort, project, final) : []\n return {\n ready: false,\n brokenProjects: projects.filter((p) => p.status === 'broken').map((p) => p.name),\n stillBootstrapping: projects\n .filter((p) => p.status === 'bootstrapping')\n .map((p) => p.name),\n }\n}\n\n// Port-availability probe (#377 / ADR-079 §2).\n//\n// The orchestrator's daemon-spawn step assumes `:8080` (REST), `:4318` (OTLP\n// HTTP), and `:6328` (web UI) are free. When a sibling daemon from another\n// terminal session — or any unrelated listener — is holding one of them, the\n// spawn exits 1 with no actionable message. The probe runs before\n// `spawnDaemonDetached()` and surfaces the named port plus recovery commands\n// on collision, exiting with code 3 (environmental) per the CLI exit-code\n// surface.\nexport const NEAT_PORTS = [8080, 4318, 6328] as const\n\n// Probe `host` so the availability answer reflects the interface the daemon\n// will actually bind. The daemon binds 0.0.0.0 on the authenticated path\n// (resolveHost) and 127.0.0.1 otherwise; probing loopback while the daemon\n// binds the wildcard reads a wildcard-held port as free, hands it to the\n// spawn, and the daemon dies on EADDRINUSE before it can write daemon.json —\n// the silent \"daemon.json timeout\" (#574). Check host must equal bind host.\n//\n// #580 — and the answer must span both IP families. A daemon binds one host,\n// but clients reach it through `localhost`, which resolves `::1` ahead of\n// `127.0.0.1` on macOS and other dual-stack systems. A foreign listener on the\n// IPv6 side of a port we bind only on IPv4 swallows every `localhost` query\n// while a pure-IPv4 probe still reads the port as free, so allocation hands\n// over a port that's already shadowed. We probe the bind host's family AND its\n// cross-family loopback/wildcard sibling, and call the port taken if a holder\n// sits on either. A family the machine genuinely lacks (no IPv6 stack →\n// EADDRNOTAVAIL / EAFNOSUPPORT on the sibling) is not a holder and doesn't\n// block allocation; only an EADDRINUSE on the sibling does.\ntype ProbeOutcome = 'free' | 'in-use' | 'unavailable'\n\nfunction probeBind(port: number, host: string): Promise<ProbeOutcome> {\n return new Promise((resolve) => {\n const server = net.createServer()\n server.once('error', (err) => {\n resolve((err as NodeJS.ErrnoException).code === 'EADDRINUSE' ? 'in-use' : 'unavailable')\n })\n server.once('listening', () => server.close(() => resolve('free')))\n server.listen(port, host)\n })\n}\n\n// The cross-family sibling to also probe for a shadowing holder. Loopback and\n// wildcard are the only hosts that have a meaningful sibling; a specific IP is\n// probed on its own.\nfunction crossFamilyHost(host: string): string | null {\n switch (host) {\n case '127.0.0.1':\n case 'localhost':\n return '::1'\n case '::1':\n return '127.0.0.1'\n case '0.0.0.0':\n return '::'\n case '::':\n return '0.0.0.0'\n default:\n return null\n }\n}\n\nexport async function isPortFree(port: number, host = '127.0.0.1'): Promise<boolean> {\n // Primary interface: any failure (in-use or otherwise) means we can't bind\n // it, so the port isn't usable — preserve the pre-#580 \"any error → false\".\n if ((await probeBind(port, host)) !== 'free') return false\n // Cross-family sibling: only a live holder (EADDRINUSE) counts. A missing\n // family answers 'unavailable' and is not a shadow.\n const sibling = crossFamilyHost(host)\n if (sibling && (await probeBind(port, sibling)) === 'in-use') return false\n return true\n}\n\nexport async function probePortsFree(): Promise<\n { free: true } | { free: false; held: number }\n> {\n for (const port of NEAT_PORTS) {\n if (!(await isPortFree(port))) return { free: false, held: port }\n }\n return { free: true }\n}\n\nexport function formatPortCollisionMessage(port: number): string[] {\n return [\n `neat: port ${port} is in use; the NEAT daemon needs it.`,\n ` run \\`neatd stop\\` to release the previous daemon, or`,\n ` \\`lsof -i :${port}\\` to find the holding process.`,\n ]\n}\n\n// ── Per-project port allocation (ADR-096 §3 / project-daemon contract) ──────\n//\n// One daemon per project means a second project's daemon must coexist with the\n// first rather than fight for one binding. The canonical triple\n// (8080/4318/6328) stays the first choice; when any of it is taken, allocation\n// steps to the next free triple. Each project's ports are persisted (in its\n// daemon.json, written by the daemon) and reused across restarts, so the\n// instrumented app's endpoint stays constant — critical, because the generated\n// otel-init reads `ports.otlp` back and a drifting port would silently dark the\n// OBSERVED layer (§1).\n\n// How far to step before giving up. 8 triples (8080→8101 etc.) is far more\n// concurrent projects than a laptop ever runs; past it the environment is\n// genuinely saturated and the operator wants the collision message, not an\n// ever-climbing search.\nconst PORT_ALLOCATION_ATTEMPTS = 8\n// Stride between candidate triples. Keeping rest/otlp/web on the same offset\n// keeps each project's three ports visually grouped (8080/4318/6328 →\n// 8081/4319/6329 …) so `neat ps` output reads cleanly.\nconst PORT_STRIDE = 1\n\nexport interface AllocatedPorts extends DaemonPorts {}\n\n// True when all three ports of a candidate triple are free on `host` — the\n// interface the daemon will bind (see isPortFree).\nasync function tripleFree(ports: AllocatedPorts, host = '127.0.0.1'): Promise<boolean> {\n for (const p of [ports.rest, ports.otlp, ports.web]) {\n if (!(await isPortFree(p, host))) return false\n }\n return true\n}\n\n// Allocate a free port triple, canonical 8080/4318/6328 first, stepping by\n// PORT_STRIDE to the next free triple when the canonical set is taken (a\n// sibling project's daemon already holds it). Returns null when nothing in the\n// search window is free — a genuinely saturated environment. Reuse of a\n// project's persisted ports is the caller's decision (it has the /health\n// identity result); this only finds fresh free ports.\nexport async function allocatePorts(host = '127.0.0.1'): Promise<AllocatedPorts | null> {\n const [baseRest, baseOtlp, baseWeb] = NEAT_PORTS\n for (let i = 0; i < PORT_ALLOCATION_ATTEMPTS; i++) {\n const candidate: AllocatedPorts = {\n rest: baseRest + i * PORT_STRIDE,\n otlp: baseOtlp + i * PORT_STRIDE,\n web: baseWeb + i * PORT_STRIDE,\n }\n if (await tripleFree(candidate, host)) return candidate\n }\n return null\n}\n\n// Read this project's persisted ports from its daemon.json, if any. Returns\n// null when the project has never run a daemon (fresh install) or the record\n// is malformed — the caller falls back to fresh allocation.\nexport async function persistedPortsFor(scanPath: string): Promise<AllocatedPorts | null> {\n const record = await readDaemonRecord(scanPath)\n if (!record) return null\n return { rest: record.ports.rest, otlp: record.ports.otlp, web: record.ports.web }\n}\n\n// Project-local concurrent-spawn guard (contract §1 \"exactly one daemon\").\n// Two `neat init` on the same project in the same instant would each find no\n// healthy daemon, allocate the same canonical triple, and the second daemon's\n// bind would crash on the conflict. A best-effort lockfile under the project's\n// own neat-out/ serialises them: the loser waits for the winner's daemon to\n// answer /health rather than racing it to the bind. It's project-local — no\n// machine-wide lock — so two DIFFERENT projects never contend here.\nasync function acquireSpawnLock(scanPath: string): Promise<(() => Promise<void>) | null> {\n const lockPath = path.join(scanPath, 'neat-out', 'daemon.spawn.lock')\n await fs.mkdir(path.dirname(lockPath), { recursive: true })\n const STALE_LOCK_MS = 60_000\n try {\n const fd = await fs.open(lockPath, 'wx')\n await fd.writeFile(`${process.pid}\\n`, 'utf8')\n await fd.close()\n return async () => {\n await fs.unlink(lockPath).catch(() => {})\n }\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'EEXIST') return null\n // A lock exists. If it's stale (a crashed prior spawn), reclaim it.\n try {\n const stat = await fs.stat(lockPath)\n if (Date.now() - stat.mtimeMs > STALE_LOCK_MS) {\n await fs.unlink(lockPath).catch(() => {})\n return acquireSpawnLock(scanPath)\n }\n } catch {\n // stat raced with the holder's unlink — treat as not-held and retry once.\n return acquireSpawnLock(scanPath)\n }\n return null\n }\n}\n\n// Wait (briefly) for another concurrent spawn to bring up a daemon that answers\n// /health for this project. Used by the loser of the spawn-lock race so it\n// reuses the winner's daemon instead of erroring.\nasync function waitForPeerDaemon(\n restPort: number,\n project: string,\n timeoutMs: number,\n): Promise<boolean> {\n const deadline = Date.now() + timeoutMs\n while (Date.now() < deadline) {\n if (await healthIsForProject(restPort, project)) return true\n await new Promise((r) => setTimeout(r, PROBE_INTERVAL_MS))\n }\n return healthIsForProject(restPort, project)\n}\n\n// The spawn-vs-reuse identity check (contract §7). A daemon found answering\n// /health on a candidate REST port is reused only when it reports THIS project;\n// a different project's daemon on a reused port answers with its own name and\n// is correctly treated as not-mine. Returns true only on a confirmed match.\nasync function healthIsForProject(restPort: number, project: string): Promise<boolean> {\n const body = await fetchDaemonHealth(restPort)\n if (body === null) return false\n // Single-project daemons stamp a top-level `project`; be tolerant of the\n // legacy daemon-wide shape that lists projects in an array, so a transitional\n // daemon still matches by name.\n const named = (body as { project?: string }).project\n if (typeof named === 'string') return named === project\n if (Array.isArray(body.projects)) {\n return body.projects.some((p) => p.name === project)\n }\n return false\n}\n\n// Test seam for the spawn-reuse identity check (project-daemon contract §7).\n// Production callers go through the spawn flow; the integration suite asserts\n// the matching-vs-not-mine decision directly.\nexport function healthIsForProjectForTest(restPort: number, project: string): Promise<boolean> {\n return healthIsForProject(restPort, project)\n}\n\n// Test seam for the readiness wait (one-command-cli contract §1 / ADR-096).\n// The integration suite drives a fake single-project daemon against this to\n// prove the gate scopes to the just-started project and never blocks on a\n// broken sibling sitting in the registry.\nexport function waitForDaemonReadyForTest(\n restPort: number,\n project: string,\n timeoutMs: number,\n): Promise<DaemonReadyResult> {\n return waitForDaemonReady(restPort, project, timeoutMs)\n}\n\n// Where a project's daemon writes its stdout/stderr. Lives beside the\n// snapshot under the project's own `neat-out/` so the operator finds it next\n// to everything else NEAT wrote for that project.\nexport function daemonLogPath(projectPath: string): string {\n return path.join(projectPath, 'neat-out', 'daemon.log')\n}\n\n// Spawn the daemon as a fully detached background process and hand the terminal\n// back. `detached: true` puts it in its own session and `unref()` lets the\n// orchestrator exit cleanly the moment its own work is done — the one-command\n// flow prints its summary and returns the prompt (#639/#529). The daemon's\n// stdout and stderr go to `<project>/neat-out/daemon.log`, never the caller's\n// fds: an inherited stderr keeps the shell attached and streams the daemon's\n// ongoing logs into the operator's terminal indefinitely. Startup faults (a\n// `BindAuthorityError`, a bind collision) land in that log; the caller's\n// `/health` readiness poll is what tells the operator a start failed, and\n// points them at the log for the detail.\n//\n// ADR-096 — when `spec` is given the daemon is spawned scoped to that one\n// project on the allocated ports (passed through the env neatd + startDaemon\n// read). The legacy no-arg form spawns the multi-project daemon on the\n// canonical ports; it stays so callers we haven't migrated keep working.\nexport interface DaemonSpawnSpec {\n project: string\n projectPath: string\n ports: AllocatedPorts\n}\n\nfunction spawnDaemonDetached(\n spec?: DaemonSpawnSpec,\n): import('node:child_process').ChildProcess {\n // Resolve the neatd entry inside the @neat.is/core dist next to this\n // file. `import.meta.url` is post-bundling — at runtime, this resolves\n // to `<core>/dist/neatd.{js,cjs}`. We pick the .cjs because tsup ships\n // it in both forms and node tolerates either.\n const here = path.dirname(new URL(import.meta.url).pathname)\n const candidates = [\n path.join(here, 'neatd.cjs'),\n path.join(here, 'neatd.js'),\n ]\n let entry: string | null = null\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const fsSync = require('node:fs') as typeof import('node:fs')\n for (const c of candidates) {\n try {\n fsSync.accessSync(c)\n entry = c\n break\n } catch {\n // try next\n }\n }\n if (!entry) {\n throw new Error(`orchestrator: cannot locate neatd entry in ${here}`)\n }\n\n // ADR-073 §3 + issue #341 — first-touch path is loopback-only. When the\n // operator hasn't set `NEAT_AUTH_TOKEN` the orchestrator hard-pins\n // HOST=127.0.0.1 in the child env so `assertBindAuthority` lets the bind\n // through. Public-bind is opt-in via the token (and an explicit\n // `HOST=0.0.0.0` if the operator wants the literal). The parent's HOST is\n // preserved untouched when the token is set — that's the deploy path,\n // where the platform owns the bind decision.\n const env = { ...process.env }\n const hasToken = typeof env.NEAT_AUTH_TOKEN === 'string' && env.NEAT_AUTH_TOKEN.length > 0\n if (!hasToken && (!env.HOST || env.HOST.length === 0)) {\n env.HOST = '127.0.0.1'\n }\n\n // ADR-096 — scope the spawned daemon to one project on the allocated ports.\n // neatd reads NEAT_PROJECT/NEAT_PROJECT_PATH and PORT/OTEL_PORT/NEAT_WEB_PORT\n // and threads them into startDaemon, which serves only this project and\n // writes its daemon.json self-description with these ports.\n if (spec) {\n env.NEAT_PROJECT = spec.project\n env.NEAT_PROJECT_PATH = spec.projectPath\n env.PORT = String(spec.ports.rest)\n env.OTEL_PORT = String(spec.ports.otlp)\n env.NEAT_WEB_PORT = String(spec.ports.web)\n }\n\n // Redirect the daemon's output to a log file rather than inheriting the\n // caller's fds (#639/#529). Inherited stderr keeps the shell attached — the\n // prompt never returns and the daemon's ongoing warnings spill into the\n // operator's terminal. A per-project `neat-out/daemon.log` keeps the output\n // reachable without holding the terminal. We open once and hand the same fd\n // to stdout and stderr; the OS dups it into the child at spawn, so the parent\n // closes its copy right after. With no spec (legacy multi-project form) there\n // is no project dir to write into, so output is discarded.\n let logFd: number | null = null\n if (spec) {\n const logPath = daemonLogPath(spec.projectPath)\n fsSync.mkdirSync(path.dirname(logPath), { recursive: true })\n logFd = fsSync.openSync(logPath, 'a')\n }\n const child = spawn(process.execPath, [entry, 'start'], {\n detached: true,\n stdio: ['ignore', logFd ?? 'ignore', logFd ?? 'ignore'],\n env,\n })\n child.unref()\n if (logFd !== null) fsSync.closeSync(logFd)\n return child\n}\n\nfunction openBrowser(url: string): 'opened' | 'failed' {\n // Skip when running headlessly; we don't want CI invocations to fail\n // because xdg-open isn't installed.\n if (!process.stdout.isTTY) return 'failed'\n const platform = process.platform\n const cmd =\n platform === 'darwin' ? 'open' :\n platform === 'win32' ? 'cmd' :\n 'xdg-open'\n const args = platform === 'win32' ? ['/c', 'start', '', url] : [url]\n try {\n const child = spawn(cmd, args, { detached: true, stdio: 'ignore' })\n child.on('error', () => {})\n child.unref()\n return 'opened'\n } catch {\n return 'failed'\n }\n}\n\nexport async function runOrchestrator(opts: OrchestratorOptions): Promise<OrchestratorResult> {\n const result: OrchestratorResult = {\n exitCode: 0,\n steps: {\n discovery: { services: 0, languages: [] },\n extraction: { nodesAdded: 0, edgesAdded: 0 },\n gitignore: 'unchanged',\n apply: { instrumented: 0, alreadyInstrumented: 0, libOnly: 0, skipped: false },\n daemon: 'skipped',\n browser: 'skipped',\n },\n }\n\n // ── Path validation ───────────────────────────────────────────────────\n const stat = await fs.stat(opts.scanPath).catch(() => null)\n if (!stat || !stat.isDirectory()) {\n console.error(`neat: ${opts.scanPath} is not a directory`)\n result.exitCode = 2\n return result\n }\n\n // ASCII banner up front — this is the one-command zero-to-graph path's\n // first impression (issue #483). Same artwork `neat init` prints, shared\n // through banner.ts so it's never duplicated.\n printBanner()\n console.log(`neat: ${opts.scanPath}`)\n console.log('')\n\n // ── Step 1: discovery, Step 2: extraction + snapshot ─────────────────\n // Shared with `neat sync` (ADR-074 §1) via extractAndPersist.\n const persisted = await extractAndPersist({\n scanPath: opts.scanPath,\n project: opts.project,\n projectExplicit: opts.projectExplicit,\n })\n const { graph, services, languages } = persisted\n result.steps.discovery = { services: services.length, languages }\n console.log(`discovered ${services.length} service(s) across ${languages.length} language(s)`)\n\n // No services means nothing to instrument and no graph worth spawning a\n // daemon for. Bail with a clear pointer instead of standing up an empty\n // daemon (issue #483) — most often the operator ran from outside their\n // project root.\n if (services.length === 0) {\n console.error(\n `neat: no services found in ${opts.scanPath} — run from inside your project root, or \\`npx neat.is <path>\\``,\n )\n result.exitCode = 2\n return result\n }\n\n // ── Confirmation prompt (default yes; --no-instrument or no-TTY skip)\n let runApply = !opts.noInstrument\n if (runApply && !opts.yes && process.stdout.isTTY && process.stdin.isTTY) {\n runApply = await promptYesNo('instrument your services and open the dashboard?')\n }\n\n result.steps.extraction = {\n nodesAdded: persisted.nodesAdded,\n edgesAdded: persisted.edgesAdded,\n }\n\n const gi = await ensureNeatOutIgnored(opts.scanPath)\n result.steps.gitignore = gi.action\n if (gi.action !== 'unchanged') {\n console.log(`${gi.action} .gitignore (neat-out/)`)\n }\n\n let currentProjectName = opts.project\n try {\n const entry = await addProject({\n name: opts.project,\n path: opts.scanPath,\n languages,\n status: 'active',\n })\n currentProjectName = entry.name\n } catch (err) {\n if (!(err instanceof ProjectNameCollisionError)) throw err\n // Same path, same name → re-init. Different path → bail with a clear\n // message so the operator can pass --project <other-name>.\n console.error(`neat: ${err.message}`)\n console.error('pass --project <other-name> to register under a different name.')\n result.exitCode = 1\n return result\n }\n\n // Narrow the active-project surface to what the operator is currently in.\n // Every other `active` entry transitions to `paused`; `broken` is left alone\n // so the daemon's broken-path handling still surfaces. `neat resume <name>`\n // brings any of them back when cross-project work is the explicit intent.\n const siblings = await listProjects()\n const paused: string[] = []\n for (const p of siblings) {\n if (p.name !== currentProjectName && p.status === 'active') {\n await setStatus(p.name, 'paused')\n paused.push(p.name)\n }\n }\n if (paused.length > 0) {\n const plural = paused.length === 1 ? '' : 's'\n console.log(\n `neat: paused ${paused.length} sibling project${plural}; run \\`neat resume <name>\\` to bring one back active.`,\n )\n }\n\n // ── Step 3: SDK install apply (default yes; --no-instrument skips) ───\n if (!runApply) {\n result.steps.apply.skipped = true\n console.log('skipped instrumentation (--no-instrument)')\n } else {\n const tally = await applyInstallersOver(services, opts.project)\n result.steps.apply = { ...tally, skipped: false }\n console.log(\n `instrumented ${tally.instrumented}, already ${tally.alreadyInstrumented}, lib-only ${tally.libOnly}`,\n )\n const failedInstalls = tally.packageManagerInstalls.filter((i) => i.exitCode !== 0)\n if (failedInstalls.length > 0) {\n result.exitCode = 1\n }\n }\n\n // ── Step 4: daemon spawn + health poll (ADR-096 per-project daemon) ──\n //\n // One daemon per project: this project either has a live daemon to reuse,\n // or we allocate ports and spawn one scoped to it. The spawn-vs-reuse\n // decision turns on the /health identity check — a daemon answering on a\n // port must report THIS project to count as ours (a sibling project's\n // daemon on a port we'd otherwise reuse is correctly seen as not-mine).\n const timeoutMs = opts.daemonReadyTimeoutMs ?? DEFAULT_DAEMON_READY_TIMEOUT_MS\n // The interface the spawned daemon will bind — 0.0.0.0 on the authenticated\n // path, 127.0.0.1 otherwise. resolveHost is the single source of that\n // decision (the daemon calls it too), so the free-port probe below checks the\n // exact interface the bind will use; a wildcard-held port must read as taken\n // on the token path or the spawn collides on EADDRINUSE (#574).\n const bindHost = resolveHost(\n {},\n typeof process.env.NEAT_AUTH_TOKEN === 'string' && process.env.NEAT_AUTH_TOKEN.length > 0,\n )\n // Ports the project used last time (its daemon.json), if any — reuse keeps\n // the instrumented app's exporter endpoint stable across restarts (§3).\n const persistedPorts = await persistedPortsFor(opts.scanPath)\n // Allocated ports the spawned daemon binds. Settled below; defaults to the\n // canonical web port so the dashboard URL has a value even on early bailouts.\n let allocated: AllocatedPorts | null = null\n\n // Already running? A daemon answering /health on the persisted REST port and\n // reporting this project is reused outright.\n if (persistedPorts && (await healthIsForProject(persistedPorts.rest, currentProjectName))) {\n result.steps.daemon = 'already-running'\n allocated = persistedPorts\n } else {\n // Decide the ports to bind. Reuse the persisted triple when its REST port\n // is free (the prior daemon is gone, so we take its ports back and the\n // app's endpoint stays put); otherwise allocate a fresh free triple,\n // stepping past the canonical set when a sibling project holds it.\n if (\n persistedPorts &&\n (await isPortFree(persistedPorts.rest, bindHost)) &&\n (await tripleFree(persistedPorts, bindHost))\n ) {\n allocated = persistedPorts\n } else {\n allocated = await allocatePorts(bindHost)\n }\n if (!allocated) {\n // The search window is saturated — surface the canonical REST port as the\n // representative collision so the operator gets the recovery hints.\n for (const line of formatPortCollisionMessage(NEAT_PORTS[0])) {\n console.error(line)\n }\n result.exitCode = 3\n return result\n }\n\n // Concurrent-spawn guard (§1). The winner spawns; a loser that couldn't\n // take the lock waits for the winner's daemon to answer /health and reuses\n // it rather than racing it into a bind conflict.\n const release = await acquireSpawnLock(opts.scanPath)\n if (!release) {\n const reused = await waitForPeerDaemon(allocated.rest, currentProjectName, timeoutMs)\n if (reused) {\n result.steps.daemon = 'already-running'\n } else {\n console.error('neat: another `neat` is spawning this project but its daemon did not come up in time')\n result.exitCode = 1\n return result\n }\n } else {\n try {\n // Re-check under the lock: a daemon the winner brought up between our\n // first probe and acquiring the lock is reused instead of double-spawned.\n if (await healthIsForProject(allocated.rest, currentProjectName)) {\n result.steps.daemon = 'already-running'\n } else {\n spawnDaemonDetached({\n project: currentProjectName,\n projectPath: opts.scanPath,\n ports: allocated,\n })\n const ready = await waitForDaemonReady(allocated.rest, currentProjectName, timeoutMs)\n result.steps.daemon = ready.ready ? 'spawned' : 'timed-out'\n if (!ready.ready) {\n console.error(`neat: daemon did not become ready within ${timeoutMs}ms`)\n if (ready.stillBootstrapping.length > 0) {\n console.error(`neat: still bootstrapping: ${ready.stillBootstrapping.join(', ')}`)\n }\n if (ready.brokenProjects.length > 0) {\n console.error(`neat: broken projects: ${ready.brokenProjects.join(', ')}`)\n }\n result.exitCode = 1\n return result\n }\n if (ready.brokenProjects.length > 0) {\n console.warn(\n `neat: ${ready.brokenProjects.length} project(s) reported broken: ${ready.brokenProjects.join(', ')}`,\n )\n }\n }\n } catch (err) {\n console.error(`neat: daemon spawn failed — ${(err as Error).message}`)\n result.exitCode = 1\n return result\n } finally {\n await release()\n }\n }\n }\n\n // ── Step 5: browser open ─────────────────────────────────────────────\n // The dashboard lives on the daemon's allocated web port (§5), not a fixed\n // 6328 — a second project's daemon serves its dashboard one port over.\n const webPort = allocated?.web ?? NEAT_PORTS[2]\n const dashboardUrl = opts.dashboardUrl ?? `http://localhost:${webPort}`\n if (opts.noOpen || !process.stdout.isTTY) {\n result.steps.browser = 'skipped'\n } else {\n result.steps.browser = openBrowser(dashboardUrl)\n }\n\n // ── Step 6: summary + onboarding signpost ────────────────────────────\n // The daemon runs in the background writing to its own log; point the\n // operator at it and at the honest next step (run their own app/tests).\n const daemonRunning =\n result.steps.daemon === 'spawned' || result.steps.daemon === 'already-running'\n // Show the log path relative to the project root — the summary already\n // printed the project path up top, so `neat-out/daemon.log` reads cleanly\n // and matches what the operator sees on disk.\n const daemonLog = daemonRunning\n ? path.relative(opts.scanPath, daemonLogPath(opts.scanPath))\n : null\n printSummary(result, graph, dashboardUrl, daemonLog)\n\n return result\n}\n\nfunction printSummary(\n result: OrchestratorResult,\n graph: ReturnType<typeof getGraph>,\n dashboardUrl: string,\n daemonLog: string | null,\n): void {\n const nodes: GraphNode[] = []\n graph.forEachNode((_id, attrs) => nodes.push(attrs))\n const edges: GraphEdge[] = []\n graph.forEachEdge((_id, attrs) => edges.push(attrs))\n\n const byNode = new Map<string, number>()\n for (const n of nodes) byNode.set(n.type, (byNode.get(n.type) ?? 0) + 1)\n const byEdge = new Map<string, number>()\n for (const e of edges) byEdge.set(e.type, (byEdge.get(e.type) ?? 0) + 1)\n\n console.log('')\n console.log('=== summary ===')\n console.log(`graph: ${graph.order} nodes, ${graph.size} edges`)\n for (const [t, c] of [...byNode.entries()].sort()) console.log(` ${t}: ${c}`)\n for (const [t, c] of [...byEdge.entries()].sort()) console.log(` ${t}: ${c}`)\n console.log('')\n console.log(`dashboard: ${dashboardUrl}`)\n // Be honest about the auth posture (issue #483). The bare first-touch path\n // pins the daemon to loopback with no token (see spawnDaemonDetached), so\n // there's nothing to log in with. When the operator has set\n // NEAT_AUTH_TOKEN, the daemon enforces it and the user needs it to reach\n // the dashboard and to route OTel — so we print the real value rather than\n // fabricating one the daemon wouldn't accept.\n const token = process.env.NEAT_AUTH_TOKEN\n if (typeof token === 'string' && token.length > 0) {\n console.log(`auth token: ${token}`)\n } else {\n console.log('running locally — open the dashboard, no token needed')\n }\n\n // Onboarding signpost — the one-command flow returns here, so the last thing\n // the operator reads has to tell them the daemon is up (and where its log is)\n // and what to do next. The honest next step is to run their own app or test\n // suite: the graph fills its OBSERVED layer as their code executes, and\n // divergences surface where code and runtime disagree. Never suggest\n // synthetic traffic — the point is what their real system does.\n if (daemonLog !== null) {\n console.log('')\n console.log(`daemon running in the background (logs: ${daemonLog})`)\n console.log(\n 'next: run your app or your test suite — OBSERVED edges fill in as it executes,',\n )\n console.log(' and divergences surface where code and runtime disagree.')\n }\n}\n","// `neat connector add/list/remove/test` — the write side of the ADR-130\n// on-ramp (docs/contracts/connector-config.md §3). The daemon-read chain\n// (#730) already turns a `~/.neat/connectors.json` entry into a running poll\n// loop; this is the command a human actually touches to put an entry there.\n//\n// Everything provider-specific is dispatched through the registry table\n// (connectors/registry.ts §5) — the required-field schema this prompts for and\n// the auth round-trip `add`/`test` run both come from the entry, so no per-\n// provider branch lives here. The two security non-negotiables the contract\n// names ride through this module: validate-on-add by default (the credential\n// is proven against the provider before it's written), and env-ref-by-default /\n// `0600` / never-a-resolved-secret-on-screen (the write helpers in\n// connectors-config.ts own the file mode; this module only ever prints the\n// redacted pointer, never a resolved value).\n//\n// Handlers take their filesystem home, environment, `fetch`, prompt, and output\n// streams as injected deps so the whole surface is testable against a temp home\n// and a stubbed provider — no live account, no real `~/.neat`.\n\nimport readline from 'node:readline'\nimport {\n autoSlugConnectorId,\n describeCredential,\n isEnvRef,\n readConnectorsConfig,\n removeConnectorEntry,\n upsertConnectorEntry,\n type ConnectorEntry,\n type CredentialRef,\n} from './connectors-config.js'\nimport {\n getProviderDispatch,\n PROVIDER_DISPATCH,\n validateConnectorEntry,\n type ProviderDispatch,\n type ValidateOutcome,\n} from './connectors/registry.js'\n\n// ── deps / injection ──────────────────────────────────────────────────────\n\nexport interface ConnectorCliDeps {\n // NEAT_HOME override. Undefined uses connectors-config.ts's own env-based\n // resolution (the real CLI); tests pass a temp home.\n home?: string\n env?: NodeJS.ProcessEnv\n // Test seam for the provider auth round-trip (contract §4). Undefined → the\n // junction's real `fetch`.\n fetchImpl?: typeof fetch\n // Interactive prompt. Undefined → a readline prompt that returns '' when\n // stdin isn't a TTY, so CI never hangs waiting on input.\n prompt?: (question: string) => Promise<string>\n // Whether to prompt at all for missing fields. Undefined → `process.stdin`\n // is a TTY. Non-interactive runs require every field as a flag.\n interactive?: boolean\n out?: (line: string) => void\n err?: (line: string) => void\n}\n\ninterface ResolvedDeps {\n home: string | undefined\n env: NodeJS.ProcessEnv\n fetchImpl?: typeof fetch\n prompt: (question: string) => Promise<string>\n interactive: boolean\n out: (line: string) => void\n err: (line: string) => void\n}\n\nasync function defaultPrompt(question: string): Promise<string> {\n if (!process.stdin.isTTY) return ''\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout })\n try {\n return await new Promise<string>((resolve) => rl.question(`${question} `, resolve))\n } finally {\n rl.close()\n }\n}\n\nfunction resolveDeps(deps: ConnectorCliDeps): ResolvedDeps {\n return {\n home: deps.home,\n env: deps.env ?? process.env,\n ...(deps.fetchImpl ? { fetchImpl: deps.fetchImpl } : {}),\n prompt: deps.prompt ?? defaultPrompt,\n interactive: deps.interactive ?? Boolean(process.stdin.isTTY),\n out: deps.out ?? ((l) => console.log(l)),\n err: deps.err ?? ((l) => console.error(l)),\n }\n}\n\n// ── argument parsing ──────────────────────────────────────────────────────\n\nexport interface ConnectorArgs {\n subcommand: string\n positional: string[]\n project?: string\n // Single-field credential from --credential / --token (an env-ref or a\n // literal). Multi-field providers read their fields from `fields` instead.\n credential?: string\n id?: string\n skipValidate: boolean\n plaintext: boolean\n // Provider-specific option/credential fields, camelCased from their kebab\n // flag (`--account-id` → accountId). Object-valued flags (`--workers '{…}'`)\n // are JSON-parsed; `*Ms` flags are numbered; everything else stays a string.\n fields: Record<string, unknown>\n}\n\nfunction kebabToCamel(name: string): string {\n return name.replace(/-([a-z0-9])/g, (_, c: string) => c.toUpperCase())\n}\n\nfunction coerceFieldValue(name: string, raw: string): unknown {\n const t = raw.trim()\n if (t.startsWith('{') || t.startsWith('[')) {\n try {\n return JSON.parse(t)\n } catch {\n return raw\n }\n }\n // Only numeric-shaped option names become numbers, so string ids that happen\n // to be all-digits (rare, but possible) are never silently retyped.\n if (/Ms$/.test(name) && /^\\d+$/.test(t)) return Number(t)\n return raw\n}\n\nexport function parseConnectorArgs(\n args: string[],\n): { ok: true; value: ConnectorArgs } | { ok: false; error: string } {\n const out: ConnectorArgs = {\n subcommand: '',\n positional: [],\n skipValidate: false,\n plaintext: false,\n fields: {},\n }\n const positional: string[] = []\n for (let i = 0; i < args.length; i++) {\n const arg = args[i] as string\n if (arg === '--skip-validate') {\n out.skipValidate = true\n continue\n }\n if (arg === '--plaintext') {\n out.plaintext = true\n continue\n }\n if (arg.startsWith('--')) {\n let flag = arg\n let value: string | undefined\n const eq = arg.indexOf('=')\n if (eq >= 0) {\n flag = arg.slice(0, eq)\n value = arg.slice(eq + 1)\n } else {\n const next = args[i + 1]\n if (next === undefined || next.startsWith('--')) {\n return { ok: false, error: `${flag} requires a value` }\n }\n value = next\n i++\n }\n const name = flag.slice(2)\n if (name === 'project') {\n out.project = value\n continue\n }\n if (name === 'credential' || name === 'token') {\n out.credential = value\n continue\n }\n if (name === 'id') {\n out.id = value\n continue\n }\n const field = kebabToCamel(name)\n out.fields[field] = coerceFieldValue(field, value)\n continue\n }\n positional.push(arg)\n }\n out.subcommand = positional[0] ?? ''\n out.positional = positional.slice(1)\n return { ok: true, value: out }\n}\n\n// ── credential assembly ───────────────────────────────────────────────────\n\n// Build the credential ref from flags + prompts. A single-field provider takes\n// one ref (--credential/--token or its primary key flag); a multi-field\n// provider (Firebase carries projectId + accessToken) takes one ref per\n// required field. Values are stored verbatim: a leading `$` is an env-ref\n// pointer, anything else is a literal — the exact rule the daemon resolves by,\n// so no transformation happens here.\nasync function buildCredentialRef(\n dispatch: ProviderDispatch,\n args: ConnectorArgs,\n deps: ResolvedDeps,\n): Promise<CredentialRef> {\n const hint = 'an env-var reference like $PROVIDER_TOKEN is recommended (stored as a pointer, not the secret); a literal value is stored as-is'\n if (dispatch.requiredCredentialFields.length <= 1) {\n const key = dispatch.primaryCredentialKey\n let value = args.credential\n if (value === undefined && typeof args.fields[key] === 'string') {\n value = args.fields[key] as string\n }\n if (value === undefined && deps.interactive) {\n value = await deps.prompt(`Credential for ${dispatch.provider} (${hint}):`)\n }\n return (value ?? '').trim()\n }\n const out: Record<string, string> = {}\n for (const f of dispatch.requiredCredentialFields) {\n let value: string | undefined\n if (typeof args.fields[f] === 'string') value = args.fields[f] as string\n else if (f === dispatch.primaryCredentialKey && args.credential !== undefined) value = args.credential\n if (value === undefined && deps.interactive) {\n value = await deps.prompt(`Credential field \"${f}\" for ${dispatch.provider} (${hint}):`)\n }\n out[f] = (value ?? '').trim()\n }\n return out\n}\n\n// Whether every required credential field carries a non-empty value.\nfunction credentialComplete(dispatch: ProviderDispatch, ref: CredentialRef): string[] {\n if (typeof ref === 'string') {\n return ref.length > 0 ? [] : [dispatch.primaryCredentialKey]\n }\n return dispatch.requiredCredentialFields.filter((f) => !ref[f] || ref[f].length === 0)\n}\n\n// The plaintext (non-env-ref) fields in a credential — the ones that put a\n// secret at rest and so warrant the opt-in warning.\nfunction plaintextFields(ref: CredentialRef): string[] {\n if (typeof ref === 'string') return isEnvRef(ref) ? [] : ['credential']\n return Object.entries(ref)\n .filter(([, v]) => !isEnvRef(v))\n .map(([k]) => k)\n}\n\n// ── `add` ─────────────────────────────────────────────────────────────────\n\nasync function connectorAdd(args: ConnectorArgs, deps: ResolvedDeps): Promise<number> {\n // Provider — positional or prompt. Must be a known, built provider.\n let provider = args.positional[0]\n if (!provider && deps.interactive) {\n provider = (await deps.prompt(`Provider (${Object.keys(PROVIDER_DISPATCH).sort().join(', ')}):`)).trim()\n }\n if (!provider) {\n deps.err('neat connector add: a provider is required (e.g. `neat connector add supabase`)')\n return 2\n }\n const dispatch = getProviderDispatch(provider)\n if (!dispatch) {\n deps.err(\n `neat connector add: unknown provider \"${provider}\". known providers: ${Object.keys(PROVIDER_DISPATCH).sort().join(', ')}`,\n )\n return 2\n }\n\n // Project — optional; blank binds to whatever project the daemon bootstraps.\n let project = args.project\n if (project === undefined && deps.interactive) {\n const answer = (await deps.prompt('Project (blank = the project the daemon is bootstrapping):')).trim()\n if (answer.length > 0) project = answer\n }\n\n // Credential + non-secret options.\n const credential = await buildCredentialRef(dispatch, args, deps)\n const options: Record<string, unknown> = { ...args.fields }\n // The credential fields aren't options — strip any that arrived via a\n // generic flag so they don't double-write into `options`.\n for (const k of dispatch.requiredCredentialFields) delete options[k]\n\n // Prompt for any still-missing required option field (interactive only).\n for (const field of dispatch.requiredOptionFields) {\n if (field in options) continue\n if (!deps.interactive) continue\n const answer = (await deps.prompt(`Option \"${field}\" for ${provider}:`)).trim()\n if (answer.length > 0) options[field] = coerceFieldValue(field, answer)\n }\n\n // Structural completeness — caught before any write, even under\n // --skip-validate, so an entry that can never run isn't silently stored.\n const missingCred = credentialComplete(dispatch, credential)\n if (missingCred.length > 0) {\n deps.err(\n `neat connector add: credential is incomplete — missing ${missingCred.join(', ')}. ` +\n 'Pass it as a flag (e.g. `--token $PROVIDER_TOKEN`) or run interactively.',\n )\n return 2\n }\n const missingOpts = dispatch.requiredOptionFields.filter((f) => !(f in options))\n if (missingOpts.length > 0) {\n deps.err(\n `neat connector add: missing required option(s) for ${provider}: ${missingOpts.join(', ')}. ` +\n `Pass e.g. \\`--${missingOpts[0].replace(/([A-Z])/g, '-$1').toLowerCase()} <value>\\`.`,\n )\n return 2\n }\n\n // Assemble the entry — auto-slug the id unless one was given.\n const existing = await readConnectorsConfig(deps.home)\n const existingIds = new Set(existing.connectors.map((c) => c.id))\n const id = args.id ?? autoSlugConnectorId(provider, project, existingIds)\n const entry: ConnectorEntry = {\n id,\n provider,\n ...(project ? { project } : {}),\n credential,\n ...(Object.keys(options).length > 0 ? { options } : {}),\n }\n\n // Validate-on-add by default (contract §4) — a wrong credential fails fast\n // here rather than quietly at the first poll. An unset env-ref is its own\n // distinct outcome, never conflated with a rejected token.\n if (!args.skipValidate) {\n const outcome = await validateConnectorEntry(entry, deps.env, deps.fetchImpl)\n const code = reportPreWriteValidation(outcome, deps)\n if (code !== 0) return code\n }\n\n // Plaintext is the explicit opt-in; surface it so a secret never lands at\n // rest by accident (contract §2).\n const plaintext = plaintextFields(credential)\n if (plaintext.length > 0 && !args.plaintext) {\n deps.err(\n `neat connector add: storing a literal secret at rest for ${plaintext.join(', ')} — ` +\n 'prefer an env-var reference like `$PROVIDER_TOKEN` (pass --plaintext to silence this).',\n )\n }\n\n const { replaced } = await upsertConnectorEntry(entry, deps.home)\n const verb = replaced ? 'updated' : 'added'\n const where = project ? `project \"${project}\"` : 'the bootstrapping project'\n deps.out(`${verb} connector \"${id}\" (${provider}) for ${where}.`)\n if (args.skipValidate) {\n deps.out('skipped validation (--skip-validate) — the credential is checked at the next daemon poll.')\n }\n deps.out('Restart the project\\'s daemon (or start it) to begin polling this connector.')\n return 0\n}\n\n// Turn a pre-write validation outcome into an exit code, printing the distinct\n// message each case warrants. 0 means proceed to write.\nfunction reportPreWriteValidation(outcome: ValidateOutcome, deps: ResolvedDeps): number {\n switch (outcome.status) {\n case 'ok':\n deps.out('credential validated against the provider.')\n return 0\n case 'unset-env':\n deps.err(\n `neat connector add: ${outcome.reason}. Export the variable before adding, ` +\n 'or pass --skip-validate to add now and set it before the daemon runs.',\n )\n return 1\n case 'rejected':\n deps.err(\n `neat connector add: the provider rejected the credential — ${outcome.reason}. ` +\n 'Nothing was written. Fix the credential, or pass --skip-validate to store it anyway.',\n )\n return 1\n case 'missing-field':\n deps.err(`neat connector add: ${outcome.reason}.`)\n return 2\n case 'unknown-provider':\n deps.err(`neat connector add: ${outcome.reason}.`)\n return 2\n }\n}\n\n// ── `list` ────────────────────────────────────────────────────────────────\n\nasync function connectorList(deps: ResolvedDeps, filterProject?: string): Promise<number> {\n const config = await readConnectorsConfig(deps.home)\n let entries = config.connectors\n if (filterProject) entries = entries.filter((e) => e.project === filterProject)\n if (entries.length === 0) {\n deps.out(\n filterProject\n ? `no connectors configured for project \"${filterProject}\".`\n : 'no connectors configured. run `neat connector add <provider>` to add one.',\n )\n return 0\n }\n deps.out('id\\tprovider\\tproject\\tcredential')\n for (const e of entries) {\n const project = e.project ?? '(bootstrapping project)'\n const credential = describeCredential(e.credential, deps.env)\n .map((c) => {\n const status = c.status ? ` (${c.status})` : c.kind === 'plaintext' ? ' (plaintext)' : ''\n return c.field ? `${c.field}=${c.display}${status}` : `${c.display}${status}`\n })\n .join(', ')\n deps.out(`${e.id}\\t${e.provider}\\t${project}\\t${credential}`)\n }\n return 0\n}\n\n// ── `remove` ──────────────────────────────────────────────────────────────\n\nasync function connectorRemove(deps: ResolvedDeps, id: string | undefined): Promise<number> {\n if (!id) {\n deps.err('neat connector remove: missing <id>. run `neat connector list` to see configured ids.')\n return 2\n }\n const removed = await removeConnectorEntry(id, deps.home)\n if (!removed) {\n deps.err(`neat connector remove: no connector with id \"${id}\". run \\`neat connector list\\` to see configured ids.`)\n return 1\n }\n deps.out(`removed connector \"${id}\" (${removed.provider}).`)\n return 0\n}\n\n// ── `test` ────────────────────────────────────────────────────────────────\n\nasync function connectorTest(deps: ResolvedDeps, id: string | undefined): Promise<number> {\n if (!id) {\n deps.err('neat connector test: missing <id>. run `neat connector list` to see configured ids.')\n return 2\n }\n const config = await readConnectorsConfig(deps.home)\n const entry = config.connectors.find((c) => c.id === id)\n if (!entry) {\n deps.err(`neat connector test: no connector with id \"${id}\". run \\`neat connector list\\` to see configured ids.`)\n return 1\n }\n const outcome = await validateConnectorEntry(entry, deps.env, deps.fetchImpl)\n switch (outcome.status) {\n case 'ok':\n deps.out(`ok: \"${id}\" (${entry.provider}) authenticated against the provider.`)\n return 0\n case 'unset-env':\n deps.err(`unset: \"${id}\" (${entry.provider}) — ${outcome.reason}. Export the variable so the daemon can resolve it.`)\n return 1\n case 'rejected':\n deps.err(`rejected: \"${id}\" (${entry.provider}) — ${outcome.reason}.`)\n return 1\n case 'missing-field':\n deps.err(`incomplete: \"${id}\" (${entry.provider}) — ${outcome.reason}.`)\n return 2\n case 'unknown-provider':\n deps.err(`unknown provider: \"${id}\" — ${outcome.reason}.`)\n return 2\n }\n}\n\n// ── dispatch ──────────────────────────────────────────────────────────────\n\nexport function printConnectorUsage(write: (line: string) => void): void {\n write('usage: neat connector <add|list|remove|test> [args]')\n write(' add <provider> add a connector; validates the credential first (--skip-validate to skip)')\n write(' flags: --project <name> --credential/--token <$VAR|value> --id <id>')\n write(' --<option> <value> (provider-specific) --plaintext --skip-validate')\n write(' list list configured connectors (credentials shown redacted)')\n write(' flags: --project <name>')\n write(' remove <id> remove a connector by id')\n write(' test <id> re-run the credential validation for an existing connector')\n}\n\n/**\n * Entry point the CLI wires `neat connector …` to. `rawArgs` is argv past the\n * `connector` token. Returns a process exit code; never calls `process.exit`\n * itself so the caller (and tests) own control flow.\n */\nexport async function runConnectorCommand(\n rawArgs: string[],\n deps: ConnectorCliDeps = {},\n): Promise<number> {\n const resolved = resolveDeps(deps)\n const parsed = parseConnectorArgs(rawArgs)\n if (!parsed.ok) {\n resolved.err(`neat connector: ${parsed.error}`)\n return 2\n }\n const a = parsed.value\n switch (a.subcommand) {\n case 'add':\n return connectorAdd(a, resolved)\n case 'list':\n return connectorList(resolved, a.project)\n case 'remove':\n return connectorRemove(resolved, a.positional[0])\n case 'test':\n return connectorTest(resolved, a.positional[0])\n case '':\n resolved.err('neat connector: missing subcommand.')\n printConnectorUsage(resolved.err)\n return 2\n default:\n resolved.err(`neat connector: unknown subcommand \"${a.subcommand}\".`)\n printConnectorUsage(resolved.err)\n return 2\n }\n}\n","/**\n * Lifecycle-verb implementations for the CLI. Query verbs live in\n * `cli-client.ts` next to the REST client; lifecycle verbs (currently\n * `neat sync`) live here because they orchestrate filesystem work and\n * daemon-state probes rather than wrapping a single REST endpoint.\n */\n\nimport path from 'node:path'\nimport type { RegistryEntry } from '@neat.is/types'\nimport {\n applyInstallersOver,\n extractAndPersist,\n type ExtractAndPersistResult,\n} from './orchestrator.js'\nimport { listProjects, normalizeProjectPath } from './registry.js'\nimport { saveGraphToDisk, SCHEMA_VERSION, type PersistedGraph } from './persist.js'\nimport {\n HttpError,\n pushSnapshotToRemote,\n resolveAuthToken,\n TransportError,\n} from './cli-client.js'\n\nexport interface SyncOptions {\n // Project name from `--project <name>`. When absent, sync resolves the\n // project by matching the cwd against the registered project paths.\n project?: string\n // Push the snapshot to a remote daemon URL. When absent, sync runs against\n // the local daemon on http://localhost:8080.\n to?: string\n // Bearer token for the remote daemon. Falls back to NEAT_REMOTE_TOKEN env.\n token?: string\n // Skip writing the snapshot or notifying the daemon. Mirrors `neat <path>\n // --dry-run`.\n dryRun: boolean\n // Skip the SDK install apply step.\n noInstrument: boolean\n // Emit a structured JSON payload on stdout instead of human text.\n json: boolean\n // Override the local daemon URL. Defaults to NEAT_API_URL or\n // http://localhost:8080. Useful for tests.\n daemonUrl?: string\n // Working directory the verb resolves against when `--project` isn't\n // passed. Defaults to process.cwd(); tests override.\n cwd?: string\n}\n\nexport interface SyncResult {\n exitCode: number\n // Stable shape across human / json output paths. cli.ts decides which\n // formatter to invoke based on `--json`.\n project: string\n scanPath: string\n nodesAdded: number\n edgesAdded: number\n snapshotPath: string | null\n // Tracks which branch the run took for `--json` consumers.\n mode: 'dry-run' | 'local' | 'remote'\n daemon: 'reloaded' | 'down' | 'remote-ok' | 'skipped'\n apply: {\n instrumented: number\n alreadyInstrumented: number\n libOnly: number\n skipped: boolean\n }\n // Soft warning lines surfaced to stderr in the human path. Empty when the\n // run was fully clean.\n warnings: string[]\n}\n\nasync function resolveProjectEntry(opts: SyncOptions): Promise<RegistryEntry | null> {\n const entries = await listProjects()\n if (opts.project) {\n const match = entries.find((e) => e.name === opts.project)\n return match ?? null\n }\n const cwd = opts.cwd ?? process.cwd()\n const resolvedCwd = await normalizeProjectPath(cwd)\n // Match by path: the cwd must be inside (or equal to) the registered path.\n for (const entry of entries) {\n if (\n resolvedCwd === entry.path ||\n resolvedCwd.startsWith(`${entry.path}${path.sep}`)\n ) {\n return entry\n }\n }\n return null\n}\n\nasync function checkDaemonHealth(baseUrl: string): Promise<boolean> {\n try {\n const res = await fetch(`${baseUrl.replace(/\\/$/, '')}/health`, {\n signal: AbortSignal.timeout(1500),\n })\n return res.ok\n } catch {\n return false\n }\n}\n\nfunction snapshotForGraph(persisted: ExtractAndPersistResult): PersistedGraph {\n return {\n // Stamp the live schema version the daemon validates against on the\n // receiving `/snapshot` merge. Tracking the constant keeps the push\n // aligned with the current snapshot shape across schema migrations.\n schemaVersion: SCHEMA_VERSION,\n exportedAt: new Date().toISOString(),\n graph: persisted.graph.export(),\n }\n}\n\nfunction emitResult(result: SyncResult, json: boolean): void {\n if (json) {\n process.stdout.write(JSON.stringify(result, null, 2) + '\\n')\n return\n }\n const verb =\n result.mode === 'dry-run'\n ? 'dry-run'\n : result.mode === 'remote'\n ? 'pushed'\n : 'synced'\n console.log(\n `${verb}: ${result.project} — ${result.nodesAdded} node(s) and ${result.edgesAdded} edge(s) added` +\n (result.snapshotPath ? `; snapshot at ${result.snapshotPath}` : ''),\n )\n if (!result.apply.skipped) {\n const { instrumented, alreadyInstrumented, libOnly } = result.apply\n console.log(\n `instrumented ${instrumented}, already ${alreadyInstrumented}, lib-only ${libOnly}`,\n )\n } else {\n console.log('skipped instrumentation (--no-instrument)')\n }\n for (const warn of result.warnings) console.error(warn)\n}\n\nexport async function runSync(opts: SyncOptions): Promise<SyncResult> {\n const entry = await resolveProjectEntry(opts)\n if (!entry) {\n const target = opts.project ?? opts.cwd ?? process.cwd()\n console.error(\n `neat sync: no registered project ${\n opts.project ? `named \"${opts.project}\"` : `covers ${target}`\n }. Run \\`neat <path>\\` or \\`neat init <path>\\` first.`,\n )\n return {\n exitCode: 1,\n project: opts.project ?? '',\n scanPath: target,\n nodesAdded: 0,\n edgesAdded: 0,\n snapshotPath: null,\n mode: opts.to ? 'remote' : 'local',\n daemon: 'skipped',\n apply: { instrumented: 0, alreadyInstrumented: 0, libOnly: 0, skipped: true },\n warnings: [],\n }\n }\n\n // ── Step 1 + 2: discovery + extraction (no snapshot in dry-run) ─────\n const persisted = await extractAndPersist({\n scanPath: entry.path,\n project: entry.name,\n projectExplicit: true,\n dryRun: true,\n })\n\n let snapshotPath: string | null = null\n if (!opts.dryRun) {\n const target = persisted.snapshotPath\n await saveGraphToDisk(persisted.graph, target)\n snapshotPath = target\n }\n\n // ── Step 3: SDK install apply (default yes; --dry-run + --no-instrument skip)\n const skipApply = opts.dryRun || opts.noInstrument\n const applyTally = skipApply\n ? { instrumented: 0, alreadyInstrumented: 0, libOnly: 0, browserBundle: 0, reactNative: 0 }\n : await applyInstallersOver(persisted.services, entry.name)\n\n // ── Step 4: daemon notify ────────────────────────────────────────────\n const warnings: string[] = []\n let daemonState: SyncResult['daemon'] = 'skipped'\n let exitCode = 0\n const mode: SyncResult['mode'] = opts.dryRun ? 'dry-run' : opts.to ? 'remote' : 'local'\n\n if (!opts.dryRun) {\n const snapshot = snapshotForGraph(persisted)\n if (opts.to) {\n const token = opts.token ?? process.env.NEAT_REMOTE_TOKEN\n try {\n await pushSnapshotToRemote({\n baseUrl: opts.to,\n token,\n project: entry.name,\n snapshot,\n })\n daemonState = 'remote-ok'\n } catch (err) {\n if (err instanceof HttpError) {\n console.error(`neat sync: ${err.message}`)\n exitCode = 1\n } else if (err instanceof TransportError) {\n console.error(`neat sync: ${err.message}`)\n exitCode = 3\n } else {\n console.error(`neat sync: ${(err as Error).message}`)\n exitCode = 1\n }\n daemonState = 'skipped'\n }\n } else {\n const daemonUrl =\n opts.daemonUrl ?? process.env.NEAT_API_URL ?? 'http://localhost:8080'\n const healthy = await checkDaemonHealth(daemonUrl)\n if (healthy) {\n try {\n await pushSnapshotToRemote({\n baseUrl: daemonUrl,\n token: resolveAuthToken(),\n project: entry.name,\n snapshot,\n })\n daemonState = 'reloaded'\n } catch (err) {\n warnings.push(\n `neat sync: daemon merge failed — ${(err as Error).message}. Snapshot is on disk at ${snapshotPath}.`,\n )\n daemonState = 'down'\n exitCode = 2\n }\n } else {\n warnings.push(\n 'neat sync: daemon not running; snapshot updated, run `neatd start` to serve it',\n )\n daemonState = 'down'\n exitCode = 2\n }\n }\n }\n\n const result: SyncResult = {\n exitCode,\n project: entry.name,\n scanPath: entry.path,\n nodesAdded: persisted.nodesAdded,\n edgesAdded: persisted.edgesAdded,\n snapshotPath,\n mode,\n daemon: daemonState,\n apply: { ...applyTally, skipped: skipApply },\n warnings,\n }\n\n emitResult(result, opts.json)\n return result\n}\n","// REST helper + CLI verb implementations for `neat <verb>` (ADR-050).\n//\n// The HttpClient and its createHttpClient factory are the \"shared REST helper\n// module\" the contract calls for — one endpoint surface, two consumers\n// (`packages/mcp/src/client.ts` re-exports from here, the CLI dispatcher\n// imports it directly).\n//\n// Verb handlers live alongside the client because they're tightly coupled:\n// each verb maps 1:1 to an MCP tool from ADR-039, but produces the structured\n// `{ summary, block, confidence, provenance }` shape (ADR-050 #3) in pure\n// data form. cli.ts formats that shape into either human-readable text or\n// `--json` output.\n\nimport type {\n BlastRadiusAffectedNode,\n BlastRadiusResult,\n Divergence,\n DivergenceResult,\n DivergenceType,\n ErrorEvent,\n GraphEdge,\n GraphNode,\n HypotheticalAction,\n ObservedDependenciesResult,\n PolicyViolation,\n RootCauseResult,\n TransitiveDependenciesResult,\n} from '@neat.is/types'\nimport { Provenance } from '@neat.is/types'\n\n// ──────────────────────────────────────────────────────────────────────────\n// REST client\n// ──────────────────────────────────────────────────────────────────────────\n\nexport interface HttpClient {\n get<T>(path: string): Promise<T>\n post?<T>(path: string, body: unknown): Promise<T>\n}\n\nexport class HttpError extends Error {\n constructor(\n public readonly status: number,\n message: string,\n public readonly responseBody: string = '',\n ) {\n super(message)\n this.name = 'HttpError'\n }\n}\n\n// Network-level failures (ECONNREFUSED, ETIMEDOUT, DNS) — distinct from\n// HttpError so the CLI can map them to exit code 3 (daemon-down) without\n// parsing error strings.\nexport class TransportError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'TransportError'\n }\n}\n\n// Single-source the bearer for every first-party read (ADR-073 §3). The CLI\n// query verbs, `neat sync`, the MCP server, and the snapshot push all read the\n// token from here so a new read site can't quietly skip auth. Returns\n// undefined when the env var is unset or empty — a loopback dev daemon stays\n// reachable without a token.\nexport function resolveAuthToken(env: NodeJS.ProcessEnv = process.env): string | undefined {\n const t = env.NEAT_AUTH_TOKEN\n return t && t.length > 0 ? t : undefined\n}\n\nexport function createHttpClient(baseUrl: string, bearerToken?: string): HttpClient {\n const root = baseUrl.replace(/\\/$/, '')\n const authHeader: Record<string, string> = bearerToken && bearerToken.length > 0\n ? { authorization: `Bearer ${bearerToken}` }\n : {}\n return {\n async get<T>(path: string): Promise<T> {\n let res: Response\n try {\n res = await fetch(`${root}${path}`, {\n headers: { ...authHeader },\n })\n } catch (err) {\n throw new TransportError(\n `cannot reach neat-core at ${root}: ${(err as Error).message}`,\n )\n }\n if (!res.ok) {\n const body = await res.text().catch(() => '')\n throw new HttpError(\n res.status,\n `${res.status} ${res.statusText} on GET ${path}: ${body}`,\n body,\n )\n }\n return (await res.json()) as T\n },\n async post<T>(path: string, body: unknown): Promise<T> {\n let res: Response\n try {\n res = await fetch(`${root}${path}`, {\n method: 'POST',\n headers: { 'content-type': 'application/json', ...authHeader },\n body: JSON.stringify(body),\n })\n } catch (err) {\n throw new TransportError(\n `cannot reach neat-core at ${root}: ${(err as Error).message}`,\n )\n }\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new HttpError(\n res.status,\n `${res.status} ${res.statusText} on POST ${path}: ${text}`,\n text,\n )\n }\n return (await res.json()) as T\n },\n }\n}\n\n// Project routing per ADR-050 #2: `--project <name>` (handled in cli.ts) →\n// `NEAT_PROJECT` env → `default`. The default routes hit the legacy\n// unprefixed URLs which the core resolves to project=`default`.\nfunction projectPath(project: string | undefined, suffix: string): string {\n if (!project) return suffix\n return `/projects/${encodeURIComponent(project)}${suffix}`\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Verb result shape (ADR-050 #3)\n// ──────────────────────────────────────────────────────────────────────────\n\nexport interface VerbResult {\n // NL paragraph. What was found and why it matters.\n summary: string\n // Structured payload — usually a bulleted list. Empty when the summary\n // already conveys everything.\n block?: string\n // Per-result confidence in [0, 1]. Undefined → footer reads \"n/a\".\n confidence?: number\n // Per-result provenance. String, array (mixed paths), or undefined.\n provenance?: string | string[]\n}\n\n// Common shape the nine verbs produce. cli.ts renders this to text or JSON.\n\n// ──────────────────────────────────────────────────────────────────────────\n// Verbs\n// ──────────────────────────────────────────────────────────────────────────\n\nexport interface RootCauseInput {\n errorNode: string\n errorId?: string\n project?: string\n}\n\nexport async function runRootCause(\n client: HttpClient,\n input: RootCauseInput,\n): Promise<VerbResult> {\n const qs = input.errorId ? `?errorId=${encodeURIComponent(input.errorId)}` : ''\n const path = projectPath(\n input.project,\n `/graph/root-cause/${encodeURIComponent(input.errorNode)}${qs}`,\n )\n try {\n const result = await client.get<RootCauseResult>(path)\n const arrowPath = result.traversalPath.join(' ← ')\n const provenances = result.edgeProvenances.length\n ? result.edgeProvenances.join(', ')\n : '(direct, no edges traversed)'\n const summary =\n `Root cause for ${input.errorNode} is ${result.rootCauseNode}. ` +\n result.rootCauseReason +\n (result.fixRecommendation ? ` Recommended fix: ${result.fixRecommendation}.` : '')\n const blockLines = [\n `Traversal path: ${arrowPath}`,\n `Edge provenances: ${provenances}`,\n ]\n if (result.fixRecommendation) blockLines.push(`Recommended fix: ${result.fixRecommendation}`)\n return {\n summary,\n block: blockLines.join('\\n'),\n confidence: result.confidence,\n provenance: result.edgeProvenances.length ? result.edgeProvenances : undefined,\n }\n } catch (err) {\n if (err instanceof HttpError && err.status === 404) {\n return {\n summary: `No root cause found for ${input.errorNode}. The node may be healthy, or it may not exist in the graph.`,\n }\n }\n throw err\n }\n}\n\nexport interface BlastRadiusInput {\n nodeId: string\n depth?: number\n project?: string\n}\n\nexport async function runBlastRadius(\n client: HttpClient,\n input: BlastRadiusInput,\n): Promise<VerbResult> {\n const qs = input.depth !== undefined ? `?depth=${input.depth}` : ''\n const path = projectPath(\n input.project,\n `/graph/blast-radius/${encodeURIComponent(input.nodeId)}${qs}`,\n )\n try {\n const result = await client.get<BlastRadiusResult>(path)\n if (result.totalAffected === 0) {\n return {\n summary: `${result.origin} has no dependents. Nothing else would break if it failed.`,\n }\n }\n const sorted = [...result.affectedNodes].sort(\n (a, b) => a.distance - b.distance || a.nodeId.localeCompare(b.nodeId),\n )\n const blockLines = sorted.map(formatBlastEntry)\n const minConfidence = sorted.reduce(\n (m, n) => Math.min(m, n.confidence),\n Number.POSITIVE_INFINITY,\n )\n const provenances = [...new Set(sorted.map((n) => n.edgeProvenance))]\n return {\n summary: `Blast radius for ${result.origin}: ${result.totalAffected} dependent node${result.totalAffected === 1 ? '' : 's'} would break if it changed.`,\n block: blockLines.join('\\n'),\n confidence: Number.isFinite(minConfidence) ? minConfidence : undefined,\n provenance: provenances.length ? provenances : undefined,\n }\n } catch (err) {\n if (err instanceof HttpError && err.status === 404) {\n return { summary: `Node ${input.nodeId} not found in the graph.` }\n }\n throw err\n }\n}\n\nfunction formatBlastEntry(n: BlastRadiusAffectedNode): string {\n const tag = n.edgeProvenance === Provenance.STALE ? ' [STALE — last seen too long ago]' : ''\n return ` • ${n.nodeId} (distance ${n.distance}, ${n.edgeProvenance})${tag}`\n}\n\nexport interface DependenciesInput {\n nodeId: string\n depth?: number\n project?: string\n}\n\nexport async function runDependencies(\n client: HttpClient,\n input: DependenciesInput,\n): Promise<VerbResult> {\n const depth = input.depth ?? 3\n const path = projectPath(\n input.project,\n `/graph/dependencies/${encodeURIComponent(input.nodeId)}?depth=${depth}`,\n )\n try {\n const result = await client.get<TransitiveDependenciesResult>(path)\n if (result.total === 0) {\n return {\n summary:\n depth === 1\n ? `${input.nodeId} has no direct dependencies in the graph.`\n : `${input.nodeId} has no dependencies (BFS to depth ${depth}).`,\n }\n }\n const byDistance = new Map<number, typeof result.dependencies>()\n for (const dep of result.dependencies) {\n const ring = byDistance.get(dep.distance) ?? []\n ring.push(dep)\n byDistance.set(dep.distance, ring)\n }\n const blockLines: string[] = []\n for (const distance of [...byDistance.keys()].sort((a, b) => a - b)) {\n const label = distance === 1 ? 'Direct (distance 1)' : `Distance ${distance}`\n blockLines.push(`${label}:`)\n for (const dep of byDistance.get(distance)!) {\n blockLines.push(` • ${dep.nodeId} — ${dep.edgeType} (${dep.provenance})`)\n }\n }\n const provenances = [...new Set(result.dependencies.map((d) => d.provenance))]\n const directCount = byDistance.get(1)?.length ?? 0\n const summary =\n depth === 1\n ? `${input.nodeId} has ${directCount} direct dependenc${directCount === 1 ? 'y' : 'ies'}.`\n : `${input.nodeId} has ${result.total} dependenc${result.total === 1 ? 'y' : 'ies'} reachable to depth ${depth} (${directCount} direct).`\n return { summary, block: blockLines.join('\\n'), provenance: provenances }\n } catch (err) {\n if (err instanceof HttpError && err.status === 404) {\n return { summary: `Node ${input.nodeId} not found in the graph.` }\n }\n throw err\n }\n}\n\n// Render one OBSERVED dependency. The edge is file-grained, so when its source\n// isn't the node we asked about (a service's owned file made the call) name the\n// originating file — that's the file-first answer, not a service rollup.\nfunction observedDepLine(nodeId: string, e: GraphEdge): string {\n const via = e.source !== nodeId ? ` (via ${e.source})` : ''\n return ` • ${e.target} — ${e.type}${via}${edgeMeta(e)}`\n}\n\nexport async function runObservedDependencies(\n client: HttpClient,\n input: DependenciesInput,\n): Promise<VerbResult> {\n try {\n const result = await client.get<ObservedDependenciesResult>(\n projectPath(\n input.project,\n `/graph/observed-dependencies/${encodeURIComponent(input.nodeId)}`,\n ),\n )\n if (result.dependencies.length === 0) {\n // A pure receiver — hit at runtime but calling nothing downstream — is\n // fully observed, so don't imply OTel is down. That note is honest only\n // when nothing has been observed and static deps exist.\n if (result.observed) {\n return {\n summary:\n `${input.nodeId} makes no outbound runtime calls, but OTel has observed it ` +\n `receiving traffic on ${result.inboundObservedCount} inbound call ` +\n `path${result.inboundObservedCount === 1 ? '' : 's'} — it's a pure receiver.`,\n provenance: Provenance.OBSERVED,\n }\n }\n const note = result.hasExtractedOutbound\n ? ' Static (EXTRACTED) dependencies exist but no runtime traffic has been seen — is OTel running?'\n : ''\n return { summary: `No OBSERVED dependencies for ${input.nodeId}.${note}` }\n }\n const blockLines = result.dependencies.map((e) => observedDepLine(input.nodeId, e))\n return {\n summary: `${input.nodeId} has ${result.dependencies.length} runtime dependenc${result.dependencies.length === 1 ? 'y' : 'ies'} confirmed by OTel.`,\n block: blockLines.join('\\n'),\n provenance: Provenance.OBSERVED,\n }\n } catch (err) {\n if (err instanceof HttpError && err.status === 404) {\n return { summary: `Node ${input.nodeId} not found in the graph.` }\n }\n throw err\n }\n}\n\nfunction edgeMeta(e: GraphEdge): string {\n const bits: string[] = []\n if (e.signal) {\n bits.push(`spans=${e.signal.spanCount}`)\n if (e.signal.errorCount > 0) bits.push(`errors=${e.signal.errorCount}`)\n if (e.signal.lastObservedAgeMs !== undefined) {\n bits.push(`age=${formatDuration(e.signal.lastObservedAgeMs)}`)\n }\n } else if (e.callCount !== undefined) {\n bits.push(`callCount=${e.callCount}`)\n }\n if (e.lastObserved) bits.push(`lastObserved=${e.lastObserved}`)\n if (e.confidence !== undefined) bits.push(`confidence=${e.confidence}`)\n return bits.length ? ` [${bits.join(', ')}]` : ''\n}\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${Math.round(ms)}ms`\n const s = Math.round(ms / 1000)\n if (s < 60) return `${s}s`\n const m = Math.round(s / 60)\n if (m < 60) return `${m}m`\n const h = Math.round(m / 60)\n if (h < 48) return `${h}h`\n return `${Math.round(h / 24)}d`\n}\n\nexport interface IncidentsInput {\n nodeId?: string\n limit?: number\n project?: string\n}\n\n// `neat incidents` shape: with a node id, returns that node's incidents.\n// Without one, returns the global recent log.\nexport async function runIncidents(\n client: HttpClient,\n input: IncidentsInput,\n): Promise<VerbResult> {\n const path = input.nodeId\n ? projectPath(input.project, `/incidents/${encodeURIComponent(input.nodeId)}`)\n : projectPath(input.project, '/incidents')\n try {\n const body = await client.get<{ count: number; total: number; events: ErrorEvent[] }>(path)\n const events = body.events\n if (events.length === 0) {\n return {\n summary: input.nodeId\n ? `No incidents recorded against ${input.nodeId}.`\n : 'No incidents recorded.',\n }\n }\n const ordered = [...events].reverse().slice(0, input.limit ?? 20)\n const blockLines: string[] = []\n for (const ev of ordered) {\n blockLines.push(` ${ev.timestamp} — ${ev.service}: ${ev.errorMessage}`)\n blockLines.push(` trace=${ev.traceId} span=${ev.spanId}`)\n }\n const target = input.nodeId ?? 'the project'\n return {\n summary: `${target} has ${body.total} recorded incident${body.total === 1 ? '' : 's'}; showing the ${ordered.length} most recent.`,\n block: blockLines.join('\\n'),\n provenance: Provenance.OBSERVED,\n }\n } catch (err) {\n if (err instanceof HttpError && err.status === 404) {\n return { summary: `Node ${input.nodeId ?? ''} not found in the graph.` }\n }\n throw err\n }\n}\n\nexport interface SearchInput {\n query: string\n project?: string\n}\n\ninterface SearchResponse {\n query: string\n provider?: 'ollama' | 'transformers' | 'substring'\n matches: (GraphNode & { score?: number })[]\n}\n\nexport async function runSearch(\n client: HttpClient,\n input: SearchInput,\n): Promise<VerbResult> {\n const result = await client.get<SearchResponse>(\n projectPath(input.project, `/search?q=${encodeURIComponent(input.query)}`),\n )\n if (result.matches.length === 0) {\n return { summary: `No matches for \"${input.query}\".` }\n }\n const provider = result.provider ?? 'substring'\n const blockLines: string[] = []\n let topScore: number | undefined\n for (const n of result.matches) {\n const score = provider !== 'substring' && typeof n.score === 'number' ? n.score : undefined\n const scoreBit = score !== undefined ? ` [score=${score.toFixed(2)}]` : ''\n if (score !== undefined && (topScore === undefined || score > topScore)) topScore = score\n blockLines.push(\n ` • ${n.id} (${n.type}) — ${(n as { name?: string }).name ?? n.id}${scoreBit}`,\n )\n }\n return {\n summary: `Found ${result.matches.length} match${result.matches.length === 1 ? '' : 'es'} for \"${input.query}\" via ${provider} provider.`,\n block: blockLines.join('\\n'),\n confidence: topScore,\n }\n}\n\nexport interface DiffInput {\n againstSnapshot: string\n project?: string\n}\n\ninterface GraphDiffResponse {\n base: { exportedAt?: string }\n current: { exportedAt: string }\n added: { nodes: GraphNode[]; edges: GraphEdge[] }\n removed: { nodes: GraphNode[]; edges: GraphEdge[] }\n changed: {\n nodes: { id: string; before: GraphNode; after: GraphNode }[]\n edges: { id: string; before: GraphEdge; after: GraphEdge }[]\n }\n}\n\nexport async function runDiff(client: HttpClient, input: DiffInput): Promise<VerbResult> {\n const result = await client.get<GraphDiffResponse>(\n projectPath(\n input.project,\n `/graph/diff?against=${encodeURIComponent(input.againstSnapshot)}`,\n ),\n )\n const total =\n result.added.nodes.length +\n result.added.edges.length +\n result.removed.nodes.length +\n result.removed.edges.length +\n result.changed.nodes.length +\n result.changed.edges.length\n const baseLabel = result.base.exportedAt ?? 'unknown'\n if (total === 0) {\n return {\n summary: `No differences between the current graph and ${input.againstSnapshot} (base exportedAt=${baseLabel}).`,\n }\n }\n const blockLines: string[] = [\n ` base exportedAt: ${baseLabel}`,\n ` current exportedAt: ${result.current.exportedAt}`,\n '',\n ]\n if (result.added.nodes.length || result.added.edges.length) {\n blockLines.push('Added:')\n for (const n of result.added.nodes) blockLines.push(` + node ${n.id} (${n.type})`)\n for (const e of result.added.edges)\n blockLines.push(` + edge ${e.id} — ${e.source} -> ${e.target} (${e.type}, ${e.provenance})`)\n blockLines.push('')\n }\n if (result.removed.nodes.length || result.removed.edges.length) {\n blockLines.push('Removed:')\n for (const n of result.removed.nodes) blockLines.push(` - node ${n.id} (${n.type})`)\n for (const e of result.removed.edges)\n blockLines.push(` - edge ${e.id} — ${e.source} -> ${e.target} (${e.type}, ${e.provenance})`)\n blockLines.push('')\n }\n if (result.changed.nodes.length || result.changed.edges.length) {\n blockLines.push('Changed:')\n for (const c of result.changed.nodes) {\n blockLines.push(` ~ node ${c.id} — ${summariseAttrDiff(c.before, c.after)}`)\n }\n for (const c of result.changed.edges) {\n const provBit =\n c.before.provenance !== c.after.provenance\n ? `provenance ${c.before.provenance} → ${c.after.provenance}`\n : summariseAttrDiff(c.before, c.after)\n blockLines.push(` ~ edge ${c.id} — ${provBit}`)\n }\n }\n return {\n summary: `Diff against ${input.againstSnapshot}: ${total} change${total === 1 ? '' : 's'} between the snapshot and the live graph.`,\n block: blockLines.join('\\n').trimEnd(),\n }\n}\n\nfunction summariseAttrDiff(\n before: Record<string, unknown>,\n after: Record<string, unknown>,\n): string {\n const keys = new Set([...Object.keys(before), ...Object.keys(after)])\n const changed: string[] = []\n for (const k of keys) {\n if (JSON.stringify(before[k]) !== JSON.stringify(after[k])) changed.push(k)\n }\n return changed.length === 0 ? 'attributes differ' : `fields changed: ${changed.sort().join(', ')}`\n}\n\nexport interface StaleEdgesInput {\n limit?: number\n edgeType?: string\n project?: string\n}\n\ninterface StaleEventResponse {\n edgeId: string\n source: string\n target: string\n edgeType: string\n thresholdMs: number\n ageMs: number\n lastObserved: string\n transitionedAt: string\n}\n\nexport async function runStaleEdges(\n client: HttpClient,\n input: StaleEdgesInput,\n): Promise<VerbResult> {\n const params = new URLSearchParams()\n if (input.limit !== undefined) params.set('limit', String(input.limit))\n if (input.edgeType) params.set('edgeType', input.edgeType)\n const qs = params.size > 0 ? `?${params.toString()}` : ''\n const body = await client.get<{ count: number; total: number; events: StaleEventResponse[] }>(\n projectPath(input.project, `/stale-events${qs}`),\n )\n const events = body.events\n if (events.length === 0) {\n return {\n summary: input.edgeType\n ? `No stale ${input.edgeType} edges recorded.`\n : 'No stale-edge transitions recorded yet.',\n }\n }\n const blockLines = events.map(\n (e) =>\n ` ${e.transitionedAt} — ${e.source} -[${e.edgeType}]-> ${e.target}` +\n ` (last seen ${e.lastObserved}, threshold ${formatDuration(e.thresholdMs)})`,\n )\n return {\n summary: `${events.length} stale-edge transition${events.length === 1 ? '' : 's'} recorded${input.edgeType ? ` for ${input.edgeType}` : ''}.`,\n block: blockLines.join('\\n'),\n provenance: Provenance.STALE,\n }\n}\n\nexport interface PoliciesInput {\n nodeId?: string\n policyId?: string\n hypotheticalAction?: HypotheticalAction\n project?: string\n}\n\ninterface PoliciesCheckResponse {\n allowed: boolean\n hypotheticalAction?: HypotheticalAction\n violations: PolicyViolation[]\n}\n\nexport async function runPolicies(\n client: HttpClient,\n input: PoliciesInput,\n): Promise<VerbResult> {\n let violations: PolicyViolation[]\n let allowed = true\n let hypothetical: HypotheticalAction | undefined\n\n if (input.hypotheticalAction) {\n if (typeof client.post !== 'function') {\n throw new Error('HttpClient does not support POST — required for policies dry-run')\n }\n const body = await client.post<PoliciesCheckResponse>(\n projectPath(input.project, '/policies/check'),\n { hypotheticalAction: input.hypotheticalAction },\n )\n violations = body.violations\n allowed = body.allowed\n hypothetical = body.hypotheticalAction\n } else {\n const params = new URLSearchParams()\n if (input.policyId) params.set('policyId', input.policyId)\n const qs = params.size > 0 ? `?${params.toString()}` : ''\n const body = await client.get<{ violations: PolicyViolation[] }>(\n projectPath(input.project, `/policies/violations${qs}`),\n )\n violations = body.violations\n allowed = violations.every((v) => v.onViolation !== 'block')\n }\n\n // Optional --node filter is applied here against the returned set; the\n // server-side endpoint doesn't take a node-id query yet.\n if (input.nodeId) {\n violations = violations.filter(\n (v) => v.subject.nodeId === input.nodeId || v.subject.path?.includes(input.nodeId!),\n )\n }\n\n if (violations.length === 0) {\n return {\n summary: hypothetical\n ? `No violations would result from the hypothetical action (${hypothetical.kind}).`\n : 'No policy violations recorded.',\n }\n }\n\n const blockCount = violations.filter((v) => v.onViolation === 'block').length\n const summaryParts: string[] = []\n if (hypothetical) {\n summaryParts.push(\n `Hypothetical ${hypothetical.kind} would surface ${violations.length} violation${violations.length === 1 ? '' : 's'}`,\n )\n } else {\n summaryParts.push(\n `${violations.length} policy violation${violations.length === 1 ? '' : 's'} currently recorded`,\n )\n }\n if (blockCount > 0) summaryParts.push(`${blockCount} of which block`)\n if (!allowed && hypothetical) summaryParts.push('action denied')\n const summary = summaryParts.join('; ') + '.'\n\n const blockLines = violations.map((v) => {\n const subject = v.subject.nodeId ?? v.subject.edgeId ?? v.subject.path?.[0] ?? '(global)'\n return ` • [${v.severity}/${v.onViolation}] ${v.policyName}: ${v.message} — ${subject}`\n })\n const severities = [...new Set(violations.map((v) => v.severity))]\n return {\n summary,\n block: blockLines.join('\\n'),\n confidence: hypothetical ? 0.7 : 1,\n provenance: severities.join(' '),\n }\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// divergences (ADR-060) — the tenth verb. Amends ADR-050's nine-verb\n// allowlist; the verb mirrors the get_divergences MCP tool.\n// ──────────────────────────────────────────────────────────────────────────\n\nexport interface DivergencesInput {\n type?: ReadonlyArray<DivergenceType>\n minConfidence?: number\n node?: string\n project?: string\n}\n\nfunction formatDivergenceLine(d: Divergence): string {\n switch (d.type) {\n case 'missing-observed':\n case 'missing-extracted':\n return ` • [${d.type}] ${d.source} → ${d.target} (${d.edgeType}) — confidence ${d.confidence.toFixed(2)}`\n case 'version-mismatch':\n return ` • [${d.type}] ${d.source} → ${d.target} — declared ${d.extractedVersion}, observed engine ${d.observedVersion} (${d.compatibility})`\n case 'host-mismatch':\n return ` • [${d.type}] ${d.source} → ${d.target} — declared host ${d.extractedHost}, observed host ${d.observedHost}`\n case 'compat-violation':\n return ` • [${d.type}] ${d.source} → ${d.target} — ${d.rule.kind}${d.rule.package ? ` (${d.rule.package})` : ''}`\n }\n}\n\nexport async function runDivergences(\n client: HttpClient,\n input: DivergencesInput,\n): Promise<VerbResult> {\n const params = new URLSearchParams()\n if (input.type && input.type.length > 0) params.set('type', input.type.join(','))\n if (input.minConfidence !== undefined) {\n params.set('minConfidence', String(input.minConfidence))\n }\n if (input.node) params.set('node', input.node)\n const qs = params.size > 0 ? `?${params.toString()}` : ''\n const result = await client.get<DivergenceResult>(\n projectPath(input.project, `/graph/divergences${qs}`),\n )\n if (result.totalAffected === 0) {\n return {\n summary:\n 'No divergences found between the declared (EXTRACTED) and observed (OBSERVED) views of the graph.',\n }\n }\n const headline = result.divergences[0]!\n const summary =\n `Found ${result.totalAffected} divergence${result.totalAffected === 1 ? '' : 's'} between code and production. ` +\n `Highest-confidence: ${headline.type} on ${headline.source} → ${headline.target}. ${headline.reason}`\n const blockLines: string[] = []\n for (const d of result.divergences) {\n blockLines.push(formatDivergenceLine(d))\n blockLines.push(` reason: ${d.reason}`)\n blockLines.push(` recommendation: ${d.recommendation}`)\n }\n const maxConfidence = result.divergences.reduce(\n (m, d) => Math.max(m, d.confidence),\n 0,\n )\n return {\n summary,\n block: blockLines.join('\\n'),\n confidence: maxConfidence,\n provenance: 'composite (EXTRACTED + OBSERVED)',\n }\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Output formatting (ADR-050 #3)\n// ──────────────────────────────────────────────────────────────────────────\n\nfunction formatFooter(\n confidence: number | undefined,\n provenance: string | string[] | undefined,\n): string {\n const c = confidence === undefined ? 'n/a' : confidence.toFixed(2)\n const p =\n provenance === undefined\n ? 'n/a'\n : Array.isArray(provenance)\n ? [...new Set(provenance)].join(', ')\n : provenance\n return `confidence: ${c} · provenance: ${p}`\n}\n\n// Default human output (NL summary + table-shaped block + footer). Mirrors\n// the three-part MCP response from ADR-039 in plain text.\nexport function formatHuman(result: VerbResult): string {\n const sections: string[] = [result.summary.trim()]\n if (result.block && result.block.trim().length > 0) sections.push(result.block.trimEnd())\n sections.push(formatFooter(result.confidence, result.provenance))\n return sections.join('\\n\\n')\n}\n\n// `--json` output. Same three sections as named fields per ADR-050 #3.\nexport function formatJson(result: VerbResult): string {\n return JSON.stringify(\n {\n summary: result.summary,\n block: result.block ?? '',\n confidence: result.confidence ?? null,\n provenance: result.provenance ?? null,\n },\n null,\n 2,\n )\n}\n\n// Exit-code mapping for thrown errors (ADR-050 #4):\n// 0 — success (handled at the call site, never via throw)\n// 1 — server error (HttpError)\n// 2 — misuse (handled in cli.ts before any network call)\n// 3 — daemon unreachable (TransportError)\nexport function exitCodeForError(err: unknown): number {\n if (err instanceof TransportError) return 3\n if (err instanceof HttpError) return 1\n return 1\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Snapshot push (ADR-074 §1)\n//\n// `neat sync` (local + --to <url>) feeds the freshly extracted snapshot into\n// either the local daemon or a remote one. The endpoint is dual-mounted via\n// registerRoutes — default project lands at /snapshot, named projects at\n// /projects/:project/snapshot. The helper goes through the shared\n// HttpClient so the verb stays on the same network path as every query verb.\n// ──────────────────────────────────────────────────────────────────────────\n\nexport interface PushSnapshotInput {\n baseUrl: string\n token: string | undefined\n project: string\n snapshot: unknown\n}\n\nexport interface PushSnapshotResult {\n project: string\n nodesAdded: number\n edgesAdded: number\n nodeCount: number\n edgeCount: number\n}\n\nexport function createSnapshotPushClient(\n baseUrl: string,\n token: string | undefined,\n): HttpClient {\n return createHttpClient(baseUrl, token && token.length > 0 ? token : undefined)\n}\n\nexport async function pushSnapshotToRemote(\n input: PushSnapshotInput,\n): Promise<PushSnapshotResult> {\n const client = createSnapshotPushClient(input.baseUrl, input.token)\n if (typeof client.post !== 'function') {\n throw new Error('HttpClient does not support POST — required for snapshot push')\n }\n return client.post<PushSnapshotResult>(\n `/projects/${encodeURIComponent(input.project)}/snapshot`,\n { snapshot: input.snapshot },\n )\n}\n"],"mappings":"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","names":["path","fs","path","fs","path","path","fs","fs","path","renderOtelEnvBlock","fs","path","path","fs","entry","fs","path","SDK_PACKAGES","OTEL_ENV","exists","detect","plan","apply","rollback","plan","plan","fs","path","spawn","path","plan","projects","path","fs","projectPath","path","entry","spawn","fs","readline","readline","entry","path","Provenance","path","entry","path","entry","plan","fs","path","entry","orchestratorCode","apply","projectPath","renderOtelEnvBlock"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/banner.ts","../src/gitignore.ts","../src/summary.ts","../src/watch.ts","../src/deploy/detect.ts","../src/installers/javascript.ts","../src/installers/templates.ts","../src/installers/python.ts","../src/installers/shared.ts","../src/installers/index.ts","../src/orchestrator.ts","../src/connector-cli.ts","../src/cli-verbs.ts","../src/cli-client.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport path from 'node:path'\nimport { promises as fs } from 'node:fs'\nimport { printBanner, readPackageVersion } from './banner.js'\nimport { DEFAULT_PROJECT, getGraph, resetGraph } from './graph.js'\nimport { extractFromDirectory } from './extract.js'\nimport {\n formatExtractionBanner,\n formatPrecisionFloorBanner,\n isStrictExtractionEnabled,\n} from './extract/errors.js'\nimport { discoverServices } from './extract/services.js'\nimport type { DiscoveredService } from './extract/shared.js'\nimport { computeDivergences } from './divergences.js'\nimport { saveGraphToDisk } from './persist.js'\nimport { ensureNeatOutIgnored } from './gitignore.js'\nimport { renderValueForwardSummary } from './summary.js'\nimport { startWatch, type WatchHandle } from './watch.js'\nimport { runDeploy, renderOtelEnvBlock } from './deploy/detect.js'\nimport { pathsForProject } from './projects.js'\nimport {\n addProject,\n findDaemonByProject,\n listMachineProjects,\n listProjects,\n ProjectNameCollisionError,\n pruneRegistry,\n removeProject,\n removeDaemonRecord,\n setStatus,\n signalDaemonStop,\n type MachineProject,\n} from './registry.js'\nimport {\n INSTALLERS,\n isEmptyPlan,\n pickInstaller,\n renderPatch,\n type InstallPlan,\n type PatchSection,\n} from './installers/index.js'\nimport { runOrchestrator } from './orchestrator.js'\nimport { runConnectorCommand } from './connector-cli.js'\nimport { runSync } from './cli-verbs.js'\nimport { DivergenceTypeSchema, type DivergenceType } from '@neat.is/types'\nimport {\n createHttpClient,\n exitCodeForError,\n formatHuman,\n formatJson,\n HttpError,\n type HttpClient,\n resolveAuthToken,\n runBlastRadius,\n runDependencies,\n runDiff,\n runDivergences,\n runIncidents,\n runObservedDependencies,\n runPolicies,\n runRootCause,\n runSearch,\n runStaleEdges,\n TransportError,\n type VerbResult,\n} from './cli-client.js'\n\nexport interface InitOptions {\n scanPath: string\n outPath: string\n // The project's registry name. Defaults to the basename of the scan path\n // when the user didn't pass `--project` (ADR-046 — project naming).\n project: string\n // Whether `project` was set explicitly via `--project`. The flag affects\n // which in-memory graph slot we use: explicit names get isolated slots\n // per ADR-026, the default basename keeps using DEFAULT_PROJECT for\n // back-compat with `neat watch`.\n projectExplicit: boolean\n apply: boolean\n dryRun: boolean\n noInstall: boolean\n // ADR-073 §5 — when true, append the per-type node/edge breakdown after\n // the value-forward findings block. Default false.\n verbose: boolean\n}\n\nexport interface InitResult {\n // Process exit code. 0 on success, 1 on collision / runtime failure,\n // 2 on misuse (handled before we get here, but documented for completeness).\n exitCode: number\n // Paths the run actually wrote to. Empty in `--dry-run` except for\n // `neat.patch`. Useful for tests asserting \"init only wrote X\".\n writtenFiles: string[]\n}\n\n// True when this run came in through `npx neat.is` rather than a global\n// `neat` binary on PATH. npx never puts `neat`/`neatd`/`neat-mcp` on PATH —\n// only `npm i -g neat.is` does — so an npx user who copies a bare `neat init`\n// example from the help screen hits `command not found`. We render every\n// example with the prefix that actually works for how they invoked us.\n//\n// Two robust signals: npm sets `npm_command` / `npm_execpath` for anything it\n// spawns (including `npx`), and an npx run resolves argv[1] under a temporary\n// `_npx` cache dir rather than a global bin dir. Either one is enough.\nexport function isNpxInvocation(): boolean {\n if (process.env.npm_command === 'exec') return true\n const execpath = process.env.npm_execpath ?? ''\n if (execpath.includes('npx')) return true\n const entry = process.argv[1] ?? ''\n if (entry.includes('/_npx/') || entry.includes('\\\\_npx\\\\')) return true\n return false\n}\n\n// The command prefix every help example renders with. `npx neat.is` for an\n// npx run, plain `neat` for a global install.\nexport function commandPrefix(): string {\n return isNpxInvocation() ? 'npx neat.is' : 'neat'\n}\n\nexport function usage(): void {\n const neat = commandPrefix()\n console.log('Installed via npx? Prefix commands with `npx neat.is`, or install once: `npm i -g neat.is`.')\n console.log('')\n console.log(`usage: ${neat} <command> [args] [--project <name>]`)\n console.log('')\n console.log(`Run \\`${neat}\\` with no command from inside your project to go zero-to-graph in one step.`)\n console.log('')\n console.log('lifecycle commands:')\n console.log(' init <path> One-time install: discover, extract, register, plan SDK install.')\n console.log(' Snapshot lands in <path>/neat-out/graph.json by default')\n console.log(' (or <path>/neat-out/<project>.json for non-default).')\n console.log(' Flags:')\n console.log(' --apply run the SDK install patch in place')\n console.log(' --dry-run write only neat.patch; do not register or snapshot')\n console.log(' --no-install skip SDK install planning entirely')\n console.log(' watch <path> Start neat-core, watch <path>, re-extract on changes.')\n console.log(' PORT (default 8080), OTEL_PORT (4318), HOST (0.0.0.0)')\n console.log(' control listeners. NEAT_OTLP_GRPC=true also opens 4317.')\n console.log(' list Report the daemons running on this machine (alias: ps).')\n console.log(' Reads ~/.neat/daemons/ and folds in any registered')\n console.log(' project no daemon has self-described yet.')\n console.log(' ps Alias of list.')\n console.log(' pause <name> Stop a project\\'s daemon until it is started again.')\n console.log(' resume <name> Bring a paused project back; for a stopped daemon, re-run')\n console.log(' `neat <path>` to start it.')\n console.log(' uninstall <name>')\n console.log(' Stop a project\\'s daemon and retire it. Does not touch')\n console.log(' neat-out/, policy.json, or any user file.')\n console.log(' prune Drop registry entries whose path is gone from disk.')\n console.log(' Flags: --json emit the removed list as JSON')\n console.log(' version Print the installed @neat.is/core version and exit.')\n console.log(' Aliases: --version, -v.')\n console.log(' skill Install or print the Claude Code MCP drop-in.')\n console.log(' Flags:')\n console.log(' --print-config print the JSON snippet to stdout')\n console.log(' --apply merge mcpServers.neat into ~/.claude.json')\n console.log(' deploy Detect the deploy substrate, generate NEAT_AUTH_TOKEN,')\n console.log(' emit a docker-compose / systemd / docker run artifact, and')\n console.log(' print the OTel env-vars block to paste into your platform.')\n console.log(' sync Re-run discovery, extraction, and SDK apply against the')\n console.log(' registered project, then notify the running daemon.')\n console.log(' Flags:')\n console.log(' --project <name> target a registered project by name')\n console.log(' --to <url> push the snapshot to a remote daemon')\n console.log(' --token <token> bearer token for --to (or $NEAT_REMOTE_TOKEN)')\n console.log(' --dry-run run extraction in-memory; do not write')\n console.log(' --no-instrument skip the SDK install apply step')\n console.log(' --json emit the delta summary as JSON')\n console.log(' connector Configure pull-based OBSERVED connectors (supabase, railway,')\n console.log(' firebase, cloudflare). Subcommands:')\n console.log(' add <provider> add a connector; validates the credential')\n console.log(' against the provider first (--skip-validate to skip)')\n console.log(' flags: --project <name>, --credential/--token <$VAR|value>,')\n console.log(' --id <id>, --<option> <value>, --plaintext, --skip-validate')\n console.log(' list list configured connectors (credentials redacted)')\n console.log(' remove <id> remove a connector by id')\n console.log(' test <id> re-check an existing connector\\'s credential')\n console.log(' Credentials default to an env-var reference ($VAR) resolved at')\n console.log(' run time; the config file is written owner-only (0600).')\n console.log('')\n console.log('query commands (mirror the MCP tools, ADR-050):')\n console.log(' root-cause <node-id> Walk inbound edges to find what broke first.')\n console.log(` example: ${neat} root-cause service:<name>`)\n console.log(' blast-radius <node-id> BFS inbound — the dependents that break if this dies.')\n console.log(` example: ${neat} blast-radius database:<host>`)\n console.log(' dependencies <node-id> Transitive outbound dependencies.')\n console.log(' Flags: --depth N (default 3, max 10)')\n console.log(` example: ${neat} dependencies service:<name> --depth 2`)\n console.log(' observed-dependencies <node-id> OBSERVED-only outbound edges (runtime traffic).')\n console.log(` example: ${neat} observed-dependencies service:<name>`)\n console.log(' incidents [<node-id>] Recent error events; per-node when an id is given.')\n console.log(' Flags: --limit N (default 20)')\n console.log(` example: ${neat} incidents service:<name> --limit 5`)\n console.log(' search <query> Semantic (or substring) match on node names/ids.')\n console.log(` example: ${neat} search \"checkout\"`)\n console.log(' diff --against <snapshot> Compare the live graph to a saved snapshot.')\n console.log(` example: ${neat} diff --against ./snapshots/baseline.json`)\n console.log(' stale-edges Recent OBSERVED → STALE transitions.')\n console.log(' Flags: --limit N, --edge-type CALLS|CONNECTS_TO|...')\n console.log(` example: ${neat} stale-edges --edge-type CALLS`)\n console.log(' policies Current policy violations.')\n console.log(' Flags: --node <id>, --hypothetical-action <json>')\n console.log(` example: ${neat} policies --node service:<name> --json`)\n console.log(' divergences Where code (EXTRACTED) and production (OBSERVED) disagree.')\n console.log(' Flags: --type <list>, --min-confidence <0..1>, --node <id>')\n console.log(` example: ${neat} divergences --min-confidence 0.7`)\n console.log('')\n console.log('flags:')\n console.log(' --project <name> Name the project this command targets. Default: \"default\".')\n console.log(' --json Emit machine-readable JSON instead of human text. Query verbs only.')\n console.log('')\n console.log('exit codes:')\n console.log(' 0 success')\n console.log(' 1 server error (4xx/5xx body printed to stderr)')\n console.log(' 2 misuse (missing args, bad flags) — handled before any network call')\n console.log(' 3 environmental — daemon unreachable, or one of ports 8080 / 4318 / 6328')\n console.log(' is held by another process when `neat <path>` tries to spawn the daemon')\n console.log('')\n console.log('environment:')\n console.log(' NEAT_API_URL base URL for the core REST API (default http://localhost:8080)')\n console.log(' alias: NEAT_CORE_URL (the name the MCP server reads)')\n console.log(' NEAT_PROJECT project name when --project isn\\'t passed')\n}\n\n// Tiny argv parser — pulls `--project <name>`, the v0.2.5 init flags, and\n// the v0.2.8 verb flags out of `rest`. Boolean / value flags are surfaced\n// unconditionally; per-command validation lives in `main`.\ninterface ParsedArgs {\n project: string | null\n apply: boolean\n dryRun: boolean\n noInstall: boolean\n noInstrument: boolean\n noOpen: boolean\n yes: boolean\n verbose: boolean\n printConfig: boolean\n json: boolean\n depth: number | null\n limit: number | null\n edgeType: string | null\n node: string | null\n since: string | null\n against: string | null\n errorId: string | null\n hypotheticalAction: string | null\n type: string | null\n minConfidence: number | null\n // `neat sync` (ADR-074 §1) — remote daemon URL + bearer token.\n to: string | null\n token: string | null\n positional: string[]\n}\n\n// String-valued flags supported across the verb surface. Each entry maps the\n// canonical `--flag` name (and its `--flag=` equivalent) to the parsed-args\n// field that receives it. Centralising the table keeps misuse diagnostics\n// (exit code 2) consistent across verbs.\nconst STRING_FLAGS = [\n ['--project', 'project'],\n ['--depth', 'depth'],\n ['--limit', 'limit'],\n ['--edge-type', 'edgeType'],\n ['--node', 'node'],\n ['--since', 'since'],\n ['--against', 'against'],\n ['--error-id', 'errorId'],\n ['--hypothetical-action', 'hypotheticalAction'],\n ['--type', 'type'],\n ['--min-confidence', 'minConfidence'],\n ['--to', 'to'],\n ['--token', 'token'],\n] as const\n\nfunction parseArgs(rest: string[]): ParsedArgs {\n const positional: string[] = []\n const out: ParsedArgs = {\n project: null,\n apply: false,\n dryRun: false,\n noInstall: false,\n noInstrument: false,\n noOpen: false,\n yes: false,\n verbose: false,\n printConfig: false,\n json: false,\n depth: null,\n limit: null,\n edgeType: null,\n node: null,\n since: null,\n against: null,\n errorId: null,\n hypotheticalAction: null,\n type: null,\n minConfidence: null,\n to: null,\n token: null,\n positional: [],\n }\n for (let i = 0; i < rest.length; i++) {\n const arg = rest[i] as string\n\n // Boolean flags first.\n if (arg === '--apply') { out.apply = true; continue }\n if (arg === '--dry-run') { out.dryRun = true; continue }\n if (arg === '--no-install') { out.noInstall = true; continue }\n if (arg === '--no-instrument') { out.noInstrument = true; continue }\n if (arg === '--no-open') { out.noOpen = true; continue }\n if (arg === '--yes' || arg === '-y') { out.yes = true; continue }\n if (arg === '--verbose') { out.verbose = true; continue }\n if (arg === '--print-config') { out.printConfig = true; continue }\n if (arg === '--json') { out.json = true; continue }\n\n // String/number flags via the shared table.\n let matched = false\n for (const [flag, field] of STRING_FLAGS) {\n if (arg === flag) {\n const next = rest[i + 1]\n if (next === undefined) {\n console.error(`neat: ${flag} requires a value`)\n process.exit(2)\n }\n assignFlag(out, field, next)\n i++\n matched = true\n break\n }\n if (arg.startsWith(`${flag}=`)) {\n assignFlag(out, field, arg.slice(flag.length + 1))\n matched = true\n break\n }\n }\n if (matched) continue\n positional.push(arg)\n }\n out.positional = positional\n return out\n}\n\nexport { parseArgs }\n\n// Number flags get parsed at assignment time so misuse (`--depth foo`)\n// surfaces with exit code 2 before any network call.\nfunction assignFlag(out: ParsedArgs, field: (typeof STRING_FLAGS)[number][1], value: string): void {\n if (field === 'depth' || field === 'limit') {\n const n = Number(value)\n if (!Number.isFinite(n) || !Number.isInteger(n) || n < 1) {\n console.error(`neat: --${field === 'depth' ? 'depth' : 'limit'} must be a positive integer`)\n process.exit(2)\n }\n out[field] = n\n return\n }\n if (field === 'minConfidence') {\n const n = Number(value)\n if (!Number.isFinite(n) || n < 0 || n > 1) {\n console.error('neat: --min-confidence must be a number in [0, 1]')\n process.exit(2)\n }\n out.minConfidence = n\n return\n }\n // String fields.\n ;(out as unknown as Record<string, unknown>)[field] = value\n}\n\n// Per-type node/edge counts + compat formatting moved into summary.ts as\n// part of the value-forward findings block (issue #305 / ADR-073 §5).\n\n// `readPackageVersion` + `printBanner` live in banner.ts so the orchestrator\n// can print the same artwork without pulling in the whole CLI dispatch (and\n// without a cli ↔ orchestrator import cycle). Re-exported here so existing\n// importers of `cli.js` (e.g. the banner test, MCP) keep resolving them.\nexport { printBanner, readPackageVersion }\n\nfunction printVersion(): void {\n process.stdout.write(`${readPackageVersion()}\\n`)\n}\n\n// One `neat list` / `neat ps` row. A discovery-backed row reports the daemon's\n// state and ports; a legacy registry row (no daemon file yet) reports\n// `registered` and the registry status so the migration window stays legible.\nfunction formatMachineProjectRow(r: MachineProject): string {\n if (r.ports) {\n const where = r.pid !== undefined ? `\\tpid=${r.pid}` : ''\n return `${r.project}\\t${r.state}\\trest=${r.ports.rest} otlp=${r.ports.otlp} web=${r.ports.web}\\t${r.projectPath}${where}`\n }\n const status = r.registryStatus ? `\\t(${r.registryStatus})` : ''\n return `${r.project}\\t${r.state}${status}\\t${r.projectPath}`\n}\n\nfunction printDiscoveryReport(opts: InitOptions, services: DiscoveredService[]): void {\n const languages = [...new Set(services.map((s) => s.node.language))].sort()\n const mode = opts.dryRun ? 'dry-run' : opts.apply ? 'apply' : 'patch-only'\n printBanner()\n console.log('=== neat init: discovery ===')\n console.log(`scan path: ${opts.scanPath}`)\n console.log(`project: ${opts.project}`)\n console.log(`mode: ${mode}`)\n console.log(`services: ${services.length}`)\n for (const s of services) {\n const where = s.node.repoPath && s.node.repoPath.length > 0 ? s.node.repoPath : '.'\n console.log(` - ${s.node.name} (${s.node.language}) — ${where}`)\n }\n console.log(`languages: ${languages.length > 0 ? languages.join(', ') : '(none)'}`)\n if (opts.noInstall) {\n console.log('install: skipped (--no-install)')\n } else if (opts.dryRun) {\n console.log('install: patch will be written to neat.patch; nothing else.')\n } else if (opts.apply) {\n console.log('install: patch will be applied in place. Run `npm install` afterwards.')\n } else {\n console.log('install: patch will be written to neat.patch for review.')\n }\n console.log('')\n}\n\nasync function buildPatchSections(\n services: DiscoveredService[],\n project: string,\n): Promise<PatchSection[]> {\n const sections: PatchSection[] = []\n for (const svc of services) {\n const installer = await pickInstaller(svc.dir)\n if (!installer) continue\n // v0.4.1 / refs #339 — pass the registered project name so the per-\n // package `.env.neat` carries `OTEL_SERVICE_NAME=<project>`. The daemon\n // routes spans by registered project name; matching keys end-to-end\n // is what keeps OBSERVED edges landing.\n const plan: InstallPlan = await installer.plan(svc.dir, { project })\n // Lib-only + runtime-kind-skipped packages keep a section so the dry-run\n // patch documents the skip and the apply summary counts them (ADR-069 §2,\n // v0.4.4 / #370). Empty plans without either flag are already-instrumented\n // end-to-end and drop out.\n if (isEmptyPlan(plan) && !plan.libOnly && plan.runtimeKind === undefined) continue\n sections.push({ installer: installer.name, plan })\n }\n return sections\n}\n\nexport async function runInit(opts: InitOptions): Promise<InitResult> {\n const written: string[] = []\n\n // ── Step 1: validate path ────────────────────────────────────────────\n const stat = await fs.stat(opts.scanPath).catch(() => null)\n if (!stat || !stat.isDirectory()) {\n console.error(`neat init: ${opts.scanPath} is not a directory`)\n return { exitCode: 2, writtenFiles: written }\n }\n\n // ── Step 2: discovery (ADR-046 #2 — before any mutation) ─────────────\n const services = await discoverServices(opts.scanPath)\n printDiscoveryReport(opts, services)\n\n // ── Step 3: plan SDK install (pure data, no fs writes) ───────────────\n const sections = opts.noInstall ? [] : await buildPatchSections(services, opts.project)\n const patch = renderPatch(sections)\n const patchPath = path.join(opts.scanPath, 'neat.patch')\n\n // ── Step 4: dry-run shortcut — only neat.patch is allowed to land ────\n if (opts.dryRun) {\n await fs.writeFile(patchPath, patch, 'utf8')\n written.push(patchPath)\n console.log(`dry-run: patch written to ${patchPath}`)\n // ADR-073 §6 — list the planned `.gitignore` write alongside the other\n // planned writes. No file mutation in dry-run; only the announcement.\n const gitignorePath = path.join(opts.scanPath, '.gitignore')\n const gitignoreExists = await fs.stat(gitignorePath).then(() => true).catch(() => false)\n const verb = gitignoreExists ? 'append' : 'create'\n console.log(`dry-run: would ${verb} ${gitignorePath} (add neat-out/)`)\n console.log('rerun without --dry-run to register and snapshot.')\n return { exitCode: 0, writtenFiles: written }\n }\n\n // ── Step 5: extraction + snapshot ────────────────────────────────────\n // Use DEFAULT_PROJECT for the in-memory graph slot when --project wasn't\n // explicitly passed; named projects get isolated slots per ADR-026.\n const graphKey = opts.projectExplicit ? opts.project : DEFAULT_PROJECT\n resetGraph(graphKey)\n const graph = getGraph(graphKey)\n // ADR-065 — per-file extraction failures land alongside the snapshot in\n // <projectDir>/neat-out/errors.ndjson. Same file as OTel error events\n // (ADR-033) with a `source: 'extract'` discriminator.\n const projectPaths = pathsForProject(\n graphKey,\n path.join(opts.scanPath, 'neat-out'),\n )\n const errorsPath = path.join(path.dirname(opts.outPath), path.basename(projectPaths.errorsPath))\n const result = await extractFromDirectory(graph, opts.scanPath, { errorsPath })\n await saveGraphToDisk(graph, opts.outPath)\n written.push(opts.outPath)\n\n // ADR-073 §6 — ensure `neat-out/` is git-ignored. Snapshot just landed on\n // disk; an un-ignored neat-out/ would leak into git history on the next\n // commit. Idempotent: the helper no-ops when the line is already present.\n const gitignoreResult = await ensureNeatOutIgnored(opts.scanPath)\n if (gitignoreResult.action !== 'unchanged') {\n written.push(gitignoreResult.file)\n }\n\n // ── Step 6: register in the machine-level registry ───────────────────\n // Idempotent re-init of the same path under the same name refreshes the\n // entry; collision against a different path exits non-zero (ADR-046 #7).\n const languages = [...new Set(services.map((s) => s.node.language))].sort()\n let currentProjectName = opts.project\n try {\n const entry = await addProject({\n name: opts.project,\n path: opts.scanPath,\n languages,\n status: 'active',\n })\n currentProjectName = entry.name\n } catch (err) {\n if (err instanceof ProjectNameCollisionError) {\n console.error(`neat init: ${err.message}`)\n console.error('pass --project <other-name> to register under a different name.')\n return { exitCode: 1, writtenFiles: written }\n }\n throw err\n }\n\n // Narrow the active-project surface to the project the operator just\n // registered. Mirrors the bare-orchestrator behaviour so `neat init` and\n // `neat <path>` agree on the activation contract.\n const siblings = await listProjects()\n const paused: string[] = []\n for (const p of siblings) {\n if (p.name !== currentProjectName && p.status === 'active') {\n await setStatus(p.name, 'paused')\n paused.push(p.name)\n }\n }\n if (paused.length > 0) {\n const plural = paused.length === 1 ? '' : 's'\n console.log(\n `neat: paused ${paused.length} sibling project${plural}; run \\`neat resume <name>\\` to bring one back active.`,\n )\n }\n\n // ── Step 7: write or apply patch ─────────────────────────────────────\n if (!opts.noInstall) {\n if (opts.apply) {\n let instrumented = 0\n let alreadyInstrumented = 0\n let libOnly = 0\n let browserBundle = 0\n let reactNative = 0\n for (const section of sections) {\n const installer = INSTALLERS.find((i) => i.name === section.installer)\n if (!installer) continue\n const outcome = await installer.apply(section.plan)\n if (outcome.outcome === 'instrumented') {\n instrumented++\n for (const f of outcome.writtenFiles) written.push(f)\n } else if (outcome.outcome === 'already-instrumented') {\n alreadyInstrumented++\n } else if (outcome.outcome === 'lib-only') {\n libOnly++\n } else if (outcome.outcome === 'browser-bundle') {\n browserBundle++\n console.log(`skipping ${section.plan.serviceDir}: browser bundle; browser-OTel support lands in a future release.`)\n } else if (outcome.outcome === 'react-native') {\n reactNative++\n console.log(`skipping ${section.plan.serviceDir}: React Native target; browser-OTel support lands in a future release.`)\n }\n }\n if (sections.length > 0) {\n console.log('')\n const parts = [\n `instrumented ${instrumented}`,\n `already-instrumented ${alreadyInstrumented}`,\n `lib-only ${libOnly}`,\n ]\n if (browserBundle > 0) parts.push(`browser-bundle ${browserBundle}`)\n if (reactNative > 0) parts.push(`react-native ${reactNative}`)\n console.log(`apply: ${parts.join(', ')}`)\n console.log('Run `npm install` (or your language equivalent) to refresh lockfiles.')\n }\n } else {\n await fs.writeFile(patchPath, patch, 'utf8')\n written.push(patchPath)\n }\n }\n\n // ── Step 8: summary + incompatibilities ──────────────────────────────\n // ADR-073 §5 / issue #305 — findings-first: compat violations, top\n // divergences, services without OBSERVED coverage, then the OTel env-vars\n // block. Per-type counts ride behind `--verbose`.\n console.log('')\n console.log(`snapshot: ${opts.outPath}`)\n console.log(`added: ${result.nodesAdded} nodes, ${result.edgesAdded} edges`)\n console.log('')\n const divergenceResult = computeDivergences(graph)\n console.log(\n renderValueForwardSummary({\n graph,\n divergences: divergenceResult.divergences,\n verbose: opts.verbose,\n }),\n )\n // ADR-065 — loud failure mode banner. Unconditional; 0 is a positive\n // signal. When errors > 0, also surface the sidecar path so the operator\n // can read per-file detail.\n console.log(formatExtractionBanner(result.extractionErrors))\n if (result.extractionErrors > 0) {\n console.log(`errors: ${errorsPath}`)\n }\n // ADR-066 — precision-floor drop banner. Always emitted; 0 is observable\n // as a positive signal that no cross-service heuristic edges grew the\n // graph this pass.\n console.log(formatPrecisionFloorBanner(result.extractedDropped))\n\n // ADR-065 — NEAT_STRICT_EXTRACTION=1 makes any per-file failure exit\n // non-zero. Default is forgiving (banner only). Exit code 4 keeps\n // misuse (2) and daemon-down (3) distinguishable per the CLI contract.\n if (result.extractionErrors > 0 && isStrictExtractionEnabled()) {\n return { exitCode: 4, writtenFiles: written }\n }\n\n return { exitCode: 0, writtenFiles: written }\n}\n\n// ── Claude Code skill (ADR-049 / v0.2.5 step 6) ────────────────────────\n//\n// The skill is a one-shot MCP-config drop-in. Source of truth for the\n// snippet lives here (the @neat.is/claude-skill package's\n// claude_code_config.json holds an identical copy for documentation; a\n// contract test keeps the two byte-aligned).\nexport const CLAUDE_SKILL_CONFIG = {\n mcpServers: {\n neat: {\n type: 'stdio' as const,\n command: 'npx',\n args: ['-y', '@neat.is/mcp'],\n env: {\n NEAT_CORE_URL: 'http://localhost:8080',\n },\n },\n },\n}\n\nfunction claudeConfigPath(): string {\n // ~/.claude.json is Claude Code's user-level MCP config. Tests override\n // via NEAT_CLAUDE_CONFIG so they don't touch the real file.\n const override = process.env.NEAT_CLAUDE_CONFIG\n if (override && override.length > 0) return path.resolve(override)\n const home = process.env.HOME ?? process.env.USERPROFILE ?? ''\n return path.join(home, '.claude.json')\n}\n\nexport interface SkillOptions {\n apply: boolean\n printConfig: boolean\n}\n\nexport async function runSkill(opts: SkillOptions): Promise<{ exitCode: number }> {\n const snippet = JSON.stringify(CLAUDE_SKILL_CONFIG, null, 2) + '\\n'\n\n if (opts.printConfig) {\n process.stdout.write(snippet)\n return { exitCode: 0 }\n }\n\n if (opts.apply) {\n const target = claudeConfigPath()\n let existing: Record<string, unknown> = {}\n try {\n existing = JSON.parse(await fs.readFile(target, 'utf8'))\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n console.error(`neat skill: failed to read ${target} — ${(err as Error).message}`)\n return { exitCode: 1 }\n }\n }\n // Merge mcpServers.neat without disturbing other entries the user\n // might have wired up by hand.\n const mcp =\n (existing as { mcpServers?: Record<string, unknown> }).mcpServers ?? {}\n const merged = {\n ...existing,\n mcpServers: { ...mcp, neat: CLAUDE_SKILL_CONFIG.mcpServers.neat },\n }\n await fs.mkdir(path.dirname(target), { recursive: true })\n await fs.writeFile(target, JSON.stringify(merged, null, 2) + '\\n', 'utf8')\n console.log(`neat skill: wrote mcpServers.neat to ${target}`)\n console.log('restart Claude Code to pick up the new MCP server.')\n return { exitCode: 0 }\n }\n\n console.log('neat skill — Claude Code MCP drop-in for NEAT')\n console.log('')\n console.log(' --print-config print the JSON snippet to stdout')\n console.log(' --apply merge mcpServers.neat into ~/.claude.json')\n console.log('')\n console.log('Manual install: copy mcpServers.neat from --print-config into ~/.claude.json,')\n console.log('then restart Claude Code. See packages/claude-skill/SKILL.md for the tool list.')\n console.log('')\n console.log('The MCP server reads NEAT_CORE_URL for the daemon URL — point it at a')\n console.log('non-default daemon by editing that value in the generated config.')\n return { exitCode: 0 }\n}\n\nexport async function main(): Promise<void> {\n const argv = process.argv.slice(2)\n // First token, for the help/version flag checks. The command dispatch below\n // keys off the first *positional* (flag-stripped) instead, so a bare\n // `npx neat.is --no-open` still reaches the orchestrator.\n const cmd0 = argv[0]\n\n // `-h` / `--help` print the usage screen and exit clean.\n if (cmd0 === '-h' || cmd0 === '--help') {\n usage()\n process.exit(0)\n }\n\n // The dispatcher honors three spellings: --version, -v, version.\n if (cmd0 === '--version' || cmd0 === '-v' || cmd0 === 'version') {\n printVersion()\n process.exit(0)\n }\n\n // `neat connector <add|list|remove|test>` — the ADR-130 connector on-ramp\n // (docs/contracts/connector-config.md §3). A top-level config command family,\n // not an eleventh query verb; it takes provider-specific flags, so it parses\n // its own argv rather than routing through the shared query-flag table.\n if (cmd0 === 'connector') {\n const code = await runConnectorCommand(argv.slice(1))\n if (code !== 0) process.exit(code)\n return\n }\n\n // No positional command — `npx neat.is` (optionally with flags like\n // `--no-open`) run from inside a repo. This is the zero-to-graph path\n // (issue #483): run the orchestrator on the current working directory, the\n // same dispatch the explicit `neat <path>` form takes (project name =\n // basename of cwd). We detect \"no command\" by the absence of any\n // positional after flag-stripping, so a bare `npx neat.is --no-instrument`\n // still lands here instead of treating the flag as a command.\n const argvParsed = parseArgs(argv)\n if (argvParsed.positional.length === 0) {\n const orchestratorCode = await tryOrchestrator(process.cwd(), argvParsed)\n // tryOrchestrator returns null only when its path isn't a directory,\n // which can't happen for process.cwd(); the non-null branch always runs.\n if (orchestratorCode !== null && orchestratorCode !== 0) process.exit(orchestratorCode)\n return\n }\n\n // From here on, the first positional is the command. Reuse the already-\n // parsed flags and drop the command token from the positional list, so each\n // verb's `parsed.positional[0]` stays the verb's own first argument (e.g.\n // the node-id for `root-cause`), unchanged from the pre-#483 dispatch.\n const cmd = argvParsed.positional[0] as string\n const parsed: ParsedArgs = { ...argvParsed, positional: argvParsed.positional.slice(1) }\n const { positional, apply, dryRun, noInstall } = parsed\n const project = parsed.project ?? DEFAULT_PROJECT\n\n if (cmd === 'init') {\n const target = positional[0]\n if (!target) {\n console.error('neat init: missing <path>')\n usage()\n process.exit(2)\n }\n if (apply && dryRun) {\n console.error('neat init: --apply and --dry-run are mutually exclusive')\n process.exit(2)\n }\n const scanPath = path.resolve(target)\n // ADR-046 — when --project isn't passed, the registry name defaults to\n // the basename of the scan path. The in-memory graph slot stays on\n // DEFAULT_PROJECT (back-compat with existing `neat watch` invocations).\n const projectExplicit = parsed.project !== null\n const projectName = projectExplicit ? project : path.basename(scanPath)\n // Default project keeps writing to graph.json (ADR-026 back-compat);\n // named projects use <project>.json under the same neat-out directory.\n const projectKey = projectExplicit ? project : DEFAULT_PROJECT\n const fallback = pathsForProject(projectKey, path.join(scanPath, 'neat-out')).snapshotPath\n const outPath = path.resolve(process.env.NEAT_OUT_PATH ?? fallback)\n const result = await runInit({\n scanPath,\n outPath,\n project: projectName,\n projectExplicit,\n apply,\n dryRun,\n noInstall,\n verbose: parsed.verbose,\n })\n if (result.exitCode !== 0) process.exit(result.exitCode)\n return\n }\n\n if (cmd === 'watch') {\n const target = positional[0]\n if (!target) {\n console.error('neat watch: missing <path>')\n usage()\n process.exit(2)\n }\n const scanPath = path.resolve(target)\n const stat = await fs.stat(scanPath).catch(() => null)\n if (!stat || !stat.isDirectory()) {\n console.error(`neat watch: ${scanPath} is not a directory`)\n process.exit(2)\n }\n const projectPaths = pathsForProject(project, path.join(scanPath, 'neat-out'))\n const outPath = path.resolve(process.env.NEAT_OUT_PATH ?? projectPaths.snapshotPath)\n const errorsPath = path.resolve(\n process.env.NEAT_ERRORS_PATH ??\n path.join(path.dirname(outPath), path.basename(projectPaths.errorsPath)),\n )\n const staleEventsPath = path.resolve(\n process.env.NEAT_STALE_EVENTS_PATH ??\n path.join(path.dirname(outPath), path.basename(projectPaths.staleEventsPath)),\n )\n\n const embeddingsCachePath = process.env.NEAT_EMBEDDINGS_CACHE_PATH\n ? path.resolve(process.env.NEAT_EMBEDDINGS_CACHE_PATH)\n : undefined\n\n const handle: WatchHandle = await startWatch(getGraph(project), {\n scanPath,\n outPath,\n errorsPath,\n staleEventsPath,\n project,\n ...(embeddingsCachePath ? { embeddingsCachePath } : {}),\n host: process.env.HOST ?? '0.0.0.0',\n port: Number(process.env.PORT ?? 8080),\n otelPort: Number(process.env.OTEL_PORT ?? 4318),\n otelGrpc: process.env.NEAT_OTLP_GRPC === 'true',\n otelGrpcPort: process.env.NEAT_OTLP_GRPC_PORT\n ? Number(process.env.NEAT_OTLP_GRPC_PORT)\n : undefined,\n })\n\n // startPersistLoop already wires SIGTERM/SIGINT to flush + exit. Hook in\n // ahead of it so the watcher closes cleanly first; the persist handler's\n // `process.exit(0)` will still run after our stop() resolves.\n let shuttingDown = false\n const shutdown = (signal: NodeJS.Signals): void => {\n if (shuttingDown) return\n shuttingDown = true\n console.log(`neat watch: ${signal} received, stopping…`)\n void handle.stop().catch((err) => {\n console.error('neat watch: shutdown error', err)\n })\n }\n process.on('SIGTERM', shutdown)\n process.on('SIGINT', shutdown)\n return\n }\n\n // `list` / `ps` both report the daemons discovered on the machine. ADR-096\n // §6 — discovery reads the lock-free `~/.neat/daemons/` directory and folds\n // in any legacy registry entries no daemon has self-described yet, so a\n // pre-migration install still lists its projects.\n if (cmd === 'list' || cmd === 'ps') {\n const rows = await listMachineProjects()\n if (rows.length === 0) {\n console.log('no daemons running and no projects registered. run `neat init <path>` to register one.')\n return\n }\n for (const r of rows) {\n console.log(formatMachineProjectRow(r))\n }\n return\n }\n\n // `pause` stops a project's daemon. Under one-daemon-per-project (ADR-096)\n // that is the per-daemon shutdown driven by the discovery record's pid. While\n // a project still lives only in the legacy registry (the migration window\n // before #508 lands), it falls back to flipping the registry status the\n // multi-project daemon reads.\n if (cmd === 'pause') {\n const name = positional[0]\n if (!name) {\n console.error('neat pause: missing <name>')\n usage()\n process.exit(2)\n }\n const daemon = await findDaemonByProject(name)\n if (daemon) {\n if (daemon.live && signalDaemonStop(daemon.record.pid)) {\n console.log(`paused: ${name} (${daemon.record.projectPath}) — stopped daemon pid ${daemon.record.pid}`)\n } else {\n console.log(`paused: ${name} (${daemon.record.projectPath}) — daemon was not running`)\n }\n return\n }\n try {\n const entry = await setStatus(name, 'paused')\n console.log(`paused: ${entry.name} (${entry.path})`)\n } catch (err) {\n console.error((err as Error).message)\n process.exit(1)\n }\n return\n }\n\n // `resume` brings a paused project back. Spawning a per-project daemon is the\n // orchestrator's job (`neat <path>`), so against a stopped daemon record we\n // point the operator at it; against a legacy registry entry we flip the\n // status the multi-project daemon reads, preserving the pre-migration shape.\n if (cmd === 'resume') {\n const name = positional[0]\n if (!name) {\n console.error('neat resume: missing <name>')\n usage()\n process.exit(2)\n }\n const daemon = await findDaemonByProject(name)\n if (daemon) {\n if (daemon.live) {\n console.log(`resume: ${name} (${daemon.record.projectPath}) — daemon already running`)\n } else {\n console.log(`resume: ${name} (${daemon.record.projectPath}) — run \\`neat ${daemon.record.projectPath}\\` to start its daemon again`)\n }\n return\n }\n try {\n const entry = await setStatus(name, 'active')\n console.log(`resumed: ${entry.name} (${entry.path})`)\n } catch (err) {\n console.error((err as Error).message)\n process.exit(1)\n }\n return\n }\n\n if (cmd === 'skill') {\n const result = await runSkill({ apply: parsed.apply, printConfig: parsed.printConfig })\n if (result.exitCode !== 0) process.exit(result.exitCode)\n return\n }\n\n // `uninstall` retires a project. Under ADR-096 that means stopping its daemon\n // (via the discovery record's pid) and clearing its discovery file, then\n // dropping any legacy registry row. As before it never touches neat-out/,\n // policy.json, or user files at the project path (ADR-048 #6).\n if (cmd === 'uninstall') {\n const name = positional[0]\n if (!name) {\n console.error('neat uninstall: missing <name>')\n usage()\n process.exit(2)\n }\n const daemon = await findDaemonByProject(name)\n const removed = await removeProject(name)\n if (!daemon && !removed) {\n console.error(`neat uninstall: no project named \"${name}\"`)\n process.exit(1)\n }\n const projectPath = daemon?.record.projectPath ?? removed?.path ?? '(unknown path)'\n if (daemon) {\n if (daemon.live && signalDaemonStop(daemon.record.pid)) {\n console.log(`uninstall: ${name} — stopped daemon pid ${daemon.record.pid}`)\n }\n // Clear the discovery copy. A live daemon clears its own on graceful stop,\n // but removing it here covers a daemon that crashed without cleanup and\n // makes the verb idempotent against a stale record.\n await removeDaemonRecord(daemon.source)\n }\n console.log(`unregistered: ${name} (${projectPath})`)\n console.log('note: neat-out/, policy.json, and other files at the project path were left in place.')\n return\n }\n\n if (cmd === 'prune') {\n // #463 — one-shot cleanup of registry entries whose path is gone. Explicit\n // user intent, so it drops any ENOENT entry immediately regardless of the\n // auto-prune TTL. Only definite ENOENT entries go — a project whose path\n // still exists, or one behind a transient stat error, is left alone.\n const removed = await pruneRegistry({ ttlMs: 0 })\n if (parsed.json) {\n console.log(JSON.stringify(removed.map((p) => ({ name: p.name, path: p.path })), null, 2))\n return\n }\n if (removed.length === 0) {\n console.log('nothing to prune — every registered project path still exists.')\n return\n }\n console.log(`pruned ${removed.length} project${removed.length === 1 ? '' : 's'}: ${removed.map((p) => p.name).join(', ')}`)\n return\n }\n\n if (cmd === 'deploy') {\n // ADR-073 §2 — detect substrate, generate token, emit artifact, print\n // the OTel env-vars block. Token is the only secret printed to stdout;\n // the artifact written to disk names the env-var by reference only.\n const artifact = await runDeploy()\n const block = renderOtelEnvBlock(artifact.token)\n\n console.log()\n console.log(`Substrate detected: ${artifact.substrate}`)\n if (artifact.artifactPath) {\n console.log(`Artifact written: ${artifact.artifactPath}`)\n } else {\n console.log('No on-disk artifact — copy the snippet below into your substrate.')\n console.log()\n console.log(artifact.contents)\n }\n console.log()\n console.log('NEAT_AUTH_TOKEN (store this — it will not be printed again):')\n console.log(` ${artifact.token}`)\n console.log()\n console.log(\"For your application's deploy platform, set these env vars:\")\n console.log(block.split('\\n').map((l) => ` ${l}`).join('\\n'))\n console.log()\n console.log('Once NEAT is running, your dashboard will be at:')\n console.log(' https://<host>:6328')\n console.log()\n console.log('To start NEAT, run:')\n console.log(` ${artifact.startCommand}`)\n return\n }\n\n if (cmd === 'sync') {\n // ADR-074 §1 — re-runs discovery + extract + SDK apply + daemon notify\n // against the registered project. Skips registry registration, browser\n // open, daemon spawn, and the first-run summary block.\n const result = await runSync({\n ...(parsed.project ? { project: parsed.project } : {}),\n ...(parsed.to ? { to: parsed.to } : {}),\n ...(parsed.token ? { token: parsed.token } : {}),\n dryRun: parsed.dryRun,\n noInstrument: parsed.noInstrument,\n json: parsed.json,\n })\n if (result.exitCode !== 0) process.exit(result.exitCode)\n return\n }\n\n // ── Query verbs (ADR-050) ────────────────────────────────────────────\n // The nine verbs mirror the MCP tool allowlist. Same multi-project\n // routing, same three-part response shape (summary + block + footer),\n // exit codes branch on misuse vs server error vs daemon-down.\n if (QUERY_VERBS.has(cmd)) {\n const code = await runQueryVerb(cmd, parsed)\n if (code !== 0) process.exit(code)\n return\n }\n\n // ── Bare-path orchestrator (ADR-073 §1) ──────────────────────────────\n // `neat <path>` — when the first positional doesn't match any verb but\n // resolves to a directory, hand the run off to the orchestrator. This is\n // the `npx neat.is <path>` shape from ADR-073: one command, end-to-end.\n const orchestratorCode = await tryOrchestrator(cmd, parsed)\n if (orchestratorCode !== null) {\n if (orchestratorCode !== 0) process.exit(orchestratorCode)\n return\n }\n\n console.error(`neat: unknown command \"${cmd}\"`)\n usage()\n process.exit(1)\n}\n\n// Returns null when the first positional doesn't resolve to a directory\n// (so the caller can fall through to the unknown-command error). Returns\n// an exit code when the orchestrator ran.\nasync function tryOrchestrator(cmd: string, parsed: ParsedArgs): Promise<number | null> {\n const scanPath = path.resolve(cmd)\n const stat = await fs.stat(scanPath).catch(() => null)\n if (!stat || !stat.isDirectory()) return null\n\n const projectExplicit = parsed.project !== null\n const projectName = projectExplicit ? (parsed.project as string) : path.basename(scanPath)\n const result = await runOrchestrator({\n scanPath,\n project: projectName,\n projectExplicit,\n noInstrument: parsed.noInstrument,\n noOpen: parsed.noOpen,\n yes: parsed.yes,\n })\n return result.exitCode\n}\n\n// ── Query verb dispatcher ──────────────────────────────────────────────\n\nexport const QUERY_VERBS: Set<string> = new Set([\n 'root-cause',\n 'blast-radius',\n 'dependencies',\n 'observed-dependencies',\n 'incidents',\n 'search',\n 'diff',\n 'stale-edges',\n 'policies',\n // Tenth verb (ADR-060) — amends ADR-050's locked allowlist of nine.\n 'divergences',\n])\n\n// ADR-050 #2: --project flag → NEAT_PROJECT env → undefined (server's\n// `default` slot). undefined keeps legacy unprefixed routes; explicit names\n// route through /projects/:project/... Returns undefined when neither was set,\n// which is the signal to resolveProjectForVerb that it should look at the\n// registered projects and pick intelligently.\nfunction resolveProjectFlag(parsed: ParsedArgs): string | undefined {\n if (parsed.project) return parsed.project\n const env = process.env.NEAT_PROJECT\n if (env && env.length > 0 && env !== DEFAULT_PROJECT) return env\n return undefined\n}\n\n// Thrown when a bare query verb (no --project, no NEAT_PROJECT) can't pick a\n// project on its own — either nothing is registered, or several are and none\n// is named `default`. Carries an exit code so the dispatcher can surface a\n// helpful message instead of letting the request 404 on the `default` slot.\nexport class ProjectResolutionError extends Error {\n constructor(\n message: string,\n public readonly exitCode: number = 2,\n ) {\n super(message)\n this.name = 'ProjectResolutionError'\n }\n}\n\n// What `GET /projects` hands back (registry.ts RegistryEntry passthrough). We\n// only read `name`, so keep the shape minimal.\ninterface RegistryProjectSummary {\n name: string\n}\n\n// Decide which project a bare query verb should route to (issue #500). When the\n// user passed --project or set NEAT_PROJECT, that wins untouched. Otherwise we\n// ask the daemon which projects it has registered and pick:\n//\n// • exactly one registered → use it (the one-command `npx neat.is` case, so\n// `neat divergences` \"just works\" without --project)\n// • a project literally named `default` exists → keep the legacy default\n// routing (return undefined → unprefixed routes the server maps to default)\n// • several registered, none `default` → don't guess; error and list them\n// • none registered → error clearly rather than 404 on `default`\n//\n// A daemon that can't be reached lets the TransportError propagate, so the verb\n// still exits 3 with the existing \"is the daemon running?\" message.\nexport async function resolveProjectForVerb(\n client: HttpClient,\n parsed: ParsedArgs,\n): Promise<string | undefined> {\n const explicit = resolveProjectFlag(parsed)\n if (explicit) return explicit\n\n // Bare verb. Let TransportError out (exit 3); only HttpError/parse issues\n // become a resolution error here.\n const projects = await client.get<RegistryProjectSummary[]>('/projects')\n\n if (projects.some((p) => p.name === DEFAULT_PROJECT)) {\n // Back-compat: a real `default` project exists, so the legacy unprefixed\n // routes resolve. Returning undefined keeps that path.\n return undefined\n }\n\n if (projects.length === 1) {\n return projects[0]!.name\n }\n\n if (projects.length === 0) {\n throw new ProjectResolutionError(\n 'No projects are registered with the daemon yet. Run `npx neat.is` in a repo to build a graph first, then re-run this command.',\n )\n }\n\n const names = projects\n .map((p) => p.name)\n .sort()\n .map((n) => ` ${n}`)\n .join('\\n')\n throw new ProjectResolutionError(\n `Several projects are registered and none is named \"default\", so I can't pick one for you.\\n` +\n `Pass --project <name> to choose:\\n${names}`,\n )\n}\n\n// The daemon URL the CLI verbs talk to. Resolution mirrors the client-profiles\n// precedence (§3): an explicit env pin wins, then the requested project's own\n// per-project daemon (ADR-096 — one daemon per project, each on its own port),\n// then the loopback default. `NEAT_API_URL` is the name the verbs have always\n// read, so it keeps precedence for existing users; `NEAT_CORE_URL` is honored\n// as an alias so a single env var works for both the CLI and the MCP server.\n//\n// The project step is issue #579: with `--project foo` (or NEAT_PROJECT=foo)\n// but no env pin, the verb used to hit the loopback 8080 and append\n// `/projects/foo/...`, which lands on whatever daemon happens to own 8080 — a\n// different project's daemon, so it 404s. Under one-daemon-per-project the\n// project's REST port lives in its discovery record at `~/.neat/daemons/<foo>.json`;\n// resolving it there points the verb at the right daemon. A project that has no\n// discovery record falls through to loopback, unchanged.\nexport async function resolveDaemonUrl(project?: string): Promise<string> {\n const explicit = process.env.NEAT_API_URL ?? process.env.NEAT_CORE_URL\n if (explicit) return explicit\n if (project) {\n const daemon = await findDaemonByProject(project)\n if (daemon) return `http://localhost:${daemon.record.ports.rest}`\n }\n return 'http://localhost:8080'\n}\n\nexport async function runQueryVerb(cmd: string, parsed: ParsedArgs): Promise<number> {\n // Resolve the URL against the requested project up front (issue #579). When\n // the project comes from --project / NEAT_PROJECT it's known synchronously, so\n // the client points at that project's daemon before the first call. A bare\n // verb (no project named) resolves nothing here and keeps the loopback default\n // — its project is discovered from /projects below (issue #500).\n const requestedProject = resolveProjectFlag(parsed)\n const baseUrl = await resolveDaemonUrl(requestedProject)\n // ADR-073 §3 — read the bearer once and thread it into the single client\n // every verb shares, so no verb path can reach a secured daemon without it.\n const client = createHttpClient(baseUrl, resolveAuthToken())\n const positional = parsed.positional\n\n // Per-verb arg/flag validation runs first so misuse exits 2 before any\n // network call (ADR-050 #4). Each case builds a thunk that takes the\n // resolved project — we resolve the project (issue #500) only after the verb\n // proves well-formed, since resolution itself hits the daemon's /projects.\n let makeWork: (project: string | undefined) => Promise<VerbResult>\n switch (cmd) {\n case 'root-cause': {\n const node = positional[0]\n if (!node) {\n console.error('neat root-cause: missing <node-id>')\n return 2\n }\n makeWork = (project) => runRootCause(client, {\n errorNode: node,\n ...(parsed.errorId ? { errorId: parsed.errorId } : {}),\n ...(project ? { project } : {}),\n })\n break\n }\n case 'blast-radius': {\n const node = positional[0]\n if (!node) {\n console.error('neat blast-radius: missing <node-id>')\n return 2\n }\n makeWork = (project) => runBlastRadius(client, {\n nodeId: node,\n ...(parsed.depth !== null ? { depth: parsed.depth } : {}),\n ...(project ? { project } : {}),\n })\n break\n }\n case 'dependencies': {\n const node = positional[0]\n if (!node) {\n console.error('neat dependencies: missing <node-id>')\n return 2\n }\n makeWork = (project) => runDependencies(client, {\n nodeId: node,\n ...(parsed.depth !== null ? { depth: parsed.depth } : {}),\n ...(project ? { project } : {}),\n })\n break\n }\n case 'observed-dependencies': {\n const node = positional[0]\n if (!node) {\n console.error('neat observed-dependencies: missing <node-id>')\n return 2\n }\n makeWork = (project) => runObservedDependencies(client, {\n nodeId: node,\n ...(project ? { project } : {}),\n })\n break\n }\n case 'incidents': {\n // node-id is optional — bare `neat incidents` returns the global log.\n makeWork = (project) => runIncidents(client, {\n ...(positional[0] ? { nodeId: positional[0] } : {}),\n ...(parsed.limit !== null ? { limit: parsed.limit } : {}),\n ...(project ? { project } : {}),\n })\n break\n }\n case 'search': {\n const q = positional.join(' ').trim()\n if (!q) {\n console.error('neat search: missing <query>')\n return 2\n }\n makeWork = (project) => runSearch(client, { query: q, ...(project ? { project } : {}) })\n break\n }\n case 'diff': {\n // --against names a snapshot file the core can resolve via\n // loadSnapshotForDiff. --since is reserved for a future date-range\n // mode (the contract lists it as `[--since <date>]`); for MVP, the\n // diff verb requires --against.\n const against = parsed.against ?? parsed.since\n if (!against) {\n console.error('neat diff: --against <snapshot-path> is required')\n return 2\n }\n makeWork = (project) => runDiff(client, {\n againstSnapshot: against,\n ...(project ? { project } : {}),\n })\n break\n }\n case 'stale-edges': {\n makeWork = (project) => runStaleEdges(client, {\n ...(parsed.limit !== null ? { limit: parsed.limit } : {}),\n ...(parsed.edgeType ? { edgeType: parsed.edgeType } : {}),\n ...(project ? { project } : {}),\n })\n break\n }\n case 'policies': {\n let hypothetical: ReturnType<typeof JSON.parse> | undefined\n if (parsed.hypotheticalAction) {\n try {\n hypothetical = JSON.parse(parsed.hypotheticalAction)\n } catch (err) {\n console.error(\n `neat policies: --hypothetical-action must be valid JSON: ${(err as Error).message}`,\n )\n return 2\n }\n }\n makeWork = (project) => runPolicies(client, {\n ...(parsed.node ? { nodeId: parsed.node } : {}),\n ...(hypothetical ? { hypotheticalAction: hypothetical } : {}),\n ...(project ? { project } : {}),\n })\n break\n }\n case 'divergences': {\n let typeFilter: DivergenceType[] | undefined\n if (parsed.type) {\n const parts = parsed.type\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0)\n const out: DivergenceType[] = []\n for (const p of parts) {\n const r = DivergenceTypeSchema.safeParse(p)\n if (!r.success) {\n console.error(\n `neat divergences: unknown --type \"${p}\". allowed: ${DivergenceTypeSchema.options.join(', ')}`,\n )\n return 2\n }\n out.push(r.data)\n }\n typeFilter = out\n }\n makeWork = (project) => runDivergences(client, {\n ...(typeFilter ? { type: typeFilter } : {}),\n ...(parsed.minConfidence !== null ? { minConfidence: parsed.minConfidence } : {}),\n ...(parsed.node ? { node: parsed.node } : {}),\n ...(project ? { project } : {}),\n })\n break\n }\n default:\n // Unreachable — QUERY_VERBS gates the dispatch.\n console.error(`neat: unknown query verb \"${cmd}\"`)\n return 2\n }\n\n try {\n // Resolve which project to route to (issue #500). When --project /\n // NEAT_PROJECT are set this is a no-op; otherwise it asks the daemon's\n // /projects list and picks the single registered one (or keeps `default`).\n // A TransportError from here means the daemon is down — same exit-3 path as\n // any verb call.\n const project = await resolveProjectForVerb(client, parsed)\n const result = await makeWork(project)\n if (parsed.json) process.stdout.write(formatJson(result) + '\\n')\n else process.stdout.write(formatHuman(result) + '\\n')\n return 0\n } catch (err) {\n // Server / transport errors land on stderr per ADR-050 #3 (stderr for\n // diagnostics, stdout for results — never mix). Exit code branches per\n // ADR-050 #4: 1 for HttpError, 3 for TransportError.\n if (err instanceof ProjectResolutionError) {\n // Couldn't pick a project on the user's behalf (none registered, or\n // several and none named `default`). The message already says what to do.\n console.error(`neat ${cmd}: ${err.message}`)\n return err.exitCode\n }\n if (err instanceof HttpError) {\n const detail = err.responseBody.length > 0 ? err.responseBody : err.message\n console.error(`neat ${cmd}: ${detail.trim()}`)\n } else if (err instanceof TransportError) {\n console.error(`neat ${cmd}: ${err.message}. Is the daemon running? (endpoint=${baseUrl})`)\n } else {\n console.error(`neat ${cmd}: ${(err as Error).message}`)\n }\n return exitCodeForError(err)\n }\n}\n\n// Only auto-run when invoked as the CLI entry point. Importing this module\n// from tests must not start the parser; otherwise vitest sees a stray\n// `process.exit` from `main()` running with no argv. The separator class\n// `[\\\\/]` matches Windows paths too — the bin shim lands as `…\\bin\\neat`, so a\n// forward-slash-only check would leave `main()` unfired and the CLI a no-op.\nconst entry = process.argv[1] ?? ''\nif (/[\\\\/](?:cli\\.(?:cjs|js)|cli|neat|neat\\.is)$/.test(entry)) {\n main().catch((err) => {\n console.error(err)\n process.exit(1)\n })\n}\n","import path from 'node:path'\nimport { readFileSync } from 'node:fs'\nimport { fileURLToPath } from 'node:url'\n\n// The `neat --version` family reads its answer from the bundled package's\n// own package.json. Reading at run time keeps the published bin in lockstep\n// with whatever version `tsup` shipped without a build-time substitution.\n// `dist/cli.cjs` sits one level below the package root.\nexport function readPackageVersion(): string {\n const here =\n typeof __dirname !== 'undefined'\n ? __dirname\n : path.dirname(fileURLToPath(import.meta.url))\n // dist/ → package root. tsup writes both cjs and mjs to dist/, so the\n // parent-of-parent walk is the same in either format.\n const candidates = [\n path.resolve(here, '../package.json'),\n path.resolve(here, '../../package.json'),\n ]\n for (const candidate of candidates) {\n try {\n const raw = readFileSync(candidate, 'utf8')\n const parsed = JSON.parse(raw) as { name?: string; version?: string }\n if (parsed.name === '@neat.is/core' && typeof parsed.version === 'string') {\n return parsed.version\n }\n } catch {\n // try the next candidate\n }\n }\n return 'unknown'\n}\n\n// The ASCII banner. Shared between the CLI's `neat init` discovery report and\n// the one-command orchestrator (issue #483) so the artwork lives in exactly\n// one place — no duplicated glyphs to drift apart.\nexport function printBanner(): void {\n console.log('███╗ ██╗███████╗ █████╗ ████████╗')\n console.log('████╗ ██║██╔════╝██╔══██╗╚══██╔══╝')\n console.log('██╔██╗ ██║█████╗ ███████║ ██║ ')\n console.log('██║╚██╗██║██╔══╝ ██╔══██║ ██║ ')\n console.log('██║ ╚████║███████╗██║ ██║ ██║ ')\n console.log('╚═╝ ╚═══╝╚══════╝╚═╝ ╚═╝ ╚═╝ ')\n console.log('')\n console.log(' Network Expressive Architecting Tool')\n console.log(` neat.is · v${readPackageVersion()} · Apache 2.0`)\n console.log('')\n}\n","/**\n * `.gitignore` automation for the init flow (ADR-073 §6).\n *\n * Init writes a snapshot under `<projectDir>/neat-out/`. Un-ignored, that\n * directory leaks the snapshot into git history within one commit. The\n * helper here ensures `neat-out/` is present in `<projectDir>/.gitignore` —\n * appending to an existing file with a NEAT comment header, creating the\n * file when absent, no-oping when the line is already there.\n *\n * Idempotency rule: an exact-match line (`neat-out/` or `neat-out`, with\n * any surrounding whitespace) counts as already-present. No duplicate\n * line is written on a re-run.\n */\n\nimport { promises as fs } from 'node:fs'\nimport path from 'node:path'\n\nexport const NEAT_OUT_LINE = 'neat-out/'\nconst NEAT_HEADER = '# NEAT — machine-local snapshots and events'\n\nexport interface EnsureNeatOutResult {\n // 'added' when the line was appended to an existing .gitignore.\n // 'created' when the file did not exist and was created with a single line.\n // 'unchanged' when the line was already present.\n action: 'added' | 'created' | 'unchanged'\n // Absolute path to the .gitignore file, regardless of action.\n file: string\n}\n\nfunction isNeatOutLine(line: string): boolean {\n const trimmed = line.trim()\n return trimmed === 'neat-out/' || trimmed === 'neat-out'\n}\n\nexport async function ensureNeatOutIgnored(projectDir: string): Promise<EnsureNeatOutResult> {\n const file = path.join(projectDir, '.gitignore')\n let existing: string | null = null\n try {\n existing = await fs.readFile(file, 'utf8')\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err\n }\n\n if (existing === null) {\n await fs.writeFile(file, `${NEAT_HEADER}\\n${NEAT_OUT_LINE}\\n`, 'utf8')\n return { action: 'created', file }\n }\n\n for (const line of existing.split(/\\r?\\n/)) {\n if (isNeatOutLine(line)) return { action: 'unchanged', file }\n }\n\n // Append with a leading newline if the file doesn't already end in one,\n // so the comment header sits on its own line.\n const needsLeadingNewline = existing.length > 0 && !existing.endsWith('\\n')\n const appended = `${needsLeadingNewline ? '\\n' : ''}\\n${NEAT_HEADER}\\n${NEAT_OUT_LINE}\\n`\n await fs.writeFile(file, existing + appended, 'utf8')\n return { action: 'added', file }\n}\n","/**\n * Value-forward CLI summary (issue #305, ADR-073 §5).\n *\n * Replaces the per-type node/edge counts that ended `neat init` with a\n * findings-first block — compat violations, top divergences, services\n * that never produced an OBSERVED edge, and the OTel env-vars block the\n * operator pastes into their deploy platform. Per-type counts move behind\n * `--verbose`.\n *\n * The renderer is a pure string builder so tests can assert against its\n * output without spawning the CLI.\n */\n\nimport type { Divergence, GraphEdge, GraphNode, ServiceNode } from '@neat.is/types'\nimport { NodeType, Provenance } from '@neat.is/types'\nimport type { NeatGraph } from './graph.js'\n\nexport interface SummaryInput {\n graph: NeatGraph\n divergences: Divergence[]\n // True → render the per-type counts after the value-forward block.\n verbose: boolean\n}\n\n// Static placeholder. The orchestrator and `neat deploy` print the same\n// block; `neat deploy` substitutes the actual token + host. This shape\n// lives in one place so the wire format stays in step.\nexport function renderOtelEnvBlock(): string {\n return [\n 'for prod OTel routing, set these in your deploy platform\\'s env:',\n ' OTEL_EXPORTER_OTLP_ENDPOINT=https://<your-neat-host>:4318',\n ' OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer <NEAT_AUTH_TOKEN>',\n ].join('\\n')\n}\n\nfunction findIncompatServices(nodes: GraphNode[]): ServiceNode[] {\n return nodes.filter(\n (n): n is ServiceNode =>\n n.type === NodeType.ServiceNode &&\n Array.isArray((n as ServiceNode).incompatibilities) &&\n ((n as ServiceNode).incompatibilities ?? []).length > 0,\n )\n}\n\n// Services that show up in the EXTRACTED graph but have no OBSERVED edge\n// pointing at or out of them. The thesis says: when the OBSERVED layer is\n// silent on a service, the gap is a load-bearing signal for the operator.\nfunction servicesWithoutObserved(nodes: GraphNode[], edges: GraphEdge[]): ServiceNode[] {\n const seen = new Set<string>()\n for (const e of edges) {\n if (e.provenance === Provenance.OBSERVED) {\n seen.add(e.source)\n seen.add(e.target)\n }\n }\n return nodes.filter(\n (n): n is ServiceNode => n.type === NodeType.ServiceNode && !seen.has(n.id),\n )\n}\n\nfunction formatDivergence(d: Divergence): string {\n // Short, scannable, one-line-per-finding. The reason field already carries\n // the load-bearing detail; the recommendation rides on a second indent.\n const conf = d.confidence.toFixed(2)\n return ` [${conf}] ${d.type} ${d.source} → ${d.target} — ${d.reason}`\n}\n\nexport function renderValueForwardSummary(input: SummaryInput): string {\n const { graph, divergences, verbose } = input\n const nodes: GraphNode[] = []\n graph.forEachNode((_id, attrs) => nodes.push(attrs))\n const edges: GraphEdge[] = []\n graph.forEachEdge((_id, attrs) => edges.push(attrs))\n\n const lines: string[] = []\n lines.push('=== neat: findings ===')\n lines.push('')\n\n // ── Compat violations (driver/engine mismatches) ───────────────────────\n const incompatServices = findIncompatServices(nodes)\n const totalIncompats = incompatServices.reduce(\n (acc, s) => acc + (s.incompatibilities?.length ?? 0),\n 0,\n )\n lines.push(`compat violations: ${totalIncompats}`)\n for (const svc of incompatServices) {\n for (const inc of svc.incompatibilities ?? []) {\n const detail = formatIncompat(inc)\n lines.push(` ${svc.name}: ${detail}`)\n }\n }\n lines.push('')\n\n // ── Top divergences (top 3 by confidence desc) ─────────────────────────\n const top = [...divergences].sort((a, b) => b.confidence - a.confidence).slice(0, 3)\n lines.push(`top divergences: ${divergences.length} total${top.length > 0 ? ', top 3:' : ''}`)\n for (const d of top) lines.push(formatDivergence(d))\n lines.push('')\n\n // ── Services missing OBSERVED coverage ─────────────────────────────────\n const noObserved = servicesWithoutObserved(nodes, edges)\n if (noObserved.length > 0) {\n lines.push(`services without OBSERVED coverage: ${noObserved.length}`)\n for (const svc of noObserved) lines.push(` ${svc.name}`)\n lines.push(' → run your services with the generated otel-init to populate OBSERVED edges.')\n lines.push('')\n }\n\n // ── OTel env-vars block (static; `neat deploy` substitutes real values)\n lines.push(renderOtelEnvBlock())\n lines.push('')\n\n // ── --verbose: per-type node/edge counts ──────────────────────────────\n if (verbose) {\n const byNode = new Map<string, number>()\n for (const n of nodes) byNode.set(n.type, (byNode.get(n.type) ?? 0) + 1)\n const byEdge = new Map<string, number>()\n for (const e of edges) byEdge.set(e.type, (byEdge.get(e.type) ?? 0) + 1)\n lines.push('=== graph (verbose) ===')\n lines.push(`total: ${graph.order} nodes, ${graph.size} edges`)\n lines.push('nodes:')\n for (const [t, c] of [...byNode.entries()].sort()) lines.push(` ${t}: ${c}`)\n lines.push('edges:')\n for (const [t, c] of [...byEdge.entries()].sort()) lines.push(` ${t}: ${c}`)\n lines.push('')\n }\n\n return lines.join('\\n')\n}\n\nfunction formatIncompat(inc: NonNullable<ServiceNode['incompatibilities']>[number]): string {\n if (inc.kind === 'node-engine') {\n const range = inc.declaredNodeEngine ? ` (engines.node=\"${inc.declaredNodeEngine}\")` : ''\n return `${inc.package}@${inc.packageVersion ?? '?'} requires Node ${inc.requiredNodeVersion}${range} — ${inc.reason}`\n }\n if (inc.kind === 'package-conflict') {\n const found = inc.foundVersion ? `@${inc.foundVersion}` : ' (missing)'\n return `${inc.package}@${inc.packageVersion ?? '?'} requires ${inc.requires.name}>=${inc.requires.minVersion}; found ${inc.requires.name}${found} — ${inc.reason}`\n }\n if (inc.kind === 'deprecated-api') {\n return `${inc.package}@${inc.packageVersion ?? '?'} is deprecated — ${inc.reason}`\n }\n return `${inc.driver}@${inc.driverVersion} vs ${inc.engine} ${inc.engineVersion} — ${inc.reason}`\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport chokidar, { type FSWatcher } from 'chokidar'\nimport type { FastifyInstance } from 'fastify'\nimport type { NeatGraph } from './graph.js'\nimport { buildApi } from './api.js'\nimport { assertBindAuthority, readAuthEnv } from './auth.js'\nimport { ensureCompatLoaded } from './compat.js'\nimport { discoverServices, addServiceNodes } from './extract/services.js'\nimport { addServiceAliases } from './extract/aliases.js'\nimport { addFiles } from './extract/files.js'\nimport { addImports } from './extract/imports.js'\nimport { addDatabasesAndCompat } from './extract/databases/index.js'\nimport { addConfigNodes } from './extract/configs.js'\nimport { addCallEdges } from './extract/calls/index.js'\nimport { addInfra } from './extract/infra/index.js'\nimport { retireEdgesByFile } from './extract/retire.js'\nimport {\n makeErrorSpanWriter,\n makeSpanHandler,\n promoteFrontierNodes,\n startStalenessLoop,\n} from './ingest.js'\nimport {\n evaluateAllPolicies,\n loadPolicyFile,\n PolicyViolationsLog,\n} from './policy.js'\nimport type { Policy } from '@neat.is/types'\nimport { buildOtelReceiver, listenSteppingOtlp } from './otel.js'\nimport {\n clearDaemonRecord,\n portFromListenAddress,\n resolveNeatVersion,\n writeDaemonRecord,\n type DaemonRecord,\n} from './daemon.js'\nimport { startOtelGrpcReceiver } from './otel-grpc.js'\nimport { loadGraphFromDisk, startPersistLoop } from './persist.js'\nimport { buildSearchIndex, type SearchIndex } from './search.js'\nimport { DEFAULT_PROJECT } from './graph.js'\nimport { Projects, pathsForProject } from './projects.js'\nimport { attachGraphToEventBus, emitNeatEvent } from './events.js'\n\nexport type ExtractPhase =\n | 'services'\n | 'aliases'\n | 'files'\n | 'imports'\n | 'databases'\n | 'configs'\n | 'calls'\n | 'infra'\n\nconst ALL_PHASES: ExtractPhase[] = [\n 'services',\n 'aliases',\n 'files',\n 'imports',\n 'databases',\n 'configs',\n 'calls',\n 'infra',\n]\n\n// Map a changed path to the phases that need re-running. Anything not matched\n// here falls back to a full re-extract — better an extra ~50ms of work than a\n// missed update because the path didn't fit a regex.\n//\n// Mapping:\n// package.json / requirements.txt / pyproject.toml → services + aliases + databases\n// (deps drive compat; aliases pull from manifest fields)\n// .env / *.env.* / prisma / knex / ormconfig → databases + configs\n// docker-compose / Dockerfile / *.tf / k8s yaml → infra + aliases\n// (compose labels and Dockerfile labels feed alias discovery)\n// *.js / *.ts / *.tsx / *.py / *.jsx / *.mjs / *.cjs → files + imports + calls\n// (a source edit can shift both its IMPORTS and CALLS edges; the shared\n// evidence.file retirement mechanism — static-extraction.md §Ghost-edge\n// cleanup — drops the stale ones from either producer before re-running.\n// The `files` phase re-enumerates FileNodes first: retiring an edited\n// file's edges also drops its CONTAINS edge — whose evidence.file is the\n// file itself — and can orphan the FileNode, so Phase 1 has to rebuild it\n// before imports/calls originate edges from it, or addImports emits from a\n// node that no longer exists.)\n// *.yaml / *.yml that isn't compose → databases + configs (ORM yaml fallbacks)\nexport function classifyChange(relPath: string): Set<ExtractPhase> {\n const phases = new Set<ExtractPhase>()\n const base = path.basename(relPath).toLowerCase()\n const segments = relPath.split(path.sep).map((s) => s.toLowerCase())\n\n if (\n base === 'package.json' ||\n base === 'requirements.txt' ||\n base === 'pyproject.toml' ||\n base === 'setup.py'\n ) {\n phases.add('services')\n phases.add('aliases')\n phases.add('databases')\n }\n\n if (\n base === '.env' ||\n base.startsWith('.env.') ||\n base === 'schema.prisma' ||\n /^knexfile\\.(?:js|ts|cjs|mjs)$/.test(base) ||\n /^ormconfig\\.(?:js|ts|json|ya?ml)$/.test(base)\n ) {\n phases.add('databases')\n phases.add('configs')\n }\n\n if (\n base === 'dockerfile' ||\n /^docker-compose.*\\.ya?ml$/.test(base) ||\n base.endsWith('.tf') ||\n segments.includes('k8s') ||\n segments.includes('kustomize') ||\n segments.includes('manifests')\n ) {\n phases.add('infra')\n phases.add('aliases')\n }\n\n if (/\\.(?:js|jsx|mjs|cjs|ts|tsx|py)$/.test(base)) {\n phases.add('files')\n phases.add('imports')\n phases.add('calls')\n }\n\n if (/\\.ya?ml$/.test(base) && !/^docker-compose.*\\.ya?ml$/.test(base)) {\n // Generic yaml — could be an ORM file, k8s manifest, or random config.\n // Cheap to run databases + configs; if it was infra, the dir-name check\n // above already added that phase.\n phases.add('databases')\n phases.add('configs')\n }\n\n return phases\n}\n\ninterface RunPhasesResult {\n phases: ExtractPhase[]\n nodesAdded: number\n edgesAdded: number\n frontiersPromoted: number\n durationMs: number\n}\n\nexport async function runExtractPhases(\n graph: NeatGraph,\n scanPath: string,\n phases: Set<ExtractPhase>,\n // Project tag passed through for the runtime event bus (ADR-051) — not\n // required for extraction logic itself but threaded for parity with\n // extractFromDirectory's project option.\n project: string = DEFAULT_PROJECT,\n): Promise<RunPhasesResult> {\n void project\n const started = Date.now()\n await ensureCompatLoaded()\n // Discovery is cheap and every phase needs the same DiscoveredService list,\n // so we always re-walk. If the user moved a service directory, this is also\n // the path that picks it up.\n const services = await discoverServices(scanPath)\n\n let nodesAdded = 0\n let edgesAdded = 0\n\n if (phases.has('services')) {\n nodesAdded += addServiceNodes(graph, services)\n }\n if (phases.has('aliases')) {\n await addServiceAliases(graph, scanPath, services)\n }\n // Phase 1 — file enumeration runs before imports/calls (file-awareness.md §1).\n // Both of those producers originate edges from FileNodes; a re-extract driven\n // by a source edit has already retired that file's CONTAINS edge (its\n // evidence.file is the file itself) and may have swept the now-orphaned\n // FileNode, so rebuilding it here is what keeps addImports from emitting an\n // edge off a missing node. Idempotent — an unchanged tree is a no-op.\n if (phases.has('files')) {\n const r = await addFiles(graph, services)\n nodesAdded += r.nodesAdded\n edgesAdded += r.edgesAdded\n }\n if (phases.has('imports')) {\n const r = await addImports(graph, services)\n nodesAdded += r.nodesAdded\n edgesAdded += r.edgesAdded\n }\n if (phases.has('databases')) {\n const r = await addDatabasesAndCompat(graph, services, scanPath)\n nodesAdded += r.nodesAdded\n edgesAdded += r.edgesAdded\n }\n if (phases.has('configs')) {\n const r = await addConfigNodes(graph, services, scanPath)\n nodesAdded += r.nodesAdded\n edgesAdded += r.edgesAdded\n }\n if (phases.has('calls')) {\n const r = await addCallEdges(graph, services)\n nodesAdded += r.nodesAdded\n edgesAdded += r.edgesAdded\n }\n if (phases.has('infra')) {\n const r = await addInfra(graph, scanPath, services)\n nodesAdded += r.nodesAdded\n edgesAdded += r.edgesAdded\n }\n const frontiersPromoted = promoteFrontierNodes(graph)\n\n return {\n phases: ALL_PHASES.filter((p) => phases.has(p)),\n nodesAdded,\n edgesAdded,\n frontiersPromoted,\n durationMs: Date.now() - started,\n }\n}\n\n// The canonical dashboard port recorded in daemon.json. `neat watch` binds no\n// dashboard of its own, but the DaemonRecord shape requires a web port; only\n// ports.otlp is load-bearing for the OBSERVED endpoint resolution this record\n// exists to serve. Mirrors DEFAULT_WEB_PORT in web-spawn.ts.\nconst DEFAULT_WATCH_WEB_PORT = 6328\n\nexport interface WatchOptions {\n scanPath: string\n outPath: string\n errorsPath: string\n staleEventsPath: string\n embeddingsCachePath?: string\n // Project name this watch instance owns. Defaults to `default` for the\n // single-project workflow that's been the only one until #83.\n project?: string\n host?: string\n port?: number\n otelPort?: number\n otelGrpc?: boolean\n otelGrpcPort?: number\n debounceMs?: number\n}\n\nexport interface WatchHandle {\n api: FastifyInstance\n stop: () => Promise<void>\n}\n\n// Anymatch-compatible ignore set passed to chokidar (#233). The earlier\n// implementation passed a function alone, which forced chokidar to descend\n// into every subdirectory before testing the path. On macOS with kqueue\n// (chokidar 4 dropped fsevents in favour of kqueue), each subdir under the\n// scan root opens a watch handle; nested `node_modules` blew through the\n// per-process kqueue cap with EMFILE before the function-based ignore ever\n// fired. Globs let chokidar prune at descent time — the dirs are never\n// opened in the first place.\nconst IGNORED_WATCH_GLOBS = [\n '**/node_modules/**',\n '**/.git/**',\n '**/dist/**',\n '**/build/**',\n '**/.turbo/**',\n '**/.next/**',\n '**/neat-out/**',\n // Python venv shapes (issue #344). chokidar opens one watch handle per\n // descended dir; a CPython venv carries 20k+ files and trivially blows\n // through the macOS kqueue cap before extraction even runs.\n '**/.venv/**',\n '**/venv/**',\n '**/__pypackages__/**',\n '**/.tox/**',\n '**/site-packages/**',\n '**/.DS_Store',\n]\n\n// Backstop regex set — covers anything chokidar surfaces post-descent that\n// the globs missed (e.g. a path containing one of these segments at an\n// unexpected depth). Same shape as before; the globs are the load-bearing\n// pruning, this is defence in depth.\nconst IGNORED_WATCH_PATHS = [\n /(?:^|[\\\\/])node_modules[\\\\/]/,\n /(?:^|[\\\\/])\\.git[\\\\/]/,\n /(?:^|[\\\\/])dist[\\\\/]/,\n /(?:^|[\\\\/])build[\\\\/]/,\n /(?:^|[\\\\/])\\.turbo[\\\\/]/,\n /(?:^|[\\\\/])\\.next[\\\\/]/,\n /(?:^|[\\\\/])neat-out[\\\\/]/,\n /(?:^|[\\\\/])\\.venv[\\\\/]/,\n /(?:^|[\\\\/])venv[\\\\/]/,\n /(?:^|[\\\\/])__pypackages__[\\\\/]/,\n /(?:^|[\\\\/])\\.tox[\\\\/]/,\n /(?:^|[\\\\/])site-packages[\\\\/]/,\n /[\\\\/]?\\.DS_Store$/,\n]\n\nfunction shouldIgnore(absPath: string): boolean {\n return IGNORED_WATCH_PATHS.some((re) => re.test(absPath))\n}\n\n// Roughly the number of immediate, non-ignored subdirectories in the scan\n// root above which `neat watch` should fall back to polling on darwin. kqueue\n// opens one handle per watched dir; macOS's per-process file-descriptor cap\n// is typically 256 (soft) / unlimited (hard) but raising the hard cap doesn't\n// help with the kqueue-specific limits. Empirically anything north of ~500\n// non-ignored dirs starts to flirt with EMFILE. Threshold sits comfortably\n// under that.\nconst DARWIN_POLLING_DIR_THRESHOLD = 400\n\n// Fast non-recursive count: walk top-level entries only, descending one\n// level into non-ignored subdirs to capture the medusa-shaped case where\n// `packages/*` itself looks small but each contains a heavy `node_modules`.\n// Returns early once it crosses the threshold so we don't waste time on huge\n// repos.\nfunction countWatchableDirs(scanPath: string, limit: number): number {\n let count = 0\n const visit = (dir: string, depth: number): void => {\n if (count >= limit) return\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true })\n } catch {\n return\n }\n for (const e of entries) {\n if (count >= limit) return\n if (!e.isDirectory()) continue\n if (IGNORED_WATCH_PATHS.some((re) => re.test(path.join(dir, e.name) + path.sep))) continue\n count++\n // One level deeper — enough to surface nested `node_modules` shapes\n // without traversing the whole tree.\n if (depth < 2) visit(path.join(dir, e.name), depth + 1)\n }\n }\n visit(scanPath, 0)\n return count\n}\n\n// Darwin heuristic (#233). Forces chokidar onto polling when the scan root\n// is large enough that kqueue would EMFILE. Override via NEAT_WATCH_POLLING:\n// - \"1\" / \"true\" → force polling regardless of platform/threshold\n// - \"0\" / \"false\" → never poll (matches pre-#233 behaviour)\n// - unset → auto-detect on darwin\nfunction shouldUsePolling(scanPath: string): boolean {\n const env = process.env.NEAT_WATCH_POLLING\n if (env === '1' || env === 'true') return true\n if (env === '0' || env === 'false') return false\n if (process.platform !== 'darwin') return false\n return countWatchableDirs(scanPath, DARWIN_POLLING_DIR_THRESHOLD) >= DARWIN_POLLING_DIR_THRESHOLD\n}\n\nexport async function startWatch(\n graph: NeatGraph,\n opts: WatchOptions,\n): Promise<WatchHandle> {\n const debounceMs = opts.debounceMs ?? 1000\n const projectName = opts.project ?? DEFAULT_PROJECT\n\n await loadGraphFromDisk(graph, opts.outPath)\n\n // Wire graph mutations into the event bus (ADR-051) before extract begins\n // so the initial pass also produces node/edge events. Detached on stop().\n const detachEventBus = attachGraphToEventBus(graph, { project: projectName })\n\n // Load policies + open the violations log once at startup. policy.json\n // lives at the project root per ADR-042 §File location; absent file is\n // a perfectly fine state (loadPolicyFile returns []). Reload-on-change\n // is queued for v0.2.5 — the kickoff doc tracks it.\n const policyFilePath = path.join(opts.scanPath, 'policy.json')\n const policyViolationsPath = path.join(path.dirname(opts.outPath), 'policy-violations.ndjson')\n let policies: Policy[] = []\n try {\n policies = await loadPolicyFile(policyFilePath)\n if (policies.length > 0) {\n console.log(`policies: loaded ${policies.length} from ${policyFilePath}`)\n }\n } catch (err) {\n console.warn(`policies: failed to load ${policyFilePath} — ${(err as Error).message}`)\n }\n const policyLog = new PolicyViolationsLog(policyViolationsPath, projectName)\n\n // Single shared trigger callback wired into post-ingest, post-extract, and\n // post-stale per ADR-043. Failures append to console.warn but don't kill\n // the daemon — a malformed evaluator shouldn't take down ingest.\n const onPolicyTrigger = async (g: NeatGraph): Promise<void> => {\n if (policies.length === 0) return\n try {\n const violations = evaluateAllPolicies(g, policies, { now: () => Date.now() })\n for (const v of violations) await policyLog.append(v)\n } catch (err) {\n console.warn(`policies: evaluation failed — ${(err as Error).message}`)\n }\n }\n\n // The post-extract trigger fires from extractFromDirectory via opts.\n // For the initial extract here we run it inline so violations land on\n // startup before the receiver opens. Subsequent watch-driven re-extract\n // passes go through runExtractPhases which doesn't take the hook directly\n // — we run it after each flush() instead.\n const initial = await runExtractPhases(\n graph,\n opts.scanPath,\n new Set(ALL_PHASES),\n projectName,\n )\n console.log(\n `extract: ${initial.nodesAdded} new nodes, ${initial.edgesAdded} new edges (graph total ${graph.order}/${graph.size})`,\n )\n // extraction-complete for the initial pass (ADR-051). runExtractPhases\n // doesn't emit on its own — the event lives at the watch / orchestrator\n // boundary so the daemon can swap in its own emission shape.\n emitNeatEvent({\n type: 'extraction-complete',\n project: projectName,\n payload: {\n project: projectName,\n fileCount: 0,\n nodesAdded: initial.nodesAdded,\n edgesAdded: initial.edgesAdded,\n },\n })\n await onPolicyTrigger(graph)\n\n const stopPersist = startPersistLoop(graph, opts.outPath)\n const stopStaleness = startStalenessLoop(graph, {\n staleEventsPath: opts.staleEventsPath,\n project: projectName,\n onPolicyTrigger,\n })\n\n // ADR-073 §3/§4 + issue #341 — `neat watch` follows the same bind discipline\n // as the daemon: an explicit host wins; otherwise loopback-only without a\n // token (laptop dev), public bind once `NEAT_AUTH_TOKEN` is set. buildApi\n // mounts the bearer gate from the same env, so a token-protected watch\n // returns 401 to unauthenticated callers exactly as `neatd` does.\n const auth = readAuthEnv()\n const host = opts.host ?? (auth.authToken ? '0.0.0.0' : '127.0.0.1')\n assertBindAuthority(host, auth.authToken)\n const port = opts.port ?? 8080\n const otelPort = opts.otelPort ?? 4318\n\n const cachePath =\n opts.embeddingsCachePath ?? path.join(path.dirname(opts.outPath), 'embeddings.json')\n let searchIndex: SearchIndex | undefined\n try {\n searchIndex = await buildSearchIndex(graph, { cachePath })\n console.log(`semantic_search: ${searchIndex.provider} provider`)\n } catch (err) {\n console.warn(\n `semantic_search: index build failed (${(err as Error).message}); falling back to inline substring`,\n )\n }\n\n const registry = new Projects()\n registry.set(projectName, {\n graph,\n scanPath: opts.scanPath,\n paths: {\n // Paths are derived from the explicit options the watch caller passes\n // — pathsForProject is only used to fill in the embeddings/snapshot\n // fields so the registry shape is complete.\n ...pathsForProject(projectName, path.dirname(opts.outPath)),\n snapshotPath: opts.outPath,\n errorsPath: opts.errorsPath,\n staleEventsPath: opts.staleEventsPath,\n },\n searchIndex,\n })\n\n const api = await buildApi({ projects: registry })\n const restAddress = await api.listen({ port, host })\n console.log(`neat-core listening on http://${host}:${port}`)\n console.log(` scan path: ${opts.scanPath} (watching for changes)`)\n console.log(` snapshot path: ${opts.outPath}`)\n console.log(` errors log: ${opts.errorsPath}`)\n\n // The receiver writes ErrorEvents synchronously before reply (durability).\n // makeSpanHandler runs on the async queue and skips the inline write\n // because the receiver already handled it. Ad-hoc callers that bypass the\n // receiver (CLI tests, fixtures) leave writeErrorEventInline at its default\n // and get the in-handleSpan write. ADR-033 §Error events.\n const onSpan = makeSpanHandler({\n graph,\n errorsPath: opts.errorsPath,\n scanPath: opts.scanPath,\n project: projectName,\n writeErrorEventInline: false,\n onPolicyTrigger,\n })\n const onErrorSpanSync = makeErrorSpanWriter(opts.errorsPath, graph, opts.scanPath)\n const otelHttp = await buildOtelReceiver({ onSpan, onErrorSpanSync })\n // A held OTLP port steps to the next free one rather than crashing the watch\n // process (daemon.md §Binding). The real bound port is what daemon.json\n // records below, so the instrumented app's otel-init resolves the right one.\n const otelAddress = await listenSteppingOtlp(otelHttp, otelPort, host)\n const boundOtelPort = portFromListenAddress(otelAddress, otelPort)\n console.log(`neat-core OTLP receiver on ${otelAddress}/v1/traces`)\n\n // Self-description (project-daemon §2). `neat watch` is a per-project daemon\n // in the dev loop: the generated otel-init resolves its OTLP endpoint from\n // `<project>/neat-out/daemon.json` `ports.otlp`, so an app instrumented\n // against a watch bound to a non-default (or stepped) OTLP port would fall\n // back to `:4318` and dark OBSERVED without this record.\n const boundRestPort = portFromListenAddress(restAddress, port)\n const daemonRecord: DaemonRecord = {\n project: projectName,\n projectPath: opts.scanPath,\n pid: process.pid,\n status: 'running',\n ports: {\n rest: boundRestPort,\n otlp: boundOtelPort,\n // watch serves no dashboard of its own; record the canonical web port so\n // the record shape is valid. Only ports.otlp is load-bearing here.\n web: DEFAULT_WATCH_WEB_PORT,\n },\n startedAt: new Date().toISOString(),\n neatVersion: resolveNeatVersion(),\n }\n try {\n await writeDaemonRecord(daemonRecord)\n console.log(\n `neat watch: wrote daemon.json (REST ${boundRestPort} / OTLP ${boundOtelPort})`,\n )\n } catch (err) {\n // The record is load-bearing for the OBSERVED layer; without it the app\n // silently falls back to :4318. Fail loud rather than run half-dark.\n await api.close().catch(() => {})\n await otelHttp.close().catch(() => {})\n throw new Error(\n `neat watch: failed to write daemon.json — ${(err as Error).message}`,\n )\n }\n\n let grpcReceiver: { stop: () => Promise<void> } | null = null\n if (opts.otelGrpc) {\n const grpcPort = opts.otelGrpcPort ?? 4317\n // gRPC handler keeps the inline ErrorEvent write — the gRPC receiver\n // awaits onSpan synchronously (otel-grpc.ts), so the same durability\n // guarantee is met without a separate sync hook. Non-blocking gRPC\n // ingest is out of scope for the v0.2.2 batch.\n const onSpanGrpc = makeSpanHandler({\n graph,\n errorsPath: opts.errorsPath,\n scanPath: opts.scanPath,\n project: projectName,\n onPolicyTrigger,\n })\n const r = await startOtelGrpcReceiver({ onSpan: onSpanGrpc, host, port: grpcPort })\n console.log(`neat-core OTLP/gRPC receiver on ${r.address}`)\n grpcReceiver = r\n }\n\n // Coalesce bursts of changes into a single re-extract. chokidar fires one\n // event per affected path; an editor save can produce 3+ events on the same\n // file in <50ms.\n const pending = new Set<ExtractPhase>()\n const pendingPaths = new Set<string>()\n let timer: NodeJS.Timeout | null = null\n let inflight: Promise<void> | null = null\n\n const flush = async (): Promise<void> => {\n if (pending.size === 0) return\n const phases = new Set(pending)\n const paths = new Set(pendingPaths)\n pending.clear()\n pendingPaths.clear()\n try {\n // Drop EXTRACTED edges keyed to changed paths first, so the producer's\n // idempotent re-extract recreates only the edges that still apply.\n // Without this, edges from deleted code would survive forever\n // (docs/contracts/static-extraction.md §Ghost-edge cleanup).\n let retired = 0\n for (const p of paths) retired += retireEdgesByFile(graph, p)\n const result = await runExtractPhases(graph, opts.scanPath, phases, projectName)\n console.log(\n `[watch] re-extract phases=${result.phases.join(',')} retired=${retired} +${result.nodesAdded}n/+${result.edgesAdded}e in ${result.durationMs}ms`,\n )\n // extraction-complete after every re-extract pass (ADR-051). fileCount\n // is the number of paths that drove the pass — closest signal we have\n // for \"how much source moved\" without per-phase accounting.\n emitNeatEvent({\n type: 'extraction-complete',\n project: projectName,\n payload: {\n project: projectName,\n fileCount: paths.size,\n nodesAdded: result.nodesAdded,\n edgesAdded: result.edgesAdded,\n },\n })\n if (searchIndex) {\n try {\n await searchIndex.refresh(graph)\n } catch (err) {\n console.warn('[watch] semantic_search refresh failed', err)\n }\n }\n // Post-extract policy trigger (ADR-043). The runExtractPhases call\n // doesn't take the hook directly — it runs through promoteFrontierNodes\n // for FRONTIER → OBSERVED upgrades but doesn't load policies itself.\n // Firing the evaluator here keeps the trigger surface symmetric across\n // ingest / extract / stale paths.\n await onPolicyTrigger(graph)\n } catch (err) {\n console.error('[watch] re-extract failed', err)\n }\n }\n\n const schedule = (): void => {\n if (timer) clearTimeout(timer)\n timer = setTimeout(() => {\n timer = null\n // Serialise re-extracts so two flushes can't interleave on the graph.\n inflight = (inflight ?? Promise.resolve()).then(flush)\n }, debounceMs)\n }\n\n const onPath = (absPath: string): void => {\n if (shouldIgnore(absPath)) return\n const rel = path.relative(opts.scanPath, absPath)\n if (!rel || rel.startsWith('..')) return\n pendingPaths.add(rel.split(path.sep).join('/'))\n const phases = classifyChange(rel)\n if (phases.size === 0) {\n // Unknown file kind — fall back to full re-extract rather than silently\n // miss it. Cheaper than the user wondering why their change didn't show.\n for (const p of ALL_PHASES) pending.add(p)\n } else {\n for (const p of phases) pending.add(p)\n }\n schedule()\n }\n\n const usePolling = shouldUsePolling(opts.scanPath)\n if (usePolling) {\n const reason =\n process.env.NEAT_WATCH_POLLING === '1' || process.env.NEAT_WATCH_POLLING === 'true'\n ? 'NEAT_WATCH_POLLING env override'\n : 'darwin heuristic — large scan root, kqueue cap risk'\n console.log(`[${projectName}] watch: usePolling=true (${reason})`)\n }\n const watcher: FSWatcher = chokidar.watch(opts.scanPath, {\n ignoreInitial: true,\n // Glob array prunes at descent time (#233) so chokidar never opens a\n // kqueue handle for `node_modules` and friends. The function backstop\n // catches any path that slipped through and matches the regex set.\n ignored: [...IGNORED_WATCH_GLOBS, (p: string) => shouldIgnore(p)],\n persistent: true,\n usePolling,\n awaitWriteFinish: { stabilityThreshold: 200, pollInterval: 50 },\n })\n watcher.on('add', onPath)\n watcher.on('change', onPath)\n watcher.on('unlink', onPath)\n watcher.on('addDir', onPath)\n watcher.on('unlinkDir', onPath)\n\n let stopped = false\n const stop = async (): Promise<void> => {\n if (stopped) return\n stopped = true\n if (timer) clearTimeout(timer)\n timer = null\n if (inflight) {\n try {\n await inflight\n } catch {\n // surfaced already in flush()\n }\n }\n await watcher.close()\n stopStaleness()\n stopPersist()\n detachEventBus()\n await api.close()\n await otelHttp.close()\n if (grpcReceiver) await grpcReceiver.stop()\n // Reconcile the self-description on shutdown (project-daemon §2) so a\n // stopped watch never leaves a `running` record pointing an app at a\n // receiver nothing is listening on.\n await clearDaemonRecord(daemonRecord).catch(() => {})\n }\n\n return { api, stop }\n}\n","/**\n * `neat deploy` substrate detection + artifact generation (ADR-073 §2).\n *\n * Three substrates, detected in order:\n *\n * 1. Docker + `docker compose` present → emit `docker-compose.neat.yml`.\n * 2. Bare machine with `systemctl` available → emit `neat.service`.\n * 3. Fallback → print a `docker run` snippet to stdout.\n *\n * Every branch generates a fresh `NEAT_AUTH_TOKEN` (32 bytes, base64url),\n * prints it once, and never embeds it in the on-disk artifact — the file\n * names the env-var, the operator stores the value out of band.\n *\n * Every branch also prints the OTel env-vars block the operator pastes into\n * their application services' deploy platform.\n */\n\nimport { promises as fs } from 'node:fs'\nimport path from 'node:path'\nimport { spawn } from 'node:child_process'\nimport { randomBytes } from 'node:crypto'\n\nexport type Substrate = 'docker-compose' | 'systemd' | 'docker-run'\n\nexport interface DetectOptions {\n cwd?: string\n // Detection is shellable-out by injected probes; tests pass these to avoid\n // depending on the local docker / systemctl installation.\n hasDocker?: () => Promise<boolean>\n hasSystemd?: () => Promise<boolean>\n}\n\nexport interface DeployArtifact {\n substrate: Substrate\n // Path written to disk; undefined for the docker-run fallback (stdout-only).\n artifactPath?: string\n // The newly generated bearer token. Printed once by the caller, never\n // re-read from disk.\n token: string\n // The body of the artifact. Always returned so callers (and tests) can\n // inspect what was written without re-reading the file.\n contents: string\n // The shell command the operator runs to bring NEAT up on this substrate.\n startCommand: string\n}\n\nexport function generateToken(): string {\n // 32 bytes → 43-byte base64url (no padding). Plenty of entropy; URL-safe\n // so the operator can paste it into env-var dashboards that escape `=`.\n return randomBytes(32).toString('base64url')\n}\n\nasync function probeBinary(binary: string, arg: string): Promise<boolean> {\n return new Promise((resolve) => {\n const child = spawn(binary, [arg], { stdio: 'ignore' })\n const timer = setTimeout(() => {\n child.kill('SIGKILL')\n resolve(false)\n }, 2000)\n child.once('error', () => {\n clearTimeout(timer)\n resolve(false)\n })\n child.once('exit', (code) => {\n clearTimeout(timer)\n resolve(code === 0)\n })\n })\n}\n\nexport async function detectSubstrate(opts: DetectOptions = {}): Promise<Substrate> {\n const hasDocker = opts.hasDocker ?? (() => probeBinary('docker', 'version'))\n const hasSystemd = opts.hasSystemd ?? (() => probeBinary('systemctl', '--version'))\n if (await hasDocker()) return 'docker-compose'\n if (await hasSystemd()) return 'systemd'\n return 'docker-run'\n}\n\nconst IMAGE = 'ghcr.io/neat-technologies/neat:latest'\n\nexport function emitDockerCompose(cwd: string): string {\n // Compose v3 — declares the three documented ports + a data volume. The\n // operator's deploy platform supplies `NEAT_AUTH_TOKEN`; the file names\n // the var with no default, so a missing env stops the container from\n // coming up rather than running unauthenticated.\n return [\n 'services:',\n ' neat:',\n ` image: ${IMAGE}`,\n ' restart: unless-stopped',\n ' environment:',\n ' NEAT_AUTH_TOKEN: ${NEAT_AUTH_TOKEN:?NEAT_AUTH_TOKEN must be set}',\n ' ports:',\n ' - \"8080:8080\"',\n ' - \"4318:4318\"',\n ' - \"6328:6328\"',\n ' volumes:',\n ` - ${cwd}:/workspace`,\n ' - ./neat-data:/neat-out',\n '',\n ].join('\\n')\n}\n\nexport function emitSystemdUnit(cwd: string): string {\n // Token lives in /etc/neat/neatd.env (NEAT_AUTH_TOKEN=...) so it's readable\n // only by root and the service user. The unit itself stays version-\n // controllable without leaking the secret.\n return [\n '# NEAT_AUTH_TOKEN is read from /etc/neat/neatd.env at startup.',\n '# Put `NEAT_AUTH_TOKEN=<value>` in that file with mode 0640 root:root.',\n '[Unit]',\n 'Description=NEAT daemon',\n 'After=network-online.target',\n 'Wants=network-online.target',\n '',\n '[Service]',\n 'Type=simple',\n 'ExecStart=/usr/local/bin/neatd start --foreground',\n `WorkingDirectory=${cwd}`,\n 'EnvironmentFile=/etc/neat/neatd.env',\n 'Restart=always',\n 'RestartSec=5',\n '',\n '[Install]',\n 'WantedBy=multi-user.target',\n '',\n ].join('\\n')\n}\n\nexport function emitDockerRunSnippet(): string {\n // Single-line `docker run` for substrates we can't detect. Operator pastes\n // their own token in; the variable name keeps the bearer-token-must-be-set\n // shape consistent across all three branches.\n return [\n '#!/usr/bin/env bash',\n 'set -euo pipefail',\n '',\n '# Generate a fresh token once, then store it where your secrets live.',\n ': \"${NEAT_AUTH_TOKEN:?NEAT_AUTH_TOKEN must be set}\"',\n '',\n `docker run -d --name neat \\\\`,\n ' -e NEAT_AUTH_TOKEN=\"$NEAT_AUTH_TOKEN\" \\\\',\n ' -p 8080:8080 -p 4318:4318 -p 6328:6328 \\\\',\n ' -v \"$PWD\":/workspace -v /var/lib/neat:/neat-out \\\\',\n ` ${IMAGE}`,\n '',\n ].join('\\n')\n}\n\nexport interface RenderDeployBlockOptions {\n substrate: Substrate\n // Host the operator's services will reach NEAT at. Defaults to a\n // placeholder so the operator notices and fills it in.\n host?: string\n}\n\n// The OTel env-vars block the operator pastes into their deploy platform.\n// Format matches the orchestrator summary so the two never drift.\nexport function renderOtelEnvBlock(token: string, host: string = '<host>'): string {\n return [\n `OTEL_EXPORTER_OTLP_ENDPOINT=https://${host}:4318`,\n `OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer ${token}`,\n 'OTEL_SERVICE_NAME=<service>',\n ].join('\\n')\n}\n\nexport async function runDeploy(opts: DetectOptions = {}): Promise<DeployArtifact> {\n const cwd = opts.cwd ?? process.cwd()\n const substrate = await detectSubstrate(opts)\n const token = generateToken()\n\n switch (substrate) {\n case 'docker-compose': {\n const artifactPath = path.join(cwd, 'docker-compose.neat.yml')\n const contents = emitDockerCompose(cwd)\n await fs.writeFile(artifactPath, contents, 'utf8')\n return {\n substrate,\n artifactPath,\n token,\n contents,\n startCommand: `NEAT_AUTH_TOKEN=${token} docker compose -f ${path.basename(artifactPath)} up -d`,\n }\n }\n case 'systemd': {\n const artifactPath = path.join(cwd, 'neat.service')\n const contents = emitSystemdUnit(cwd)\n await fs.writeFile(artifactPath, contents, 'utf8')\n return {\n substrate,\n artifactPath,\n token,\n contents,\n startCommand: [\n `sudo install -m 0640 -o root -g root <(echo NEAT_AUTH_TOKEN=${token}) /etc/neat/neatd.env`,\n `sudo install -m 0644 neat.service /etc/systemd/system/neat.service`,\n 'sudo systemctl daemon-reload && sudo systemctl enable --now neat',\n ].join(' && '),\n }\n }\n case 'docker-run':\n default: {\n const contents = emitDockerRunSnippet()\n // No on-disk artifact for the fallback — operator copies the snippet.\n return {\n substrate: 'docker-run',\n token,\n contents,\n startCommand: `NEAT_AUTH_TOKEN=${token} bash <(cat <<'EOF'\\n${contents}EOF\\n)`,\n }\n }\n }\n}\n","/**\n * Node / TypeScript SDK installer (ADR-047 + ADR-069).\n *\n * Detects services by the presence of a `package.json` carrying a `name`\n * field — same shape `extract/services.ts` uses to decide what counts as a\n * Node service. The plan adds four OTel-adjacent packages to `dependencies`\n * (api, sdk-node, auto-instrumentations-node, dotenv), writes a generated\n * `otel-init.{js,ts}` adjacent to the resolved entry, and injects the\n * require/import as the first non-shebang line of that entry. Per-package\n * `.env.neat` carries `OTEL_SERVICE_NAME` (scope-preserved) so dashboards\n * joining OBSERVED spans against the EXTRACTED graph use the same key.\n *\n * Lockfiles are never touched (ADR-047 §4). The apply phase writes only to\n * package.json, otel-init.{js,ts}, and .env.neat (ADR-069 §7). After\n * `--apply`, init prints \"run npm install\" so the user owns the lockfile\n * commit.\n *\n * Idempotency (ADR-069 §6): the generated otel-init's presence is the\n * primary signal that a package is instrumented end-to-end — when it\n * exists, the apply phase logs `already instrumented` and skips the file\n * write and the entry-point injection together. Existing `.env.neat` files\n * are preserved (never overwritten).\n */\n\nimport { promises as fs } from 'node:fs'\nimport path from 'node:path'\nimport semver from 'semver'\nimport type {\n ApplyResult,\n DependencyEdit,\n EntrypointEdit,\n EnvEdit,\n GeneratedFile,\n Installer,\n InstallPlan,\n PlanOptions,\n} from './shared.js'\nimport {\n ASTRO_MIDDLEWARE_JS,\n ASTRO_MIDDLEWARE_TS,\n ASTRO_OTEL_INIT_JS,\n ASTRO_OTEL_INIT_TS,\n NEXT_INSTRUMENTATION_EDGE_JS,\n NEXT_INSTRUMENTATION_EDGE_TS,\n NEXT_INSTRUMENTATION_HEADER,\n NEXT_INSTRUMENTATION_JS,\n NEXT_INSTRUMENTATION_NODE_JS,\n NEXT_INSTRUMENTATION_NODE_TS,\n NEXT_INSTRUMENTATION_TS,\n NUXT_OTEL_INIT_JS,\n NUXT_OTEL_INIT_TS,\n NUXT_OTEL_PLUGIN_JS,\n NUXT_OTEL_PLUGIN_TS,\n OTEL_INIT_CJS,\n OTEL_INIT_ESM,\n OTEL_INIT_HEADER,\n OTEL_INIT_STAMP,\n OTEL_INIT_TS,\n REMIX_OTEL_SERVER_JS,\n REMIX_OTEL_SERVER_TS,\n SVELTEKIT_HOOKS_SERVER_JS,\n SVELTEKIT_HOOKS_SERVER_TS,\n SVELTEKIT_OTEL_INIT_JS,\n SVELTEKIT_OTEL_INIT_TS,\n renderEnvNeat,\n renderFrameworkOtelInit,\n renderNextInstrumentationNode,\n renderNodeOtelInit,\n} from './templates.js'\nimport { resolve as resolveRegistry } from '@neat.is/instrumentation-registry'\n\n// ADR-069 §5 — three OTel packages land in `dependencies`. `dotenv` was a\n// fourth from v0.3.6 through v0.4.3; the generated `otel-init` templates\n// no longer load `.env.neat` from disk (issue #369), so it's gone from the\n// dep set.\nconst SDK_PACKAGES = [\n { name: '@opentelemetry/api', version: '^1.9.0' },\n { name: '@opentelemetry/sdk-node', version: '^0.57.0' },\n { name: '@opentelemetry/auto-instrumentations-node', version: '^0.55.0' },\n] as const\n\n// ADR-126 — the Next.js edge-runtime file is the first named exception to\n// the four-deps invariant (framework-installers.md §6/§7): the standard Node\n// SDK can't execute inside Next's Edge runtime at all, so\n// instrumentation.edge.{ts,js} depends on `@vercel/otel` instead of the\n// shared SDK_PACKAGES set. Scoped to this one generated file's dependency\n// list — SDK_PACKAGES itself is untouched, and every other framework branch\n// keeps reading only SDK_PACKAGES.\nconst NEXT_EDGE_PACKAGES = [{ name: '@vercel/otel', version: '^2.1.3' }] as const\n\n// Issue #376 — non-bundled instrumentations. The auto-instrumentations-node\n// set covers HTTP, fetch, and the common DB drivers via the wire protocol,\n// but libraries that bypass those wires (Prisma's Rust query engine talks\n// to its own engine binary; LangChain wraps model calls in its own SDK)\n// need their own instrumentation package registered explicitly. The detected\n// entries here compose into the generated otel-init's `instrumentations`\n// array — one `instrumentations.push(...)` line per entry — and join the\n// package.json dep set so the registration line resolves at runtime.\n//\n// v0.4.5 scope is Prisma alone (first library that meaningfully widens\n// NEAT's OBSERVED coverage on real codebases). The function's interface is\n// stable so the v0.5.0 instrumentation registry (ADR-080) can return more\n// entries without revisiting the template.\ninterface NonBundledInstrumentation {\n pkg: string\n version: string\n registration: string\n}\n\n// Pull the leading integer out of a semver range. `^6.2.0`, `~6.2.0`, `6.x`,\n// `>=6.0.0 <7` all return 6. Anything we can't parse (workspace:*, file:…,\n// undefined) returns 0 so the caller falls through to the pre-Prisma-6 path.\nexport function getMajor(versionRange: string | undefined): number {\n if (!versionRange) return 0\n const match = versionRange.match(/(\\d+)/)\n return match ? parseInt(match[1], 10) : 0\n}\n\nexport function detectNonBundledInstrumentations(\n pkg: PackageJsonShape,\n): NonBundledInstrumentation[] {\n const deps = allDeps(pkg)\n const out: NonBundledInstrumentation[] = []\n if ('@prisma/client' in deps) {\n // Issue #381 — `@prisma/instrumentation@^5` doesn't speak Prisma 6's\n // tracing-helper API. Connecting the client throws\n // `this.getGlobalTracingHelper(...).dispatchEngineSpans is not a function`\n // before any user query lands. Mirror the Prisma major so the\n // instrumentation package matches the client surface.\n const prismaMajor = getMajor(deps['@prisma/client'])\n const prismaInstrVersion = prismaMajor >= 6 ? '^6.0.0' : '^5.0.0'\n out.push({\n pkg: '@prisma/instrumentation',\n version: prismaInstrVersion,\n registration:\n \"instrumentations.push(new (require('@prisma/instrumentation').PrismaInstrumentation)())\",\n })\n }\n return out\n}\n\nconst OTEL_ENV: EnvEdit = {\n // ADR-069 §4 — endpoint moves into the per-package .env.neat (written\n // by the apply phase). The envEdits surface stays for the dry-run\n // patch render: it documents the key/value the user can inspect in the\n // generated .env.neat.\n file: null,\n key: 'OTEL_EXPORTER_OTLP_TRACES_ENDPOINT',\n value: 'http://localhost:4318/projects/<project>/v1/traces',\n}\n\ninterface PackageJsonShape {\n name?: string\n type?: string\n main?: string\n bin?: string | Record<string, string>\n scripts?: Record<string, string>\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n}\n\n// v0.4.4 — `OTEL_SERVICE_NAME` regains its proper semantic role: the\n// ServiceNode id inside the project's graph, not the project name. v0.4.1\n// papered over the missing routing key by writing the project basename here;\n// the project-scoped OTLP URL (issue #367) means the URL carries the routing\n// key and the env var goes back to naming the ServiceNode.\nfunction serviceNodeName(pkg: PackageJsonShape, serviceDir: string): string {\n return pkg.name ?? path.basename(serviceDir)\n}\n\n// The URL routing key. When the orchestrator threads a project through we use\n// it verbatim; ad-hoc / test usage falls back to the package's own name so\n// the generated file is still well-formed.\nfunction projectToken(\n pkg: PackageJsonShape,\n serviceDir: string,\n project: string | undefined,\n): string {\n if (project && project.length > 0) return project\n return pkg.name ?? path.basename(serviceDir)\n}\n\n// Issue #370 — runtime-kind detection. The installer historically treated\n// every JavaScript package as a Node service; Brief's frontend workspace\n// showed that wrong assumption write `instrumentation-node/register` into a\n// Vite browser bundle and an Expo React Native entry, where the Node SDK\n// can't execute. Detection runs after framework dispatch (Next / Remix /\n// SvelteKit / Nuxt / Astro all render server-side, so they classify as\n// `node`); only the framework-less packages reach the bucket here.\ntype RuntimeKind = 'node' | 'browser-bundle' | 'react-native' | 'bun' | 'deno' | 'cloudflare-workers' | 'electron'\n\nasync function readJsonFile(p: string): Promise<unknown> {\n try {\n const raw = await fs.readFile(p, 'utf8')\n return JSON.parse(raw) as unknown\n } catch {\n return null\n }\n}\n\nasync function detectRuntimeKind(\n pkgRoot: string,\n pkg: PackageJsonShape,\n): Promise<RuntimeKind> {\n const deps = allDeps(pkg)\n if ('react-native' in deps || 'expo' in deps) return 'react-native'\n // Expo apps sometimes carry the SDK only as a transitive dep but always\n // ship an `app.json` carrying an `expo` block — that's the canonical Expo\n // signal.\n const appJson = await readJsonFile(path.join(pkgRoot, 'app.json'))\n if (appJson && typeof appJson === 'object' && 'expo' in (appJson as Record<string, unknown>)) {\n return 'react-native'\n }\n if (\n (await exists(path.join(pkgRoot, 'vite.config.js'))) ||\n (await exists(path.join(pkgRoot, 'vite.config.ts'))) ||\n (await exists(path.join(pkgRoot, 'vite.config.mjs'))) ||\n 'vite' in deps\n ) {\n return 'browser-bundle'\n }\n // Issues #389 #390 — out-of-scope runtime detection for BYO-OTel escape hatch.\n // Order: wrangler.toml first (Workers projects may also carry package.json),\n // then bun.lockb (Bun projects often have package.json too), then Deno signals.\n if (await exists(path.join(pkgRoot, 'wrangler.toml'))) return 'cloudflare-workers'\n if (await exists(path.join(pkgRoot, 'bun.lockb'))) return 'bun'\n if (\n (await exists(path.join(pkgRoot, 'deno.json'))) ||\n (await exists(path.join(pkgRoot, 'deno.lock')))\n ) {\n return 'deno'\n }\n const engines = (pkg as { engines?: Record<string, unknown> }).engines ?? {}\n if ('electron' in engines) return 'electron'\n return 'node'\n}\n\n// Issue #368 — `OTel deps in package.json` is no longer the signal for\n// `already-instrumented`. The hook file is. Each `plan<Framework>` reads its\n// canonical hook path off disk via `await exists(...)` before queueing the\n// generated-file write, so deps-present-but-hook-absent correctly buckets\n// the package as `instrumented` (the installer writes the hook), not\n// `already-instrumented`. The next-deps-no-hook fixture in the contract\n// suite locks this against regression.\n\nasync function readPackageJson(serviceDir: string): Promise<PackageJsonShape | null> {\n try {\n const raw = await fs.readFile(path.join(serviceDir, 'package.json'), 'utf8')\n return JSON.parse(raw) as PackageJsonShape\n } catch {\n return null\n }\n}\n\nasync function exists(p: string): Promise<boolean> {\n try {\n await fs.stat(p)\n return true\n } catch {\n return false\n }\n}\n\n// Read a file's contents, or null when it doesn't exist. Used by the\n// otel-init migration check (file-awareness.md §4) so a single read decides\n// between write / migrate / preserve.\nasync function readFileMaybe(p: string): Promise<string | null> {\n try {\n return await fs.readFile(p, 'utf8')\n } catch {\n return null\n }\n}\n\n// Decide what to do with the generated otel-init at `file`, given its rendered\n// current contents. A missing file is written (skipIfExists honours a race\n// where it appears between plan and apply). A NEAT-owned file (carries\n// OTEL_INIT_HEADER) on an older template — no current stamp — is regenerated so\n// a re-run upgrades the install. A current-stamp NEAT file is already current,\n// and a hand-written init (no header) is never touched.\nasync function planOtelInitGeneration(\n file: string,\n contents: string,\n): Promise<GeneratedFile | null> {\n const existing = await readFileMaybe(file)\n if (existing === null) {\n return { file, contents, skipIfExists: true }\n }\n if (existing.includes(OTEL_INIT_HEADER) && !existing.includes(OTEL_INIT_STAMP)) {\n return { file, contents, skipIfExists: false }\n }\n return null\n}\n\nasync function detect(serviceDir: string): Promise<boolean> {\n const pkg = await readPackageJson(serviceDir)\n return pkg !== null && typeof pkg.name === 'string'\n}\n\n// Returns true when the currently-installed range and the registry-resolved\n// expected range have no intersection — meaning the installed version is\n// incompatible and an upgrade edit should be emitted.\nfunction needsVersionUpgrade(installed: string, expected: string): boolean {\n return (\n !semver.satisfies(\n semver.minVersion(installed)?.version ?? installed,\n expected,\n ) && !semver.intersects(installed, expected)\n )\n}\n\n// ADR-073 §1 — Next.js detection. A package is Next-flavored when it\n// declares `next` as a (dev)dependency AND ships a `next.config.{js,ts,mjs}`\n// at the package root. Both are required: a stray `next` import without the\n// config file isn't a Next app, and a config file without the dep is dead\n// configuration.\nconst NEXT_CONFIG_CANDIDATES = ['next.config.js', 'next.config.ts', 'next.config.mjs']\n\nasync function findNextConfig(serviceDir: string): Promise<string | null> {\n for (const name of NEXT_CONFIG_CANDIDATES) {\n const candidate = path.join(serviceDir, name)\n if (await exists(candidate)) return candidate\n }\n return null\n}\n\nfunction hasNextDependency(pkg: PackageJsonShape): boolean {\n return (\n (pkg.dependencies?.next !== undefined) ||\n (pkg.devDependencies?.next !== undefined)\n )\n}\n\n// Read the merged dep + devDep map once per detection step. Framework checks\n// only care about presence, not version.\nfunction allDeps(pkg: PackageJsonShape): Record<string, string> {\n return { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) }\n}\n\n// Issue #545 — web-framework signals. When a package depends on one of these\n// but the installer couldn't resolve an entry point, it's almost certainly a\n// runnable app whose runtime layer is about to silently fail to engage rather\n// than a true library. The orchestrator uses this to turn a quiet `lib-only N`\n// tally into a loud, actionable line. Presence is enough — version doesn't\n// matter for the warning.\nconst WEB_FRAMEWORK_DEPS = [\n 'express',\n 'fastify',\n 'koa',\n '@hapi/hapi',\n 'hapi',\n 'restify',\n 'connect',\n '@nestjs/core',\n 'next',\n 'hono',\n 'elysia',\n 'polka',\n 'micro',\n] as const\n\n// Issue #570 — background-worker / queue-consumer signals. A package that\n// pulls jobs off a queue or consumes a message bus is a runnable process, not\n// a pure library: a lib-only classification on one of these is a missed entry\n// just like a web framework, so it earns the same loud warning instead of a\n// silent `lib-only N`. These sit alongside WEB_FRAMEWORK_DEPS rather than in\n// the registry because they're an app-shape heuristic, not instrumentation\n// coverage — the registry stays the single source of truth for what is/isn't\n// observed (uninstrumentedLibraries below), and these only answer \"is this a\n// runnable app whose entry we failed to find?\".\nconst WORKER_FRAMEWORK_DEPS = [\n 'bullmq',\n 'bull',\n 'bee-queue',\n 'agenda',\n 'kafkajs',\n 'amqplib',\n 'amqp-connection-manager',\n 'nats',\n 'node-resque',\n 'pg-boss',\n 'graphile-worker',\n] as const\n\n// Every dependency family that marks a package as a runnable application\n// (inbound web framework or background worker) rather than a library.\nconst APP_FRAMEWORK_DEPS = [...WEB_FRAMEWORK_DEPS, ...WORKER_FRAMEWORK_DEPS] as const\n\n// The application-framework dependencies a package declares — the names the\n// orchestrator puts in its warning so a lib-only-but-app-shaped package gets a\n// specific recovery line (\"depends on bullmq but neat couldn't resolve an\n// entry\") instead of a silent tally bump.\nexport function appFrameworkDependencies(pkg: PackageJsonShape): string[] {\n const deps = allDeps(pkg)\n return APP_FRAMEWORK_DEPS.filter((name) => name in deps)\n}\n\n// Issue #546 — libraries whose calls aren't observed by the default\n// auto-instrumentation set. Resolved through the instrumentation registry (the\n// single source of truth, contract §3) rather than a hardcoded list: a\n// dependency whose registry coverage is `gap` produces no OBSERVED edges out of\n// the box. `sqlite3` / `better-sqlite3` are the motivating cases — in-process\n// drivers that never cross an instrumented wire. Returns the library names so\n// the orchestrator can name them in its guidance line.\nexport function uninstrumentedLibraries(pkg: PackageJsonShape): string[] {\n const deps = allDeps(pkg)\n const out: string[] = []\n for (const [name, version] of Object.entries(deps)) {\n const entry = resolveRegistry(name, version)\n if (entry && entry.coverage === 'gap') out.push(name)\n }\n return out\n}\n\n// ADR-074 §3 — Remix detection. A package is Remix-flavored when it declares\n// `remix` or any `@remix-run/*` package AND ships an entry-server file at one\n// of the canonical paths (`app/entry.server.{ts,tsx,js,jsx}`).\nconst REMIX_ENTRY_CANDIDATES = [\n 'app/entry.server.ts',\n 'app/entry.server.tsx',\n 'app/entry.server.js',\n 'app/entry.server.jsx',\n]\n\nfunction hasRemixDependency(pkg: PackageJsonShape): boolean {\n const deps = allDeps(pkg)\n if ('remix' in deps) return true\n for (const name of Object.keys(deps)) {\n if (name.startsWith('@remix-run/')) return true\n }\n return false\n}\n\nasync function findRemixEntry(serviceDir: string): Promise<string | null> {\n for (const rel of REMIX_ENTRY_CANDIDATES) {\n const candidate = path.join(serviceDir, rel)\n if (await exists(candidate)) return candidate\n }\n return null\n}\n\n// ADR-074 §3 — SvelteKit detection. `@sveltejs/kit` dep, plus either an\n// existing `src/hooks.server.{ts,js}` or a top-level `svelte.config.{js,ts}`\n// (the absent-hooks case where the installer creates the hook file).\nconst SVELTEKIT_HOOKS_CANDIDATES = ['src/hooks.server.ts', 'src/hooks.server.js']\nconst SVELTEKIT_CONFIG_CANDIDATES = ['svelte.config.js', 'svelte.config.ts']\n\nfunction hasSvelteKitDependency(pkg: PackageJsonShape): boolean {\n return '@sveltejs/kit' in allDeps(pkg)\n}\n\nasync function findSvelteKitHooks(serviceDir: string): Promise<string | null> {\n for (const rel of SVELTEKIT_HOOKS_CANDIDATES) {\n const candidate = path.join(serviceDir, rel)\n if (await exists(candidate)) return candidate\n }\n return null\n}\n\nasync function findSvelteKitConfig(serviceDir: string): Promise<string | null> {\n for (const rel of SVELTEKIT_CONFIG_CANDIDATES) {\n const candidate = path.join(serviceDir, rel)\n if (await exists(candidate)) return candidate\n }\n return null\n}\n\n// ADR-074 §3 — Nuxt detection. `nuxt` dep + `nuxt.config.{ts,js,mjs}`.\nconst NUXT_CONFIG_CANDIDATES = ['nuxt.config.ts', 'nuxt.config.js', 'nuxt.config.mjs']\n\nfunction hasNuxtDependency(pkg: PackageJsonShape): boolean {\n return 'nuxt' in allDeps(pkg)\n}\n\nasync function findNuxtConfig(serviceDir: string): Promise<string | null> {\n for (const name of NUXT_CONFIG_CANDIDATES) {\n const candidate = path.join(serviceDir, name)\n if (await exists(candidate)) return candidate\n }\n return null\n}\n\n// ADR-074 §3 — Astro detection. `astro` dep + `astro.config.{mjs,ts,js}`.\nconst ASTRO_CONFIG_CANDIDATES = ['astro.config.mjs', 'astro.config.ts', 'astro.config.js']\n\nfunction hasAstroDependency(pkg: PackageJsonShape): boolean {\n return 'astro' in allDeps(pkg)\n}\n\nasync function findAstroConfig(serviceDir: string): Promise<string | null> {\n for (const name of ASTRO_CONFIG_CANDIDATES) {\n const candidate = path.join(serviceDir, name)\n if (await exists(candidate)) return candidate\n }\n return null\n}\n\n// Parse the leading major version out of a semver range like \"^14.0.3\" or\n// \"~15.0\" or \"15.0.0\". Returns null when the range can't be read (workspace\n// links, git refs, \"*\", etc.).\nexport function parseNextMajor(range: string | undefined): number | null {\n if (!range) return null\n const cleaned = range.trim().replace(/^[\\^~>=<\\s]+/, '')\n const match = cleaned.match(/^(\\d+)/)\n if (!match) return null\n const n = Number(match[1])\n return Number.isFinite(n) ? n : null\n}\n\nasync function isTypeScriptProject(serviceDir: string): Promise<boolean> {\n return exists(path.join(serviceDir, 'tsconfig.json'))\n}\n\n// ADR-069 §2 + ADR-070 + issue #545 #570 — entry resolution: pkg.main →\n// pkg.bin → scripts.start → scripts.dev → src/index.* →\n// src/{server,main,app,worker}.* → root {server,app,main,worker}.* →\n// root index.*. `pkg.main` is only accepted when\n// the file it names actually exists; a stale `main` (e.g. `dist/index.js` that\n// hasn't been built, or a leftover that was deleted) falls through to the rest\n// of the chain rather than marking the package lib-only. Returns the absolute\n// path to the resolved entry, or null when the package is lib-only (no\n// resolvable entry).\nconst INDEX_EXTENSIONS = ['.ts', '.tsx', '.js', '.mjs', '.cjs']\nconst INDEX_CANDIDATES = INDEX_EXTENSIONS.map((ext) => `index${ext}`)\nconst SRC_INDEX_CANDIDATES = INDEX_EXTENSIONS.map((ext) => `src/index${ext}`)\n// `worker` joins the named set (issue #570) — a background-queue worker\n// (bullmq, kafkajs, …) is a runnable process whose entry conventionally lives\n// in `worker.{js,ts}`, never under `index`. Without it the worker fell to\n// lib-only and its runtime layer silently never engaged.\nconst SRC_NAMED_CANDIDATES = ['server', 'main', 'app', 'worker'].flatMap((name) =>\n INDEX_EXTENSIONS.map((ext) => `src/${name}${ext}`),\n)\n// Issue #545 / #570 — a runnable app commonly keeps its entry at the repo root\n// under a conventional name (`server.js`, `app.js`, `main.js`, or `worker.js`\n// for a queue consumer) with no `scripts.start` and a `pkg.main` that points at\n// a build output that doesn't exist yet. Those shapes resolved to lib-only\n// before — the runtime layer never engaged. Root named candidates sit just\n// before the `index.*` root fallback so they're the last resort after the\n// manifest/script/src signals, but still keep the app from silently dropping\n// out of instrumentation.\nconst ROOT_NAMED_CANDIDATES = ['server', 'app', 'main', 'worker'].flatMap((name) =>\n INDEX_EXTENSIONS.map((ext) => `${name}${ext}`),\n)\n\n// ADR-070 — script-entry tokeniser. Launchers and similar wrappers we strip\n// before reading the first file-shaped argument. Anything not in this set is\n// treated as a candidate entry if it looks like a relative file path.\nconst SCRIPT_LAUNCHERS = new Set([\n 'node',\n 'ts-node',\n 'tsx',\n 'ts-node-dev',\n 'nodemon',\n 'npx',\n 'pnpm',\n 'yarn',\n 'npm',\n 'cross-env',\n 'dotenv',\n '--',\n])\n\n// True when the token resembles a path inside the package — contains a `/` or\n// ends in one of the JS/TS extensions we instrument.\nfunction looksLikeEntryPath(token: string): boolean {\n if (token.length === 0) return false\n if (token.startsWith('-')) return false\n if (token.includes('=')) return false // env-var assignments\n if (token.includes('/')) return true\n return /\\.(?:m?[jt]sx?|c[jt]s)$/.test(token)\n}\n\n// Bail when the script chains commands or pipes — those scripts mean an\n// orchestrator runs multiple things and our heuristic can't pick safely.\nfunction scriptHasShellChain(script: string): boolean {\n return /(?:&&|\\|\\||;|\\|(?!\\|))/.test(script)\n}\n\n// Pull the first file-shaped argument out of a script invocation, after\n// stripping recognised launchers and inline env-var assignments. Returns\n// undefined when no candidate surfaces (or when shell chaining bails us out).\nexport function entryFromScript(script: string | undefined): string | undefined {\n if (!script) return undefined\n if (scriptHasShellChain(script)) return undefined\n const tokens = script.split(/\\s+/).filter((t) => t.length > 0)\n for (const token of tokens) {\n const lower = token.toLowerCase()\n if (SCRIPT_LAUNCHERS.has(lower)) continue\n // Strip a leading `./` so the existence check resolves cleanly.\n const cleaned = token.startsWith('./') ? token.slice(2) : token\n if (looksLikeEntryPath(cleaned)) return cleaned\n }\n return undefined\n}\n\nexport async function resolveEntry(\n serviceDir: string,\n pkg: PackageJsonShape,\n): Promise<string | null> {\n // 1) pkg.main — but only when it actually exists on disk (ADR-070).\n if (typeof pkg.main === 'string' && pkg.main.length > 0) {\n const candidate = path.resolve(serviceDir, pkg.main)\n if (await exists(candidate)) return candidate\n // Manifest points main at a missing build output (e.g. dist/index.js\n // pre-build). Fall through to bin/scripts/src heuristics rather than\n // marking lib-only.\n }\n // 2) pkg.bin (string or pkg.name-keyed map).\n if (pkg.bin) {\n let binEntry: string | undefined\n if (typeof pkg.bin === 'string') {\n binEntry = pkg.bin\n } else if (pkg.name && typeof pkg.bin[pkg.name] === 'string') {\n binEntry = pkg.bin[pkg.name]\n } else {\n const first = Object.values(pkg.bin)[0]\n if (typeof first === 'string') binEntry = first\n }\n if (binEntry) {\n const candidate = path.resolve(serviceDir, binEntry)\n if (await exists(candidate)) return candidate\n }\n }\n // 3) scripts.start — ADR-070.\n const startEntry = entryFromScript(pkg.scripts?.start)\n if (startEntry) {\n const candidate = path.resolve(serviceDir, startEntry)\n if (await exists(candidate)) return candidate\n }\n // 4) scripts.dev — ADR-070.\n const devEntry = entryFromScript(pkg.scripts?.dev)\n if (devEntry) {\n const candidate = path.resolve(serviceDir, devEntry)\n if (await exists(candidate)) return candidate\n }\n // 5) src/index.* — ADR-070.\n for (const rel of SRC_INDEX_CANDIDATES) {\n const candidate = path.join(serviceDir, rel)\n if (await exists(candidate)) return candidate\n }\n // 6) src/server.*, src/main.*, src/app.*, src/worker.* — ADR-070 + #570.\n for (const rel of SRC_NAMED_CANDIDATES) {\n const candidate = path.join(serviceDir, rel)\n if (await exists(candidate)) return candidate\n }\n // 7) root server.*, app.*, main.*, worker.* — issue #545 / #570. Common for\n // a runnable app or queue worker whose entry sits at the repo root.\n for (const rel of ROOT_NAMED_CANDIDATES) {\n const candidate = path.join(serviceDir, rel)\n if (await exists(candidate)) return candidate\n }\n // 8) root index.* — original ADR-069 §3 fallback.\n for (const name of INDEX_CANDIDATES) {\n const candidate = path.join(serviceDir, name)\n if (await exists(candidate)) return candidate\n }\n return null\n}\n\n// ADR-069 §1, §3 — dispatch by entry extension + pkg.type.\ntype EntryFlavor = 'cjs' | 'esm' | 'ts'\n\nexport function dispatchEntry(entryFile: string, pkg: PackageJsonShape): EntryFlavor {\n const ext = path.extname(entryFile).toLowerCase()\n if (ext === '.ts' || ext === '.tsx') return 'ts'\n if (ext === '.mjs') return 'esm'\n if (ext === '.cjs') return 'cjs'\n // .js — disambiguate on pkg.type. \"module\" → ESM, anything else → CJS.\n return pkg.type === 'module' ? 'esm' : 'cjs'\n}\n\n// Generated-file basename per flavor.\nfunction otelInitFilename(flavor: EntryFlavor): string {\n if (flavor === 'ts') return 'otel-init.ts'\n if (flavor === 'esm') return 'otel-init.mjs'\n return 'otel-init.cjs'\n}\n\nfunction otelInitContents(flavor: EntryFlavor): string {\n if (flavor === 'ts') return OTEL_INIT_TS\n if (flavor === 'esm') return OTEL_INIT_ESM\n return OTEL_INIT_CJS\n}\n\n// Build the injection line per flavor. The relative path is computed against\n// the entry's directory so the injection works regardless of the entry's\n// depth inside the package.\nexport function injectionLine(\n flavor: EntryFlavor,\n entryFile: string,\n otelInitFile: string,\n): string {\n let rel = path.relative(path.dirname(entryFile), otelInitFile)\n if (!rel.startsWith('.')) rel = `./${rel}`\n // Normalize to forward slashes for cross-platform module specifiers.\n rel = rel.split(path.sep).join('/')\n if (flavor === 'cjs') return `require('${rel}')`\n if (flavor === 'esm') return `import '${rel}'`\n // TS: drop the .ts extension so the resolver doesn't choke on it under\n // either tsc-output or runtime-loader pipelines.\n const tsRel = rel.replace(/\\.ts$/, '')\n return `import '${tsRel}'`\n}\n\n// Detect whether a given line already matches an injection of our otel-init.\n// Used for the entry-point idempotency check (ADR-069 §6).\nfunction lineIsOtelInjection(line: string): boolean {\n const trimmed = line.trim()\n if (trimmed.length === 0) return false\n // Match require('./otel-init…') and import './otel-init…' shapes.\n return /(?:require\\(|import\\s+)['\"]\\.\\/otel-init[^'\"]*['\"]/.test(trimmed)\n}\n\n// `create-next-app --src-dir` puts source under `src/` and Next then resolves\n// the instrumentation hook from `src/instrumentation.ts`. Routing the\n// generated files to root in that case means the hook never loads. We detect\n// src-layout by the presence of `src/app/` or `src/pages/` AND the absence of\n// the same at the package root — a project with both is treated as flat, the\n// safer default for monorepos that vendor a `src/` subpackage.\nasync function detectsSrcLayout(serviceDir: string): Promise<boolean> {\n const [hasSrcApp, hasSrcPages, hasRootApp, hasRootPages] = await Promise.all([\n exists(path.join(serviceDir, 'src', 'app')),\n exists(path.join(serviceDir, 'src', 'pages')),\n exists(path.join(serviceDir, 'app')),\n exists(path.join(serviceDir, 'pages')),\n ])\n return (hasSrcApp || hasSrcPages) && !hasRootApp && !hasRootPages\n}\n\n// ADR-073 §1 / ADR-126 — Next.js apply path. Emits `instrumentation.{ts,js}`,\n// `instrumentation.node.{ts,js}`, and `instrumentation.edge.{ts,js}` at the\n// package root (or under `src/` for `--src-dir` layouts), plus `.env.neat`\n// co-located with them. Skips entry-point injection entirely — Next loads\n// the instrumentation file through its own runtime hook. Queues a\n// next.config edit only when the declared major is < 15 (the flag is\n// on-by-default from Next 15 on).\nasync function planNext(\n serviceDir: string,\n pkg: PackageJsonShape,\n manifestPath: string,\n nextConfigPath: string,\n project: string | undefined,\n): Promise<InstallPlan> {\n const useTs = await isTypeScriptProject(serviceDir)\n const srcLayout = await detectsSrcLayout(serviceDir)\n // Co-locate the generated files with where Next looks for the hook. When\n // src-layout is detected the framework resolves `src/instrumentation.{ts,js}`\n // and we route the .env.neat alongside so an operator reading the codebase\n // finds the wiring in one place. The flat layout keeps the existing root\n // placement.\n const baseDir = srcLayout ? path.join(serviceDir, 'src') : serviceDir\n const instrumentationFile = path.join(baseDir, useTs ? 'instrumentation.ts' : 'instrumentation.js')\n const instrumentationNodeFile = path.join(\n baseDir,\n useTs ? 'instrumentation.node.ts' : 'instrumentation.node.js',\n )\n const instrumentationEdgeFile = path.join(\n baseDir,\n useTs ? 'instrumentation.edge.ts' : 'instrumentation.edge.js',\n )\n const envNeatFile = path.join(baseDir, '.env.neat')\n\n // Dependency edits — `dotenv` is gone repo-wide from v0.4.4 (issue #369),\n // so SDK_PACKAGES has the three OTel packages the apply phase adds and the\n // Next branch shares the same loop as every other framework. Issue #376\n // adds non-bundled instrumentations (Prisma in v0.4.5) — each detected\n // entry contributes one dep + one registration line into the generated\n // instrumentation.node file.\n const existingDeps = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) }\n const dependencyEdits: DependencyEdit[] = []\n for (const sdk of SDK_PACKAGES) {\n if (sdk.name in existingDeps) {\n if (needsVersionUpgrade(existingDeps[sdk.name]!, sdk.version)) {\n dependencyEdits.push({ file: manifestPath, kind: 'upgrade', name: sdk.name, version: sdk.version, fromVersion: existingDeps[sdk.name]! })\n }\n continue\n }\n dependencyEdits.push({ file: manifestPath, kind: 'add', name: sdk.name, version: sdk.version })\n }\n // ADR-126 — `@vercel/otel` lands only for the edge file's sake, read from\n // NEXT_EDGE_PACKAGES rather than SDK_PACKAGES. Same existing-deps / upgrade\n // check as the loop above so a project that already depends on\n // `@vercel/otel` (e.g. it already had ambient Vercel tracing) doesn't get a\n // redundant or downgrading edit.\n for (const sdk of NEXT_EDGE_PACKAGES) {\n if (sdk.name in existingDeps) {\n if (needsVersionUpgrade(existingDeps[sdk.name]!, sdk.version)) {\n dependencyEdits.push({ file: manifestPath, kind: 'upgrade', name: sdk.name, version: sdk.version, fromVersion: existingDeps[sdk.name]! })\n }\n continue\n }\n dependencyEdits.push({ file: manifestPath, kind: 'add', name: sdk.name, version: sdk.version })\n }\n const nonBundled = detectNonBundledInstrumentations(pkg)\n for (const inst of nonBundled) {\n if (inst.pkg in existingDeps) {\n if (needsVersionUpgrade(existingDeps[inst.pkg]!, inst.version)) {\n dependencyEdits.push({ file: manifestPath, kind: 'upgrade', name: inst.pkg, version: inst.version, fromVersion: existingDeps[inst.pkg]! })\n }\n continue\n }\n dependencyEdits.push({ file: manifestPath, kind: 'add', name: inst.pkg, version: inst.version })\n }\n\n // Generated files — instrumentation pair + .env.neat. Existing files are\n // preserved (skipIfExists honours user customisations and keeps the apply\n // phase idempotent per ADR-069 §6). The instrumentation.node template\n // carries `__SERVICE_NAME__` (the ServiceNode id) and `__PROJECT__` (the\n // registered project basename — the URL routing key) placeholders we\n // substitute here so the bundler-survivable `process.env.X ||=` lines land\n // with both values verbatim.\n const svcName = serviceNodeName(pkg, serviceDir)\n const projectName = projectToken(pkg, serviceDir, project)\n const registrations = nonBundled.map((i) => i.registration)\n const generatedFiles: GeneratedFile[] = []\n if (!(await exists(instrumentationFile))) {\n generatedFiles.push({\n file: instrumentationFile,\n contents: useTs ? NEXT_INSTRUMENTATION_TS : NEXT_INSTRUMENTATION_JS,\n skipIfExists: true,\n })\n }\n if (!(await exists(instrumentationNodeFile))) {\n generatedFiles.push({\n file: instrumentationNodeFile,\n contents: renderNextInstrumentationNode(\n useTs ? NEXT_INSTRUMENTATION_NODE_TS : NEXT_INSTRUMENTATION_NODE_JS,\n svcName,\n projectName,\n registrations,\n ),\n skipIfExists: true,\n })\n }\n // ADR-126 — the edge-runtime file. Same substitution style as the Node\n // file (renderFrameworkOtelInit does the same __SERVICE_NAME__/__PROJECT__\n // regex replace renderNextInstrumentationNode does), same skipIfExists\n // idempotency so a re-run never clobbers a hand-edited registerOTel() call.\n if (!(await exists(instrumentationEdgeFile))) {\n generatedFiles.push({\n file: instrumentationEdgeFile,\n contents: renderFrameworkOtelInit(\n useTs ? NEXT_INSTRUMENTATION_EDGE_TS : NEXT_INSTRUMENTATION_EDGE_JS,\n svcName,\n projectName,\n ),\n skipIfExists: true,\n })\n }\n if (!(await exists(envNeatFile))) {\n generatedFiles.push({\n file: envNeatFile,\n contents: renderEnvNeat(svcName, projectName),\n skipIfExists: true,\n })\n }\n\n // ADR-073 §1 — `experimental.instrumentationHook: true` is required for\n // Next 13 / 14 and a no-op on Next 15+. Plan the edit only when the\n // declared major is < 15 and the flag isn't already present.\n let nextConfigEdit: InstallPlan['nextConfigEdit']\n const nextRange = pkg.dependencies?.next ?? pkg.devDependencies?.next\n const nextMajor = parseNextMajor(nextRange)\n if (nextMajor !== null && nextMajor < 15) {\n try {\n const raw = await fs.readFile(nextConfigPath, 'utf8')\n if (!raw.includes('instrumentationHook')) {\n nextConfigEdit = {\n file: nextConfigPath,\n reason: `enable experimental.instrumentationHook (Next ${nextMajor} requires the opt-in flag)`,\n }\n }\n } catch {\n // Config disappeared between detect and plan. Skip the edit.\n }\n }\n\n const empty =\n dependencyEdits.length === 0 &&\n generatedFiles.length === 0 &&\n nextConfigEdit === undefined\n\n if (empty) {\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits: [],\n entrypointEdits: [],\n envEdits: [],\n generatedFiles: [],\n framework: 'next',\n }\n }\n\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits,\n entrypointEdits: [],\n envEdits: [OTEL_ENV],\n generatedFiles,\n framework: 'next',\n ...(nextConfigEdit ? { nextConfigEdit } : {}),\n }\n}\n\n// ── Meta-framework planners (ADR-074 §3). ───────────────────────────────\n//\n// Each planner mirrors planNext's shape: build dep edits via the same\n// SDK_PACKAGES + existing-deps filter, queue generated files for the\n// framework-canonical hook surface, record `framework: '<name>'`, never\n// inject into pkg.main. Idempotency rides on `skipIfExists` for generated\n// files and on a re-read header-grep for the inject-into-existing case.\n\nfunction buildDependencyEdits(\n pkg: PackageJsonShape,\n manifestPath: string,\n): DependencyEdit[] {\n const existingDeps = allDeps(pkg)\n const edits: DependencyEdit[] = []\n for (const sdk of SDK_PACKAGES) {\n if (sdk.name in existingDeps) continue\n edits.push({\n file: manifestPath,\n kind: 'add',\n name: sdk.name,\n version: sdk.version,\n })\n }\n return edits\n}\n\nasync function queueEnvNeat(\n serviceDir: string,\n pkg: PackageJsonShape,\n project: string | undefined,\n generatedFiles: GeneratedFile[],\n): Promise<void> {\n const envNeatFile = path.join(serviceDir, '.env.neat')\n if (!(await exists(envNeatFile))) {\n generatedFiles.push({\n file: envNeatFile,\n contents: renderEnvNeat(\n serviceNodeName(pkg, serviceDir),\n projectToken(pkg, serviceDir, project),\n ),\n skipIfExists: true,\n })\n }\n}\n\nfunction renderFrameworkOtelInitForPkg(\n template: string,\n pkg: PackageJsonShape,\n serviceDir: string,\n project: string | undefined,\n): string {\n return renderFrameworkOtelInit(\n template,\n serviceNodeName(pkg, serviceDir),\n projectToken(pkg, serviceDir, project),\n )\n}\n\nfunction fileImportsOtelHook(raw: string, specifiers: readonly string[]): boolean {\n const lines = raw.split(/\\r?\\n/)\n for (const line of lines) {\n const trimmed = line.trim()\n for (const spec of specifiers) {\n const escaped = spec.replace(/\\./g, '\\\\.')\n const pattern = new RegExp(\n `(?:import\\\\s+['\"]${escaped}['\"]|require\\\\(['\"]${escaped}['\"]\\\\))`,\n )\n if (pattern.test(trimmed)) return true\n }\n }\n return false\n}\n\nasync function planRemix(\n serviceDir: string,\n pkg: PackageJsonShape,\n manifestPath: string,\n entryFile: string,\n project: string | undefined,\n): Promise<InstallPlan> {\n const useTs = await isTypeScriptProject(serviceDir)\n const otelServerFile = path.join(\n serviceDir,\n useTs ? 'app/otel.server.ts' : 'app/otel.server.js',\n )\n\n const dependencyEdits = buildDependencyEdits(pkg, manifestPath)\n const generatedFiles: GeneratedFile[] = []\n\n if (!(await exists(otelServerFile))) {\n generatedFiles.push({\n file: otelServerFile,\n contents: renderFrameworkOtelInitForPkg(\n useTs ? REMIX_OTEL_SERVER_TS : REMIX_OTEL_SERVER_JS,\n pkg,\n serviceDir,\n project,\n ),\n skipIfExists: true,\n })\n }\n await queueEnvNeat(serviceDir, pkg, project, generatedFiles)\n\n const entrypointEdits: EntrypointEdit[] = []\n try {\n const raw = await fs.readFile(entryFile, 'utf8')\n if (!fileImportsOtelHook(raw, ['./otel.server'])) {\n const lines = raw.split(/\\r?\\n/)\n const firstReal = lines[0]?.startsWith('#!') ? lines[1] ?? '' : lines[0] ?? ''\n entrypointEdits.push({\n file: entryFile,\n before: firstReal,\n after: \"import './otel.server'\",\n })\n }\n } catch {\n // Entry file disappeared between detect and plan; fall through.\n }\n\n const empty =\n dependencyEdits.length === 0 &&\n generatedFiles.length === 0 &&\n entrypointEdits.length === 0\n\n if (empty) {\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits: [],\n entrypointEdits: [],\n envEdits: [],\n generatedFiles: [],\n framework: 'remix',\n }\n }\n\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits,\n entrypointEdits,\n envEdits: [OTEL_ENV],\n generatedFiles,\n framework: 'remix',\n }\n}\n\nasync function planSvelteKit(\n serviceDir: string,\n pkg: PackageJsonShape,\n manifestPath: string,\n hooksFile: string | null,\n project: string | undefined,\n): Promise<InstallPlan> {\n const useTs = await isTypeScriptProject(serviceDir)\n const otelInitFile = path.join(\n serviceDir,\n useTs ? 'src/otel-init.ts' : 'src/otel-init.js',\n )\n const resolvedHooksFile =\n hooksFile ??\n path.join(serviceDir, useTs ? 'src/hooks.server.ts' : 'src/hooks.server.js')\n\n const dependencyEdits = buildDependencyEdits(pkg, manifestPath)\n const generatedFiles: GeneratedFile[] = []\n const entrypointEdits: EntrypointEdit[] = []\n\n if (!(await exists(otelInitFile))) {\n generatedFiles.push({\n file: otelInitFile,\n contents: renderFrameworkOtelInitForPkg(\n useTs ? SVELTEKIT_OTEL_INIT_TS : SVELTEKIT_OTEL_INIT_JS,\n pkg,\n serviceDir,\n project,\n ),\n skipIfExists: true,\n })\n }\n await queueEnvNeat(serviceDir, pkg, project, generatedFiles)\n\n if (hooksFile === null) {\n generatedFiles.push({\n file: resolvedHooksFile,\n contents: useTs ? SVELTEKIT_HOOKS_SERVER_TS : SVELTEKIT_HOOKS_SERVER_JS,\n skipIfExists: true,\n })\n } else {\n try {\n const raw = await fs.readFile(hooksFile, 'utf8')\n if (!fileImportsOtelHook(raw, ['./otel-init'])) {\n const lines = raw.split(/\\r?\\n/)\n const firstReal = lines[0]?.startsWith('#!') ? lines[1] ?? '' : lines[0] ?? ''\n entrypointEdits.push({\n file: hooksFile,\n before: firstReal,\n after: \"import './otel-init'\",\n })\n }\n } catch {\n // Disappeared between detect and plan; fall through.\n }\n }\n\n const empty =\n dependencyEdits.length === 0 &&\n generatedFiles.length === 0 &&\n entrypointEdits.length === 0\n\n if (empty) {\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits: [],\n entrypointEdits: [],\n envEdits: [],\n generatedFiles: [],\n framework: 'sveltekit',\n }\n }\n\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits,\n entrypointEdits,\n envEdits: [OTEL_ENV],\n generatedFiles,\n framework: 'sveltekit',\n }\n}\n\nasync function planNuxt(\n serviceDir: string,\n pkg: PackageJsonShape,\n manifestPath: string,\n project: string | undefined,\n): Promise<InstallPlan> {\n const useTs = await isTypeScriptProject(serviceDir)\n const otelPluginFile = path.join(\n serviceDir,\n useTs ? 'server/plugins/otel.ts' : 'server/plugins/otel.js',\n )\n const otelInitFile = path.join(\n serviceDir,\n useTs ? 'server/plugins/otel-init.ts' : 'server/plugins/otel-init.js',\n )\n\n const dependencyEdits = buildDependencyEdits(pkg, manifestPath)\n const generatedFiles: GeneratedFile[] = []\n\n if (!(await exists(otelInitFile))) {\n generatedFiles.push({\n file: otelInitFile,\n contents: renderFrameworkOtelInitForPkg(\n useTs ? NUXT_OTEL_INIT_TS : NUXT_OTEL_INIT_JS,\n pkg,\n serviceDir,\n project,\n ),\n skipIfExists: true,\n })\n }\n if (!(await exists(otelPluginFile))) {\n generatedFiles.push({\n file: otelPluginFile,\n contents: useTs ? NUXT_OTEL_PLUGIN_TS : NUXT_OTEL_PLUGIN_JS,\n skipIfExists: true,\n })\n }\n await queueEnvNeat(serviceDir, pkg, project, generatedFiles)\n\n const empty = dependencyEdits.length === 0 && generatedFiles.length === 0\n\n if (empty) {\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits: [],\n entrypointEdits: [],\n envEdits: [],\n generatedFiles: [],\n framework: 'nuxt',\n }\n }\n\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits,\n entrypointEdits: [],\n envEdits: [OTEL_ENV],\n generatedFiles,\n framework: 'nuxt',\n }\n}\n\nconst ASTRO_MIDDLEWARE_CANDIDATES = ['src/middleware.ts', 'src/middleware.js']\n\nasync function findAstroMiddleware(serviceDir: string): Promise<string | null> {\n for (const rel of ASTRO_MIDDLEWARE_CANDIDATES) {\n const candidate = path.join(serviceDir, rel)\n if (await exists(candidate)) return candidate\n }\n return null\n}\n\nasync function planAstro(\n serviceDir: string,\n pkg: PackageJsonShape,\n manifestPath: string,\n project: string | undefined,\n): Promise<InstallPlan> {\n const useTs = await isTypeScriptProject(serviceDir)\n const otelInitFile = path.join(\n serviceDir,\n useTs ? 'src/otel-init.ts' : 'src/otel-init.js',\n )\n const existingMiddleware = await findAstroMiddleware(serviceDir)\n const middlewareFile =\n existingMiddleware ??\n path.join(serviceDir, useTs ? 'src/middleware.ts' : 'src/middleware.js')\n\n const dependencyEdits = buildDependencyEdits(pkg, manifestPath)\n const generatedFiles: GeneratedFile[] = []\n const entrypointEdits: EntrypointEdit[] = []\n\n if (!(await exists(otelInitFile))) {\n generatedFiles.push({\n file: otelInitFile,\n contents: renderFrameworkOtelInitForPkg(\n useTs ? ASTRO_OTEL_INIT_TS : ASTRO_OTEL_INIT_JS,\n pkg,\n serviceDir,\n project,\n ),\n skipIfExists: true,\n })\n }\n await queueEnvNeat(serviceDir, pkg, project, generatedFiles)\n\n if (existingMiddleware === null) {\n generatedFiles.push({\n file: middlewareFile,\n contents: useTs ? ASTRO_MIDDLEWARE_TS : ASTRO_MIDDLEWARE_JS,\n skipIfExists: true,\n })\n } else {\n try {\n const raw = await fs.readFile(existingMiddleware, 'utf8')\n if (!fileImportsOtelHook(raw, ['./otel-init'])) {\n const lines = raw.split(/\\r?\\n/)\n const firstReal = lines[0]?.startsWith('#!') ? lines[1] ?? '' : lines[0] ?? ''\n entrypointEdits.push({\n file: existingMiddleware,\n before: firstReal,\n after: \"import './otel-init'\",\n })\n }\n } catch {\n // Disappeared between detect and plan; fall through.\n }\n }\n\n const empty =\n dependencyEdits.length === 0 &&\n generatedFiles.length === 0 &&\n entrypointEdits.length === 0\n\n if (empty) {\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits: [],\n entrypointEdits: [],\n envEdits: [],\n generatedFiles: [],\n framework: 'astro',\n }\n }\n\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits,\n entrypointEdits,\n envEdits: [OTEL_ENV],\n generatedFiles,\n framework: 'astro',\n }\n}\n\ntype FrameworkDispatch = () => Promise<InstallPlan>\n\n// ADR-073 §1 + ADR-074 §3 — framework signal lookup. Returns a thunk that\n// invokes the framework-specific planner when a match lands, or null when\n// none do. Detection precedence is Next → Remix → SvelteKit → Nuxt → Astro;\n// the chain bails on the first match. Pulled out of `plan()` so issue\n// #375's lib-only check can see the framework signal upfront — a package\n// with no framework hook AND no Node entry buckets as lib-only regardless\n// of stray Vite config or Expo deps.\nasync function findFrameworkDispatch(\n serviceDir: string,\n pkg: PackageJsonShape,\n manifestPath: string,\n project: string | undefined,\n): Promise<FrameworkDispatch | null> {\n if (hasNextDependency(pkg)) {\n const nextConfig = await findNextConfig(serviceDir)\n if (nextConfig) {\n return () => planNext(serviceDir, pkg, manifestPath, nextConfig, project)\n }\n }\n if (hasRemixDependency(pkg)) {\n const remixEntry = await findRemixEntry(serviceDir)\n if (remixEntry) {\n return () => planRemix(serviceDir, pkg, manifestPath, remixEntry, project)\n }\n }\n if (hasSvelteKitDependency(pkg)) {\n const hooks = await findSvelteKitHooks(serviceDir)\n const config = await findSvelteKitConfig(serviceDir)\n if (hooks || config) {\n return () => planSvelteKit(serviceDir, pkg, manifestPath, hooks, project)\n }\n }\n if (hasNuxtDependency(pkg)) {\n const nuxtConfig = await findNuxtConfig(serviceDir)\n if (nuxtConfig) {\n return () => planNuxt(serviceDir, pkg, manifestPath, project)\n }\n }\n if (hasAstroDependency(pkg)) {\n const astroConfig = await findAstroConfig(serviceDir)\n if (astroConfig) {\n return () => planAstro(serviceDir, pkg, manifestPath, project)\n }\n }\n return null\n}\n\nasync function plan(serviceDir: string, opts?: PlanOptions): Promise<InstallPlan> {\n const pkg = await readPackageJson(serviceDir)\n const manifestPath = path.join(serviceDir, 'package.json')\n const project = opts?.project\n const empty: InstallPlan = {\n language: 'javascript',\n serviceDir,\n dependencyEdits: [],\n entrypointEdits: [],\n envEdits: [],\n generatedFiles: [],\n }\n if (!pkg) return empty\n\n // Issue #375 — classification pipeline order: lib-only → framework →\n // runtime-kind → emit. A package with no framework hook AND no resolvable\n // Node entry is lib-only regardless of stray Vite config or Expo deps. The\n // runtime-kind dispatch only fires for non-framework packages that\n // actually have an entry to instrument; without this ordering, a UI library\n // that ships a `vite.config.ts` for its build pipeline would bucket as\n // browser-bundle and surface in the operator summary as if it were a real\n // SPA the installer was choosing to skip.\n const frameworkDispatch = await findFrameworkDispatch(\n serviceDir,\n pkg,\n manifestPath,\n project,\n )\n\n // Resolve the Node entry up front so the lib-only check can read both\n // signals together. Skipped on the framework branch — frameworks own their\n // boot path and never need a `pkg.main` injection (the chain returns\n // before this line runs).\n let entryFile: string | null = null\n if (!frameworkDispatch) {\n entryFile = await resolveEntry(serviceDir, pkg)\n if (!entryFile) {\n return { ...empty, libOnly: true }\n }\n }\n\n if (frameworkDispatch) {\n return frameworkDispatch()\n }\n\n // Issue #370 — runtime-kind detection sits between the lib-only check and\n // vanilla Node template emission. Browser bundles (Vite) and React Native\n // / Expo packages bucket here so the apply phase skips every write and\n // surfaces the package in the summary instead of injecting a Node SDK hook\n // into code that can't run it.\n const runtimeKind = await detectRuntimeKind(serviceDir, pkg)\n if (runtimeKind !== 'node') {\n return { ...empty, runtimeKind }\n }\n\n // entryFile resolved above on the non-framework branch; the null path\n // already returned lib-only.\n if (!entryFile) {\n return { ...empty, libOnly: true }\n }\n const flavor = dispatchEntry(entryFile, pkg)\n const otelInitFile = path.join(path.dirname(entryFile), otelInitFilename(flavor))\n const envNeatFile = path.join(serviceDir, '.env.neat')\n\n // ── Dependency edits (four-deps invariant; ADR-069 §5). ────────────────\n // Issue #376 — non-bundled instrumentations append additional deps when\n // the host package declares libraries whose runtime traffic bypasses the\n // auto-instrumentation set (Prisma's Rust query engine for v0.4.5; the\n // v0.5.0 registry feeds the same loop with more entries).\n const existingDeps = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) }\n const dependencyEdits: DependencyEdit[] = []\n for (const sdk of SDK_PACKAGES) {\n if (sdk.name in existingDeps) {\n if (needsVersionUpgrade(existingDeps[sdk.name]!, sdk.version)) {\n dependencyEdits.push({ file: manifestPath, kind: 'upgrade', name: sdk.name, version: sdk.version, fromVersion: existingDeps[sdk.name]! })\n }\n continue\n }\n dependencyEdits.push({ file: manifestPath, kind: 'add', name: sdk.name, version: sdk.version })\n }\n const nonBundled = detectNonBundledInstrumentations(pkg)\n for (const inst of nonBundled) {\n if (inst.pkg in existingDeps) {\n if (needsVersionUpgrade(existingDeps[inst.pkg]!, inst.version)) {\n dependencyEdits.push({ file: manifestPath, kind: 'upgrade', name: inst.pkg, version: inst.version, fromVersion: existingDeps[inst.pkg]! })\n }\n continue\n }\n dependencyEdits.push({ file: manifestPath, kind: 'add', name: inst.pkg, version: inst.version })\n }\n\n // ── Entry-point injection edit (ADR-069 §3). ───────────────────────────\n const entrypointEdits: EntrypointEdit[] = []\n try {\n const raw = await fs.readFile(entryFile, 'utf8')\n const lines = raw.split(/\\r?\\n/)\n // Preserve a shebang on line 1 and check line 2 (the first non-shebang\n // line) for an existing injection.\n const firstReal = lines[0]?.startsWith('#!') ? lines[1] ?? '' : lines[0] ?? ''\n if (!lineIsOtelInjection(firstReal)) {\n const inject = injectionLine(flavor, entryFile, otelInitFile)\n // Use the existing first-real line as the `before` marker so the apply\n // phase can splice the injection cleanly even if the file shifts.\n entrypointEdits.push({\n file: entryFile,\n before: firstReal,\n after: inject,\n })\n }\n } catch {\n // Entry file disappeared between resolve and plan (rare). Treat as\n // lib-only.\n return { ...empty, libOnly: true }\n }\n\n // ── Generated files (ADR-069 §1, §4). ──────────────────────────────────\n // v0.4.4 — the otel-init template carries `__SERVICE_NAME__` (the\n // ServiceNode id) and `__PROJECT__` (the URL routing key) placeholders we\n // substitute here. The .env.neat shape lands with the same pair so an\n // operator can grep for both fields in one place.\n // v0.4.5 — `__INSTRUMENTATION_BLOCK__` substitutes to the registration\n // snippets for any non-bundled instrumentations detected above (Prisma\n // for v0.4.5; the v0.5.0 registry will feed more entries through the same\n // path). Empty list collapses cleanly to nothing.\n const svcName = serviceNodeName(pkg, serviceDir)\n const projectName = projectToken(pkg, serviceDir, project)\n const registrations = nonBundled.map((i) => i.registration)\n const generatedFiles: GeneratedFile[] = []\n const otelInitGen = await planOtelInitGeneration(\n otelInitFile,\n renderNodeOtelInit(otelInitContents(flavor), svcName, projectName, registrations),\n )\n if (otelInitGen) generatedFiles.push(otelInitGen)\n if (!(await exists(envNeatFile))) {\n generatedFiles.push({\n file: envNeatFile,\n contents: renderEnvNeat(svcName, projectName),\n skipIfExists: true,\n })\n }\n\n // ── Idempotency check (ADR-069 §6). ────────────────────────────────────\n // If the package is already instrumented end-to-end — deps present, entry\n // already injected, generated files already there — return an empty plan.\n if (\n dependencyEdits.length === 0 &&\n entrypointEdits.length === 0 &&\n generatedFiles.length === 0\n ) {\n return empty\n }\n\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits,\n entrypointEdits,\n envEdits: [OTEL_ENV],\n generatedFiles,\n entryFile,\n libOnly: false,\n }\n}\n\n// ADR-069 §7 + ADR-073 §1 + ADR-074 §3 — allowed write paths. Anything\n// outside this set inside an installer's apply phase is a contract violation.\nfunction isAllowedWritePath(serviceDir: string, target: string): boolean {\n const rel = path.relative(serviceDir, target)\n if (rel.startsWith('..')) return false\n const base = path.basename(target)\n if (base === 'package.json') return true\n if (base === '.env.neat') return true\n if (/^otel-init\\.(?:js|cjs|mjs|ts)$/.test(base)) return true\n // ADR-073 §1 / ADR-126 — Next framework files at the package root, or\n // under src/ when create-next-app's --src-dir layout is in use. The\n // instrumentation hook resolves from `src/` in that layout; routing files\n // there is the load-bearing fix for the src-dir shape. `.edge` joins\n // `.node` as the second runtime-scoped instrumentation file (ADR-126).\n const relPosix = rel.split(path.sep).join('/')\n if (/^instrumentation(?:\\.(?:node|edge))?\\.(?:js|cjs|mjs|ts)$/.test(base)) {\n if (relPosix === base) return true\n if (relPosix === `src/${base}`) return true\n return false\n }\n if (/^next\\.config\\.(?:js|mjs|ts)$/.test(base)) return true\n // ADR-074 §3 — meta-framework hook surfaces.\n if (relPosix === 'app/otel.server.ts' || relPosix === 'app/otel.server.js') return true\n if (/^app\\/entry\\.server\\.(?:tsx?|jsx?)$/.test(relPosix)) return true\n if (relPosix === 'src/otel-init.ts' || relPosix === 'src/otel-init.js') return true\n if (relPosix === 'src/hooks.server.ts' || relPosix === 'src/hooks.server.js') return true\n if (relPosix === 'server/plugins/otel.ts' || relPosix === 'server/plugins/otel.js') return true\n if (relPosix === 'server/plugins/otel-init.ts' || relPosix === 'server/plugins/otel-init.js') return true\n if (relPosix === 'src/middleware.ts' || relPosix === 'src/middleware.js') return true\n return false\n}\n\nasync function writeAtomic(file: string, contents: string): Promise<void> {\n // Meta-framework branches write to convention-driven subdirs that the user\n // may not have scaffolded yet (`server/plugins/`, `src/`, `app/`). Ensure\n // the parent directory exists before the atomic write; existing parents\n // are a no-op under `recursive: true`.\n await fs.mkdir(path.dirname(file), { recursive: true })\n const tmp = `${file}.${process.pid}.${Date.now()}.tmp`\n await fs.writeFile(tmp, contents, 'utf8')\n await fs.rename(tmp, file)\n}\n\nasync function apply(installPlan: InstallPlan): Promise<ApplyResult> {\n const { serviceDir } = installPlan\n if (installPlan.libOnly) {\n return {\n serviceDir,\n outcome: 'lib-only',\n reason: 'no resolvable entry point',\n writtenFiles: [],\n }\n }\n\n // Issue #370 — non-Node runtimes write nothing. The CLI surfaces the\n // outcome in the summary so the operator can see which packages were\n // skipped and why.\n if (installPlan.runtimeKind === 'browser-bundle') {\n return {\n serviceDir,\n outcome: 'browser-bundle',\n reason: 'browser bundle; Node OTel SDK cannot run here',\n writtenFiles: [],\n }\n }\n if (installPlan.runtimeKind === 'react-native') {\n return {\n serviceDir,\n outcome: 'react-native',\n reason: 'React Native / Expo target; Node OTel SDK cannot run here',\n writtenFiles: [],\n }\n }\n if (installPlan.runtimeKind === 'bun') {\n return { serviceDir, outcome: 'bun', reason: 'Bun runtime; use BYO-OTel', writtenFiles: [] }\n }\n if (installPlan.runtimeKind === 'deno') {\n return { serviceDir, outcome: 'deno', reason: 'Deno runtime; use BYO-OTel', writtenFiles: [] }\n }\n if (installPlan.runtimeKind === 'cloudflare-workers') {\n return {\n serviceDir,\n outcome: 'cloudflare-workers',\n reason: 'Cloudflare Workers runtime; use BYO-OTel',\n writtenFiles: [],\n }\n }\n if (installPlan.runtimeKind === 'electron') {\n return {\n serviceDir,\n outcome: 'electron',\n reason: 'Electron; use BYO-OTel',\n writtenFiles: [],\n }\n }\n\n // Already-instrumented check: an empty plan means there's nothing to do.\n if (\n installPlan.dependencyEdits.length === 0 &&\n installPlan.entrypointEdits.length === 0 &&\n (installPlan.generatedFiles?.length ?? 0) === 0 &&\n installPlan.nextConfigEdit === undefined\n ) {\n return {\n serviceDir,\n outcome: 'already-instrumented',\n writtenFiles: [],\n }\n }\n\n // Validate every target we plan to touch against the allowed-path set.\n // Bail out before any write if a violation slipped through.\n const allTargets = new Set<string>()\n for (const d of installPlan.dependencyEdits) allTargets.add(d.file)\n for (const e of installPlan.entrypointEdits) allTargets.add(e.file)\n for (const g of installPlan.generatedFiles ?? []) allTargets.add(g.file)\n if (installPlan.nextConfigEdit) allTargets.add(installPlan.nextConfigEdit.file)\n for (const target of allTargets) {\n // Entry-point edits land in user source files, not the allowed set —\n // they're explicitly carved out below.\n const isEntryEdit = installPlan.entrypointEdits.some((e) => e.file === target)\n if (isEntryEdit) continue\n if (!isAllowedWritePath(serviceDir, target)) {\n throw new Error(\n `javascript installer: refusing to write outside the allowed path set (ADR-069 §7): ${target}`,\n )\n }\n }\n\n // Snapshot every file we may touch so a partial failure can roll back the\n // batch (ADR-047 §7). Newly-generated files have no prior contents — they\n // get tracked separately so rollback unlinks them instead of restoring.\n const originals = new Map<string, string>()\n const createdFiles: string[] = []\n for (const target of allTargets) {\n if (await exists(target)) {\n try {\n originals.set(target, await fs.readFile(target, 'utf8'))\n } catch {\n // Best-effort. The mutation loop below will throw if this matters.\n }\n }\n }\n\n const writtenFiles: string[] = []\n try {\n // ── 1. Manifest edits (package.json) ─────────────────────────────────\n const manifestTargets = installPlan.dependencyEdits\n .reduce<Set<string>>((acc, e) => {\n acc.add(e.file)\n return acc\n }, new Set())\n for (const file of manifestTargets) {\n const raw = originals.get(file)\n if (raw === undefined) {\n throw new Error(`javascript installer: cannot read ${file} during apply`)\n }\n const pkg = JSON.parse(raw) as PackageJsonShape\n pkg.dependencies = pkg.dependencies ?? {}\n for (const dep of installPlan.dependencyEdits) {\n if (dep.file !== file) continue\n if (dep.kind === 'add') {\n if (!(dep.name in (pkg.dependencies ?? {}))) {\n pkg.dependencies[dep.name] = dep.version\n }\n } else if (dep.kind === 'upgrade') {\n pkg.dependencies[dep.name] = dep.version\n } else {\n delete pkg.dependencies[dep.name]\n }\n }\n const newRaw = JSON.stringify(pkg, null, 2) + '\\n'\n await writeAtomic(file, newRaw)\n writtenFiles.push(file)\n }\n\n // ── 2. Generated files (otel-init, .env.neat) ────────────────────────\n for (const gen of installPlan.generatedFiles ?? []) {\n if (gen.skipIfExists && (await exists(gen.file))) {\n // Skip silently; the contract treats this as part of the\n // already-instrumented path.\n continue\n }\n await writeAtomic(gen.file, gen.contents)\n if (!originals.has(gen.file)) createdFiles.push(gen.file)\n writtenFiles.push(gen.file)\n }\n\n // ── 3. Entry-point injection (require/import on first non-shebang line)\n for (const ep of installPlan.entrypointEdits) {\n const raw = originals.get(ep.file)\n if (raw === undefined) {\n throw new Error(`javascript installer: cannot read entry ${ep.file} during apply`)\n }\n const lines = raw.split(/\\r?\\n/)\n const hasShebang = lines[0]?.startsWith('#!') ?? false\n const insertAt = hasShebang ? 1 : 0\n // Idempotency: if the first non-shebang line already matches our\n // injection pattern, skip — never double-inject.\n const firstReal = lines[insertAt] ?? ''\n if (lineIsOtelInjection(firstReal)) continue\n lines.splice(insertAt, 0, ep.after)\n const newRaw = lines.join('\\n')\n await writeAtomic(ep.file, newRaw)\n writtenFiles.push(ep.file)\n }\n\n // ── 4. Next.js config flag (ADR-073 §1) — only present on the Next\n // path when the declared major is < 15 and the flag isn't already\n // mentioned in the file. Best-effort regex insertion into the first\n // config object literal; bails silently when the shape isn't\n // recognisable so we never corrupt a user-customised config.\n if (installPlan.nextConfigEdit) {\n const target = installPlan.nextConfigEdit.file\n const raw = originals.get(target)\n if (raw !== undefined && !raw.includes('instrumentationHook')) {\n const updated = injectInstrumentationHook(raw)\n if (updated !== null) {\n await writeAtomic(target, updated)\n writtenFiles.push(target)\n }\n }\n }\n } catch (err) {\n await rollback(installPlan, originals, createdFiles)\n throw err\n }\n\n return {\n serviceDir,\n outcome: 'instrumented',\n writtenFiles,\n }\n}\n\nasync function rollback(\n installPlan: InstallPlan,\n originals: Map<string, string>,\n createdFiles: string[],\n): Promise<void> {\n const restored: string[] = []\n const removed: string[] = []\n for (const [file, raw] of originals.entries()) {\n try {\n await fs.writeFile(file, raw, 'utf8')\n restored.push(file)\n } catch {\n // Best-effort: keep going so we restore as much as we can.\n }\n }\n for (const file of createdFiles) {\n try {\n await fs.unlink(file)\n removed.push(file)\n } catch {\n // Best-effort.\n }\n }\n const lines = [\n '# neat-rollback.patch',\n '',\n `# Generated after a partial apply failure in the ${installPlan.language} installer.`,\n '# Files listed below were restored to their pre-apply contents.',\n '',\n ...restored.map((f) => `restored: ${f}`),\n ...removed.map((f) => `removed: ${f}`),\n '',\n ]\n const rollbackPath = path.join(installPlan.serviceDir, 'neat-rollback.patch')\n await fs.writeFile(rollbackPath, lines.join('\\n'), 'utf8')\n}\n\n// ADR-073 §1 — best-effort injection of `experimental.instrumentationHook:\n// true` into a next.config.{js,ts,mjs}. Returns the rewritten contents on\n// success, or null when the config shape isn't recognisable (in which case\n// the apply phase leaves the file alone — partial Next coverage is fine,\n// silent corruption of a user's config is not).\n//\n// Recognised shapes:\n// - `module.exports = { ... }` (CJS)\n// - `module.exports = { ... } satisfies NextConfig` (TS-via-CJS)\n// - `export default { ... }` (ESM / TS)\n// - `const nextConfig = { ... }; module.exports = nextConfig` (named CJS)\n// - `const nextConfig: NextConfig = { ... }; export default nextConfig` (TS)\nexport function injectInstrumentationHook(raw: string): string | null {\n if (raw.includes('instrumentationHook')) return raw\n\n // Strategy: find the first config object literal whose contents we can\n // edit, then either merge into an existing `experimental: { ... }` block\n // or insert a fresh `experimental: { instrumentationHook: true }` entry.\n //\n // We look for one of four anchors near a top-level `{` and splice from\n // there. The regexes capture the `{` so we can splice right after it.\n const anchors: Array<{ pattern: RegExp; label: string }> = [\n { pattern: /(module\\.exports\\s*=\\s*\\{)/, label: 'cjs-default' },\n { pattern: /(export\\s+default\\s*\\{)/, label: 'esm-default' },\n { pattern: /(?:const|let|var)\\s+\\w+(?:\\s*:\\s*[^=]+)?\\s*=\\s*(\\{)/, label: 'named-config' },\n ]\n\n for (const { pattern } of anchors) {\n const match = pattern.exec(raw)\n if (!match) continue\n const insertAfter = match.index + match[0].length\n const before = raw.slice(0, insertAfter)\n const after = raw.slice(insertAfter)\n // Insert a leading newline so the injection sits on its own line and\n // doesn't fight any existing trailing-comma style. Two-space indent\n // covers most code-styled configs.\n const injection = '\\n experimental: { instrumentationHook: true },'\n return `${before}${injection}${after}`\n }\n\n return null\n}\n\nexport const javascriptInstaller: Installer = {\n name: 'javascript',\n detect,\n plan,\n apply,\n}\n\n// Re-exports used by the contract test surface.\nexport { NEXT_INSTRUMENTATION_HEADER, OTEL_INIT_HEADER }\n","/**\n * Generated-file templates for the Node SDK installer (ADR-069 §1).\n *\n * Three flavors so the inserted file matches the host package's module\n * system: CJS for `require`-based packages, ESM for `import`-based, TS for\n * TypeScript entries. Env vars are inlined as `process.env.X ||=` defaults\n * rather than loaded from `.env.neat` at runtime — `__dirname` /\n * `import.meta.url` resolve unpredictably once a bundler rewrites the\n * generated file (Brief-smoke evidence, issue #369), so we let the OTel SDK\n * read its config from the same `process.env` either way. Platform env\n * (Vercel / Railway / Fly / etc.) stays authoritative at deploy time;\n * `||=` keeps the local default for laptop dev only.\n */\n\n// Header comment that ships at the top of every generated otel-init. Stable\n// across flavors so a grep for the header line finds every generated file in\n// a target codebase. Used by the idempotency check too (ADR-069 §6).\nexport const OTEL_INIT_HEADER = '// Generated by `neat init --apply` (ADR-069). OpenTelemetry auto-instrumentation hook.'\n\n// Version stamp on the generated otel-init (file-awareness.md §4). A NEAT-owned\n// file carries OTEL_INIT_HEADER; the stamp records which template revision wrote\n// it. On re-run, an existing NEAT-owned file whose stamp is older than the\n// current one is regenerated (a hand-written init — no header — is never\n// touched). Bump the revision whenever the generated body changes shape.\nexport const OTEL_INIT_STAMP =\n '// neat-template-version: 6 — daemon.json endpoint resolution (ADR-096) + layered file-first capture (ADR-090).'\n\n// OTLP exporter auth (ADR-073 §3/§4, #410). When the operator runs the\n// instrumented app with `NEAT_OTEL_TOKEN` set — the same secret the daemon's\n// OTLP receiver reads (`NEAT_OTEL_TOKEN ?? NEAT_AUTH_TOKEN`) — the exporter\n// sends `Authorization: Bearer <token>` so a secured daemon accepts the spans.\n// Unset (laptop dev against a loopback daemon with no token) sends no header,\n// matching the daemon's unauthenticated loopback path. The token is the single\n// source: it lives in the environment, never inlined into the generated file.\n// `||=` keeps any platform-set header (Vercel / Railway / Fly) authoritative.\nexport const OTEL_OTLP_HEADERS_JS =\n \"if (process.env.NEAT_OTEL_TOKEN) process.env.OTEL_EXPORTER_OTLP_HEADERS ||= 'Authorization=Bearer ' + process.env.NEAT_OTEL_TOKEN\"\n\n// Export protocol pin (#468). The OTel JS SDK defaults to http/protobuf; NEAT's\n// receiver accepts both, but http/json is the wire format the smoke gates\n// validate hardest, so the generated init pins it. Same `||=` discipline as the\n// other inlined env: an operator who explicitly sets\n// OTEL_EXPORTER_OTLP_PROTOCOL (e.g. to route through a collector that insists\n// on protobuf) stays authoritative.\nexport const OTEL_OTLP_PROTOCOL_JS =\n \"process.env.OTEL_EXPORTER_OTLP_PROTOCOL ||= 'http/json'\"\n\n// OTLP endpoint resolution (ADR-096 / project-daemon contract). Under\n// one-daemon-per-project the daemon allocates its OTLP port once (canonical\n// 4318, stepping to the next free port when a sibling daemon already holds it)\n// and records it in `<project>/neat-out/daemon.json`. The instrumented app must\n// read THAT port back, or a second project's app — baked to a fixed 4318 —\n// sends its spans to the first project's daemon, which has no slot for them and\n// drops them: the second project's OBSERVED layer goes dark silently. That is\n// exactly the failure this code exists to kill, so the endpoint is resolved at\n// app boot from the daemon's own record rather than hardcoded.\n//\n// Precedence (highest first):\n// 1. An explicit OTEL_EXPORTER_OTLP_TRACES_ENDPOINT / _ENDPOINT env var —\n// the prod/hosted path where a platform or collector owns the target.\n// 2. `<project>/neat-out/daemon.json` → `ports.otlp` → the bare\n// `http://localhost:<otlp>/v1/traces` route the per-project daemon serves.\n// 3. The canonical `http://localhost:4318/v1/traces` default — the laptop\n// happy path where the daemon took its first-choice port.\n//\n// This is INJECTED into the user's app, so it is bulletproof: the whole thing\n// is wrapped in try/catch, a missing or malformed daemon.json falls through to\n// the canonical default, and it NEVER throws — a resolution failure must not\n// crash the host app's startup. The daemon.json path is resolved by walking up\n// from the app's runtime cwd looking for `neat-out/daemon.json`, which lands on\n// the project root whether the app boots from the project root (single package)\n// or a package subdirectory (monorepo).\n//\n// The endpoint matches the bare `/v1/traces` route the per-project daemon\n// serves (daemon.ts) — NOT the legacy `/projects/<name>/v1/traces` form, since\n// a daemon that hosts exactly one project needs no project name to disambiguate.\n\n// CJS flavor — `require('node:fs')` is available in the require-based template.\nexport const OTEL_ENDPOINT_RESOLVER_CJS = `;(function () {\n try {\n if (process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT || process.env.OTEL_EXPORTER_OTLP_ENDPOINT) return\n const __neatFs = require('node:fs')\n const __neatPath = require('node:path')\n let __neatDir = process.cwd()\n for (let __i = 0; __i < 8; __i++) {\n try {\n const __rec = JSON.parse(__neatFs.readFileSync(__neatPath.join(__neatDir, 'neat-out', 'daemon.json'), 'utf8'))\n if (__rec && __rec.ports && typeof __rec.ports.otlp === 'number') {\n process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = 'http://localhost:' + __rec.ports.otlp + '/v1/traces'\n break\n }\n } catch (_e) {}\n const __parent = __neatPath.dirname(__neatDir)\n if (__parent === __neatDir) break\n __neatDir = __parent\n }\n } catch (_e) {}\n process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||= 'http://localhost:4318/v1/traces'\n})()`\n\n// ESM/TS flavor — `require` is not defined in a pure-ESM module, so the\n// built-in fs/path come in via the hoisted `import` block\n// OTEL_ESM_NODE_IMPORTS adds to the top of the generated ESM/TS file. The\n// resolver references those bindings (`__neatReadFileSync` / `__neatJoin` /\n// `__neatDirname`) directly. ES import bindings are evaluated before this IIFE\n// runs, so they're always present.\nexport const OTEL_ESM_NODE_IMPORTS =\n \"import { readFileSync as __neatReadFileSync } from 'node:fs'\\n\" +\n \"import { join as __neatJoin, dirname as __neatDirname } from 'node:path'\"\n\nexport const OTEL_ENDPOINT_RESOLVER_ESM = `;(function () {\n try {\n if (process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT || process.env.OTEL_EXPORTER_OTLP_ENDPOINT) return\n let __neatDir = process.cwd()\n for (let __i = 0; __i < 8; __i++) {\n try {\n const __rec = JSON.parse(__neatReadFileSync(__neatJoin(__neatDir, 'neat-out', 'daemon.json'), 'utf8'))\n if (__rec && __rec.ports && typeof __rec.ports.otlp === 'number') {\n process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = 'http://localhost:' + __rec.ports.otlp + '/v1/traces'\n break\n }\n } catch (_e) {}\n const __parent = __neatDirname(__neatDir)\n if (__parent === __neatDir) break\n __neatDir = __parent\n }\n } catch (_e) {}\n process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||= 'http://localhost:4318/v1/traces'\n})()`\n\n// Inlined layered call-site capture (file-awareness.md §4–6, ADR-090). The\n// whole mechanism is self-contained — NEAT can't import its own package into a\n// user's generated file, so the runtime logic is inlined verbatim. The exact\n// bytes that ship are exercised by the capture spike\n// (test/callsite-processor.test.ts) so a regression here fails CI before it\n// ships. The `ts` flag adds the few type annotations a strict tsconfig needs;\n// the runtime logic is identical across flavors.\n//\n// Three layers land the user's `file:line:function` on every CLIENT / PRODUCER\n// / SERVER span:\n// 1. Synchronous stack walk at span start — covers the sync-wrapper majority.\n// 2. Handler-entry attribution — stamps the framework SERVER span and pushes\n// the handler frame into the active context so downstream CLIENT/PRODUCER\n// spans inherit it (the floor).\n// 3. Off-stack facades — undici / built-in `fetch` (diagnostics_channel) and\n// Prisma (backdated dispatch) push the call-site frame into context for\n// the inner call; the processor reads it as a fallback.\nfunction neatCaptureSource(ts: boolean): string {\n const spanT = ts ? ': any' : ''\n const strOpt = ts ? ': string | undefined' : ''\n const anyT = ts ? ': any' : ''\n const fnT = ts ? ': any' : ''\n const arrAny = ts ? ': any[]' : ''\n return `// Context key shared by the facade/handler wraps (writers) and the\n// processor fallback (reader). Symbol.for keeps it stable even if the wraps\n// and the processor end up in different module instances.\nconst NEAT_USER_FRAME = Symbol.for('neat.user-frame')\n\nfunction __neatPickUserFrame(stack${strOpt}) {\n const lines = String(stack || '').split('\\\\n')\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i].trim()\n if (raw.indexOf('at ') !== 0) continue\n if (raw.indexOf('node_modules') !== -1) continue\n if (raw.indexOf('@opentelemetry') !== -1) continue\n if (raw.indexOf('node:') !== -1) continue\n if (raw.indexOf('NeatCallSiteSpanProcessor') !== -1) continue\n // Skip NEAT's own inlined wraps/helpers (all carry the __neat prefix) so a\n // facade frame never masquerades as the user's call site.\n if (raw.indexOf('__neat') !== -1) continue\n const bodyText = raw.slice(3)\n const loc = bodyText.match(/:(\\\\d+):(\\\\d+)\\\\)?$/)\n if (!loc) continue\n const paren = bodyText.lastIndexOf('(')\n let filepath${strOpt}\n let fn${strOpt}\n if (paren !== -1) {\n fn = bodyText.slice(0, paren).trim()\n if (fn.indexOf('async ') === 0) fn = fn.slice(6)\n if (fn.indexOf('new ') === 0) fn = fn.slice(4)\n filepath = bodyText.slice(paren + 1, bodyText.length - loc[0].length)\n } else {\n filepath = bodyText.slice(0, bodyText.length - loc[0].length)\n }\n if (filepath.indexOf('file://') === 0) filepath = filepath.slice(7)\n if (!filepath) continue\n return { filepath: filepath, lineno: Number(loc[1]), function: fn || undefined }\n }\n return null\n}\n\n// Layer 2/3 fallback source: the frame a handler-entry or facade wrap pushed\n// into context. Reads the span's own parent context first, then the active\n// context — the capture spike confirmed both return the value for undici.\nfunction __neatFrameFromContext(parentContext${anyT}) {\n try {\n const fromParent =\n parentContext && typeof parentContext.getValue === 'function'\n ? parentContext.getValue(NEAT_USER_FRAME)\n : undefined\n return fromParent || context.active().getValue(NEAT_USER_FRAME) || null\n } catch (_e) {\n return null\n }\n}\n\nfunction __neatSetCodeAttrs(span${spanT}, frame${anyT}) {\n span.setAttribute('code.filepath', frame.filepath)\n if (typeof frame.lineno === 'number') span.setAttribute('code.lineno', frame.lineno)\n if (frame.function) span.setAttribute('code.function', frame.function)\n}\n\nclass NeatCallSiteSpanProcessor {\n onStart(span${spanT}, parentContext${anyT}) {\n if (!span || (span.kind !== 2 && span.kind !== 3)) return\n // Layer 1 — synchronous stack walk (sync-wrapper instrumentations).\n let frame = __neatPickUserFrame(new Error().stack)\n // Layer 2/3 — the handler-entry or off-stack-facade frame from context.\n if (!frame) frame = __neatFrameFromContext(parentContext)\n if (!frame) return\n __neatSetCodeAttrs(span, frame)\n }\n onEnd() {}\n forceFlush() { return Promise.resolve() }\n shutdown() { return Promise.resolve() }\n}\n\n// Capture the caller's synchronous frame at the wrap point and run \\`fn\\` with\n// that frame pushed into the active context (file-awareness.md §4 layer 3). An\n// off-stack instrumentation that creates its span inside \\`fn\\` inherits the\n// frame; the processor reads it via __neatFrameFromContext.\nfunction __neatRunWithUserFrame(fn${fnT}) {\n const frame = __neatPickUserFrame(new Error().stack)\n if (!frame) return fn()\n return context.with(context.active().setValue(NEAT_USER_FRAME, frame), fn)\n}\n\n// Handler-entry attribution (file-awareness.md §4 layer 2). Stamp the framework\n// SERVER span with the handler frame captured at route registration, and push\n// the same frame into context so downstream CLIENT/PRODUCER spans inherit the\n// handler-file floor when their own stack carries none.\nfunction __neatStampHandler(frame${anyT}, run${fnT}) {\n try {\n const active = trace.getActiveSpan()\n if (active && active.kind === 1 && typeof active.setAttribute === 'function') {\n __neatSetCodeAttrs(active, frame)\n }\n } catch (_e) {}\n try {\n return context.with(context.active().setValue(NEAT_USER_FRAME, frame), run)\n } catch (_e) {\n return run()\n }\n}\n\n// require-in-the-middle is a transitive dependency of the OTel instrumentation\n// packages NEAT installs, so it resolves in any instrumented CJS service.\n// Guarded: when it's absent (or the host runs as pure ESM, where require isn't\n// defined) the off-stack/handler wraps degrade to the stack walk + context\n// floor, never to a crash.\nfunction __neatHook(modules${arrAny}, onload${fnT}) {\n try {\n const RITM = require('require-in-the-middle')\n const Hook = RITM && RITM.Hook ? RITM.Hook : RITM\n new Hook(modules, { internals: false }, onload)\n return true\n } catch (_e) {\n return false\n }\n}\n\n// Off-stack facade: Node's built-in fetch / undici. The instrumentation creates\n// the CLIENT span inside a diagnostics_channel handler detached from the\n// caller's stack, so wrap the global so the user frame is in context when the\n// span is created. The capture spike (2026-05-28) validated this on real\n// undici. .name is restored to 'fetch' for ecosystem compatibility; the inner\n// __neat name is what the frame skip keys on.\nfunction __neatWrapFetch() {\n try {\n const g${anyT} = globalThis\n if (typeof g.fetch === 'function' && !g.fetch.__neatWrapped) {\n const realFetch = g.fetch\n // The wrapper keeps its __neat-prefixed name so the frame skip in\n // __neatPickUserFrame never mistakes the wrapper's own frame for the\n // user's call site (renaming it to 'fetch' would defeat the skip).\n const __neatFetch${anyT} = function (input${anyT}, init${anyT}) {\n return __neatRunWithUserFrame(function () { return realFetch(input, init) })\n }\n __neatFetch.__neatWrapped = true\n g.fetch = __neatFetch\n }\n } catch (_e) {}\n}\n\n// Off-stack facade: @prisma/client. Prisma's query engine backdates its spans\n// from Rust, off the caller's stack. Wrap the model methods on the client\n// prototype so the call-site frame (still synchronous at \\`prisma.user.find\\`)\n// is pushed into context for the engine dispatch.\nfunction __neatWrapPrisma() {\n __neatHook(['@prisma/client'], function (exports${anyT}) {\n try {\n const Client = exports && exports.PrismaClient\n if (typeof Client === 'function' && !Client.__neatWrapped) {\n const ops = ['findUnique','findUniqueOrThrow','findFirst','findFirstOrThrow','findMany','create','createMany','update','updateMany','upsert','delete','deleteMany','count','aggregate','groupBy']\n const __neatPrismaWrapModel = function (model${anyT}) {\n if (!model || model.__neatWrapped) return model\n for (let i = 0; i < ops.length; i++) {\n const op = ops[i]\n const orig = model[op]\n if (typeof orig !== 'function') continue\n model[op] = function __neatPrismaOp(${ts ? '...args: any[]' : '...args'}) {\n const self = this\n return __neatRunWithUserFrame(function () { return orig.apply(self, args) })\n }\n }\n model.__neatWrapped = true\n return model\n }\n const proto = Client.prototype\n const handler = function (model${anyT}) { return __neatPrismaWrapModel(model) }\n // Model accessors are lazily created getters on the instance; wrap the\n // \\`$extends\\`-free common path by trapping property access via a proxy\n // on each constructed client.\n exports.PrismaClient = new Proxy(Client, {\n construct(Target${anyT}, argList${anyT}, NewTarget${anyT}) {\n const instance = Reflect.construct(Target, argList, NewTarget)\n return new Proxy(instance, {\n get(target${anyT}, prop${anyT}, receiver${anyT}) {\n const value = Reflect.get(target, prop, receiver)\n if (value && typeof value === 'object' && typeof prop === 'string' && prop[0] !== '$' && prop[0] !== '_') {\n return handler(value)\n }\n return value\n },\n })\n },\n })\n exports.PrismaClient.__neatWrapped = true\n void proto\n }\n } catch (_e) {}\n return exports\n })\n}\n\n// Handler-entry facades. express / connect share the Layer model (each route\n// handler is a function registered on a Router); the wrap captures the\n// registration frame and stamps + propagates it when the handler runs. The\n// registry is the extensibility seam — koa, fastify (via @fastify/otel),\n// nestjs, restify, and hapi add an entry as their patch surface is wired.\nfunction __neatWrapConnectStyle(mod${anyT}) {\n try {\n // express() returns an app whose route verbs live on Router.prototype and\n // the application proto; connect apps expose \\`use\\`. Wrap the registration\n // verbs so the user handler is wound with its registration frame.\n const verbs = ['use','get','post','put','delete','patch','all','options','head']\n const wrapTarget = function (target${anyT}) {\n if (!target || target.__neatVerbsWrapped) return\n for (let i = 0; i < verbs.length; i++) {\n const verb = verbs[i]\n const orig = target[verb]\n if (typeof orig !== 'function') continue\n target[verb] = function __neatVerb(${ts ? '...args: any[]' : '...args'}) {\n const frame = __neatPickUserFrame(new Error().stack)\n if (frame) {\n for (let a = 0; a < args.length; a++) {\n const h = args[a]\n if (typeof h === 'function' && !h.__neatHandlerWrapped && h.length <= 4) {\n const inner = h\n const __neatHandler${anyT} = function (${ts ? '...hargs: any[]' : '...hargs'}) {\n const self = this\n return __neatStampHandler(frame, function () { return inner.apply(self, hargs) })\n }\n __neatHandler.__neatHandlerWrapped = true\n args[a] = __neatHandler\n }\n }\n }\n return orig.apply(this, args)\n }\n }\n target.__neatVerbsWrapped = true\n }\n if (mod && mod.Router && mod.Router.prototype) wrapTarget(mod.Router.prototype)\n if (mod && mod.application) wrapTarget(mod.application)\n if (mod && mod.prototype) wrapTarget(mod.prototype)\n } catch (_e) {}\n}\n\nfunction __neatInstallHandlerEntry() {\n __neatHook(['express'], function (exports${anyT}) { __neatWrapConnectStyle(exports); return exports })\n __neatHook(['connect'], function (exports${anyT}) { __neatWrapConnectStyle(exports); return exports })\n}\n\n// Install every off-stack and handler-entry wrap. Called once after sdk.start()\n// — before user code requires the framework / Prisma modules, so the hooks land\n// on first require. Each wrap is independently guarded.\nfunction __neatInstallFacades() {\n __neatWrapFetch()\n __neatWrapPrisma()\n __neatInstallHandlerEntry()\n}`\n}\n\n// The runtime capture source, exported so the capture spike can materialise and\n// exercise the exact bytes that ship in the generated file.\nexport const CALLSITE_PROCESSOR_JS = neatCaptureSource(false)\nexport const CALLSITE_PROCESSOR_TS = neatCaptureSource(true)\n\n// Post-`sdk.start()` wiring. NodeSDK keeps its env-configured OTLP exporter\n// (passing `spanProcessors` to the constructor would replace it); we add the\n// call-site processor to the started provider via the public `getDelegate()` +\n// `addSpanProcessor()` surface, then assert it actually attached (file-\n// awareness.md §4 / ADR-090). A wiring regression that would silently drop\n// file-first capture throws loudly at boot instead of shipping service-level-\n// only spans. The facade/handler wraps install last, so a span export path is\n// live before any user module loads.\nfunction neatWireCaptureSource(ts: boolean): string {\n const providerT = ts ? ': any' : ''\n return `try {\n const provider${providerT} = trace.getTracerProvider()\n const delegate = provider && typeof provider.getDelegate === 'function' ? provider.getDelegate() : provider\n if (!delegate || typeof delegate.addSpanProcessor !== 'function') {\n throw new Error('[neat] could not resolve a TracerProvider to attach the call-site processor; file-first OBSERVED capture would be silent (file-awareness.md §4)')\n }\n const __neatProcessor = new NeatCallSiteSpanProcessor()\n delegate.addSpanProcessor(__neatProcessor)\n // Post-init assertion: confirm attachment on providers that expose their\n // processor list. An un-introspectable provider is trusted (we just called\n // its addSpanProcessor); a list that exists and lacks our processor throws.\n const registered = delegate._registeredSpanProcessors\n if (Array.isArray(registered) && registered.indexOf(__neatProcessor) === -1) {\n throw new Error('[neat] call-site processor did not attach to the active TracerProvider (file-awareness.md §4)')\n }\n} catch (err) {\n throw err\n}\ntry {\n __neatInstallFacades()\n} catch (_e) {\n // Facade install is best-effort: the stack-walk + handler-entry floor still\n // attribute the sync-wrapper majority even if an off-stack wrap fails.\n}`\n}\n\n// __SERVICE_NAME__ → the ServiceNode id (the package's `pkg.name`, or the\n// directory basename for nameless packages); __PROJECT__ → the registered\n// project basename; __INSTRUMENTATION_BLOCK__ → a (possibly empty) sequence\n// of `instrumentations.push(...)` lines for non-bundled instrumentations\n// (Prisma for v0.4.5; more libraries via the v0.5.0 registry). All three are\n// substituted at apply time via renderNodeOtelInit().\n//\n// v0.4.5 — explicit `NodeSDK` construction replaces the\n// `auto-instrumentations-node/register` shorthand so non-bundled libraries\n// (Prisma's Rust query engine bypasses node-pg; Drizzle, BetterAuth, etc.\n// have their own packages) can compose into the same `instrumentations`\n// array without templating a different file shape per library.\nexport const OTEL_INIT_CJS = `${OTEL_INIT_HEADER}\n${OTEL_INIT_STAMP}\nprocess.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'\n${OTEL_ENDPOINT_RESOLVER_CJS}\n${OTEL_OTLP_PROTOCOL_JS}\n${OTEL_OTLP_HEADERS_JS}\n\nconst { NodeSDK } = require('@opentelemetry/sdk-node')\nconst { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node')\nconst { trace, context } = require('@opentelemetry/api')\n\n${CALLSITE_PROCESSOR_JS}\n\nconst instrumentations = [getNodeAutoInstrumentations()]\n__INSTRUMENTATION_BLOCK__\nconst sdk = new NodeSDK({ instrumentations })\nsdk.start()\n${neatWireCaptureSource(false)}\n`\n\nexport const OTEL_INIT_ESM = `${OTEL_INIT_HEADER}\n${OTEL_INIT_STAMP}\n${OTEL_ESM_NODE_IMPORTS}\nprocess.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'\n${OTEL_ENDPOINT_RESOLVER_ESM}\n${OTEL_OTLP_PROTOCOL_JS}\n${OTEL_OTLP_HEADERS_JS}\n\nimport { NodeSDK } from '@opentelemetry/sdk-node'\nimport { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'\nimport { trace, context } from '@opentelemetry/api'\n\n${CALLSITE_PROCESSOR_JS}\n\nconst instrumentations = [getNodeAutoInstrumentations()]\n__INSTRUMENTATION_BLOCK__\nconst sdk = new NodeSDK({ instrumentations })\nsdk.start()\n${neatWireCaptureSource(false)}\n`\n\nexport const OTEL_INIT_TS = `${OTEL_INIT_HEADER}\n${OTEL_INIT_STAMP}\n// @ts-nocheck — generated runtime shim. The layered capture mechanism uses\n// dynamic patterns (facade wraps, Proxy traps, a createRequire bridge) that a\n// strict user tsconfig would reject; suppressing type-checking here keeps the\n// generated file from breaking the host project's \\`tsc\\` gate (#427) without\n// constraining the runtime logic. The file is regenerated, never hand-edited.\n${OTEL_ESM_NODE_IMPORTS}\nprocess.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'\n${OTEL_ENDPOINT_RESOLVER_ESM}\n${OTEL_OTLP_PROTOCOL_JS}\n${OTEL_OTLP_HEADERS_JS}\n\nimport { NodeSDK } from '@opentelemetry/sdk-node'\nimport { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'\nimport { trace, context } from '@opentelemetry/api'\n\n${CALLSITE_PROCESSOR_TS}\n\nconst instrumentations = [getNodeAutoInstrumentations()]\n__INSTRUMENTATION_BLOCK__\nconst sdk = new NodeSDK({ instrumentations })\nsdk.start()\n${neatWireCaptureSource(true)}\n`\n\n// Substitute __SERVICE_NAME__, __PROJECT__, and __INSTRUMENTATION_BLOCK__\n// at apply time. The third arg is a list of registration snippets — one per\n// non-bundled instrumentation the installer detected (e.g. Prisma). An empty\n// list collapses the placeholder to nothing so the generated file stays\n// readable on the common \"auto-instrumentations covers everything\" path.\nexport function renderNodeOtelInit(\n template: string,\n serviceName: string,\n projectName: string,\n registrations: readonly string[] = [],\n): string {\n const block = registrations.length === 0 ? '' : `\\n${registrations.join('\\n')}\\n`\n return template\n .replace(/__SERVICE_NAME__/g, serviceName)\n .replace(/__PROJECT__/g, projectName)\n .replace(/__INSTRUMENTATION_BLOCK__\\n?/g, block)\n}\n\n// .env.neat shape (ADR-069 §4, amended v0.4.1 — refs #339, v0.4.4 — refs\n// #367 + #369, v0.4.8 — refs #410, ADR-096). Two keys: OTEL_SERVICE_NAME (the\n// ServiceNode id — the package's own name, scope-preserved, so spans land on\n// per-service nodes inside the project's graph) and\n// OTEL_EXPORTER_OTLP_TRACES_ENDPOINT. Under one-daemon-per-project (ADR-096)\n// the daemon serves a bare `/v1/traces` route and allocates its OTLP port once,\n// recording it in `<project>/neat-out/daemon.json`; the generated `otel-init`\n// reads that record at boot and ignores this file, so the value here is purely\n// the canonical-default advisory the operator sees when grepping for the\n// service.name → endpoint mapping. Both env vars are advisory only — the\n// generated `otel-init` inlines/derives them so bundlers can't lose them. A\n// commented `NEAT_OTEL_TOKEN` hint documents the single source of the OTLP\n// bearer (#410): set it to the secret the daemon's receiver expects and the\n// generated init sends `Authorization: Bearer <token>`.\nexport function renderEnvNeat(serviceName: string, _projectName: string): string {\n return [\n '# Generated by `neat init --apply` (ADR-069).',\n `OTEL_SERVICE_NAME=${serviceName}`,\n '# Advisory only — the generated otel-init resolves the live endpoint from',\n '# <project>/neat-out/daemon.json (ports.otlp) at boot (ADR-096). This is the',\n '# canonical default the daemon takes when its first-choice OTLP port is free.',\n 'OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4318/v1/traces',\n 'OTEL_EXPORTER_OTLP_PROTOCOL=http/json',\n '# Set NEAT_OTEL_TOKEN to the daemon\\'s OTLP secret to authenticate exported spans (#410).',\n '# NEAT_OTEL_TOKEN=',\n '',\n ].join('\\n')\n}\n\n// ── Next.js framework-aware templates (ADR-073 §1, ADR-069 §3, ADR-126). ─\n//\n// Next.js owns its own boot — `pkg.main` is unused, and the auto-instrumentation\n// register hook can't run before user code. Next 13+ ships an `instrumentation`\n// file at the project root with an async `register()` export the framework\n// invokes during server start, once per runtime it boots. Browser bundles\n// still never load this file.\n//\n// Three-file shape: `instrumentation.{ts,js}` is the runtime gate, dispatching\n// to `instrumentation.node.{ts,js}` (the Node SDK init) on the nodejs runtime\n// and `instrumentation.edge.{ts,js}` (`@vercel/otel`, ADR-126) on the edge\n// runtime — the standard Node SDK can't execute inside Next's Edge runtime at\n// all, so the edge file leans on a runtime-aware package instead. All three\n// files sit at the project root (or under `src/` for `--src-dir` layouts).\n\nexport const NEXT_INSTRUMENTATION_HEADER =\n '// Generated by `neat init --apply` (ADR-073). Next.js instrumentation hook.'\n\nexport const NEXT_INSTRUMENTATION_TS = `${NEXT_INSTRUMENTATION_HEADER}\nexport async function register() {\n if (process.env.NEXT_RUNTIME === 'nodejs') {\n await import('./instrumentation.node')\n }\n if (process.env.NEXT_RUNTIME === 'edge') {\n await import('./instrumentation.edge')\n }\n}\n`\n\nexport const NEXT_INSTRUMENTATION_JS = `${NEXT_INSTRUMENTATION_HEADER}\nexport async function register() {\n if (process.env.NEXT_RUNTIME === 'nodejs') {\n await import('./instrumentation.node')\n }\n if (process.env.NEXT_RUNTIME === 'edge') {\n await import('./instrumentation.edge')\n }\n}\n`\n\n// Env vars are inlined as process.env defaults so they survive Turbopack /\n// Webpack bundling — `import.meta.url` resolves to a path under .next/dev/\n// server/chunks/ once Next compiles this file, which would miss .env.neat.\n// `process.env.X ||=` keeps platform env (Vercel / Railway / Fly / etc.)\n// authoritative at deploy time while the local default carries the routing\n// key the daemon needs to map spans back to this project. The endpoint uses\n// the project-scoped URL form so the daemon never has to guess which project\n// owns the span (issue #367); the OTel SDK reads the env vars from\n// process.env directly, so no file-system lookup is required at runtime.\nexport const NEXT_INSTRUMENTATION_NODE_TS = `${NEXT_INSTRUMENTATION_HEADER}\n${OTEL_ESM_NODE_IMPORTS}\nprocess.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'\n${OTEL_ENDPOINT_RESOLVER_ESM}\n${OTEL_OTLP_PROTOCOL_JS}\n${OTEL_OTLP_HEADERS_JS}\n\nimport { NodeSDK } from '@opentelemetry/sdk-node'\nimport { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'\n\nconst instrumentations = [getNodeAutoInstrumentations()]\n__INSTRUMENTATION_BLOCK__\nnew NodeSDK({ instrumentations }).start()\n`\n\nexport const NEXT_INSTRUMENTATION_NODE_JS = `${NEXT_INSTRUMENTATION_HEADER}\nprocess.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'\n${OTEL_ENDPOINT_RESOLVER_CJS}\n${OTEL_OTLP_PROTOCOL_JS}\n${OTEL_OTLP_HEADERS_JS}\n\nconst { NodeSDK } = require('@opentelemetry/sdk-node')\nconst { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node')\n\nconst instrumentations = [getNodeAutoInstrumentations()]\n__INSTRUMENTATION_BLOCK__\nnew NodeSDK({ instrumentations }).start()\n`\n\n// Substitute the placeholders at apply time so the generated file carries the\n// ServiceNode id (`__SERVICE_NAME__`) and the registered project name\n// (`__PROJECT__`) verbatim. The two roles diverged in v0.4.4: the service name\n// names the ServiceNode inside one project's graph, the project basename is\n// the URL routing key. v0.4.5 adds __INSTRUMENTATION_BLOCK__ — a (possibly\n// empty) sequence of `instrumentations.push(...)` calls for non-bundled\n// libraries like Prisma whose query engines bypass the auto-instrumentation\n// set's coverage.\nexport function renderNextInstrumentationNode(\n template: string,\n serviceName: string,\n projectName: string,\n registrations: readonly string[] = [],\n): string {\n const block = registrations.length === 0 ? '' : `\\n${registrations.join('\\n')}\\n`\n return template\n .replace(/__SERVICE_NAME__/g, serviceName)\n .replace(/__PROJECT__/g, projectName)\n .replace(/__INSTRUMENTATION_BLOCK__\\n?/g, block)\n}\n\n// ── Next.js edge-runtime template (ADR-126). ─────────────────────────────\n//\n// `@opentelemetry/sdk-node` cannot run inside Next's Edge runtime — a V8\n// isolate with no Node.js API surface (no `node:fs`, no `node:net`). Next's\n// own build-time analysis rejects an edge bundle that imports `node:fs`, so\n// this file cannot reuse the `OTEL_ENDPOINT_RESOLVER_ESM` daemon.json walk\n// the Node file relies on — that walk is exactly the kind of Node API access\n// the Edge runtime forbids. `@vercel/otel`'s `registerOTel()` is runtime-aware\n// and built on web-standard APIs instead, so one call covers the Edge runtime\n// (and, on Vercel, gets Vercel's own OTel integration for free when present).\n//\n// The endpoint still resolves from the same `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`\n// env var every other generated init reads, defaulting to the same canonical\n// `http://localhost:4318/v1/traces` — no new env var, no new config surface\n// (framework-installers.md §7, ADR-126). `registerOTel` reads OTLP\n// endpoint/protocol/headers from `process.env` itself when `traceExporter`\n// is left at its \"auto\" default, so setting the env vars ahead of the call\n// is enough; unlike the Node file there's no filesystem probe to run first.\nexport const NEXT_INSTRUMENTATION_EDGE_HEADER =\n '// Generated by `neat init --apply` (ADR-126). Next.js edge-runtime instrumentation via @vercel/otel.'\n\nexport const NEXT_INSTRUMENTATION_EDGE_TS = `${NEXT_INSTRUMENTATION_EDGE_HEADER}\nimport { registerOTel } from '@vercel/otel'\n\nprocess.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'\nprocess.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||= 'http://localhost:4318/v1/traces'\n${OTEL_OTLP_PROTOCOL_JS}\n${OTEL_OTLP_HEADERS_JS}\n\nregisterOTel({ serviceName: process.env.OTEL_SERVICE_NAME })\n`\n\n// Edge bundles are ESM-only (Next.js requires `import`/`export` syntax for\n// any file it loads into the Edge runtime), so the JS flavor is identical to\n// the TS flavor byte-for-byte — there's no CJS variant to diverge from, same\n// as the top-level instrumentation.{ts,js} gate above.\nexport const NEXT_INSTRUMENTATION_EDGE_JS = NEXT_INSTRUMENTATION_EDGE_TS\n\n// ── Meta-framework templates (ADR-074 §3). ──────────────────────────────\n//\n// Remix, SvelteKit, Nuxt, and Astro each own their boot path. The installer\n// emits one OTel-init module that loads `.env.neat` and starts the Node SDK,\n// then either creates or injects an import into the framework's canonical\n// hook file. Templates mirror the Next.js pair in shape — one generated init\n// module, one optional framework-hook stub for the absent-file case.\n\nexport const FRAMEWORK_OTEL_INIT_HEADER =\n '// Generated by `neat init --apply` (ADR-074). OpenTelemetry SDK hook.'\n\n// Same inline-defaults pattern as the plain-Node + Next templates: env vars\n// arrive on `process.env` via the apply-time substitution below so bundler\n// path mangling (issue #369) can't lose them. `__SERVICE_NAME__` /\n// `__PROJECT__` are substituted via renderFrameworkOtelInit().\nconst FRAMEWORK_OTEL_INIT_TS_BODY = `${FRAMEWORK_OTEL_INIT_HEADER}\n${OTEL_ESM_NODE_IMPORTS}\nprocess.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'\n${OTEL_ENDPOINT_RESOLVER_ESM}\n${OTEL_OTLP_PROTOCOL_JS}\n${OTEL_OTLP_HEADERS_JS}\n\nimport { NodeSDK } from '@opentelemetry/sdk-node'\nimport { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'\n\nconst sdk = new NodeSDK({\n serviceName: process.env.OTEL_SERVICE_NAME,\n instrumentations: [getNodeAutoInstrumentations()],\n})\nsdk.start()\n`\n\nconst FRAMEWORK_OTEL_INIT_JS_BODY = `${FRAMEWORK_OTEL_INIT_HEADER}\nprocess.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'\n${OTEL_ENDPOINT_RESOLVER_CJS}\n${OTEL_OTLP_PROTOCOL_JS}\n${OTEL_OTLP_HEADERS_JS}\n\nconst { NodeSDK } = require('@opentelemetry/sdk-node')\nconst { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node')\n\nconst sdk = new NodeSDK({\n serviceName: process.env.OTEL_SERVICE_NAME,\n instrumentations: [getNodeAutoInstrumentations()],\n})\nsdk.start()\n`\n\nexport function renderFrameworkOtelInit(\n template: string,\n serviceName: string,\n projectName: string,\n): string {\n return template\n .replace(/__SERVICE_NAME__/g, serviceName)\n .replace(/__PROJECT__/g, projectName)\n}\n\n// Remix — `app/otel.server.{ts,js}` carries the SDK bootstrap. The framework\n// loads `entry.server.*` at server-process start, and a top-of-module import\n// of `./otel.server` runs the bootstrap before any request handler imports.\nexport const REMIX_OTEL_SERVER_TS = FRAMEWORK_OTEL_INIT_TS_BODY\nexport const REMIX_OTEL_SERVER_JS = FRAMEWORK_OTEL_INIT_JS_BODY\n\n// SvelteKit — `src/otel-init.{ts,js}` carries the SDK bootstrap; the\n// framework's `src/hooks.server.{ts,js}` imports it. When hooks.server is\n// absent, the installer writes the stub below alongside the import.\nexport const SVELTEKIT_OTEL_INIT_TS = FRAMEWORK_OTEL_INIT_TS_BODY\nexport const SVELTEKIT_OTEL_INIT_JS = FRAMEWORK_OTEL_INIT_JS_BODY\n\nexport const SVELTEKIT_HOOKS_SERVER_TS = `${FRAMEWORK_OTEL_INIT_HEADER}\nimport './otel-init'\n\nimport type { Handle } from '@sveltejs/kit'\n\nexport const handle: Handle = async ({ event, resolve }) => {\n return resolve(event)\n}\n`\n\nexport const SVELTEKIT_HOOKS_SERVER_JS = `${FRAMEWORK_OTEL_INIT_HEADER}\nimport './otel-init'\n\n/** @type {import('@sveltejs/kit').Handle} */\nexport const handle = async ({ event, resolve }) => {\n return resolve(event)\n}\n`\n\n// Nuxt — `server/plugins/otel.{ts,js}` is the convention-loaded plugin file;\n// it imports the sibling `otel-init.{ts,js}` which carries the SDK bootstrap.\nexport const NUXT_OTEL_INIT_TS = FRAMEWORK_OTEL_INIT_TS_BODY\nexport const NUXT_OTEL_INIT_JS = FRAMEWORK_OTEL_INIT_JS_BODY\n\nexport const NUXT_OTEL_PLUGIN_TS = `${FRAMEWORK_OTEL_INIT_HEADER}\nimport './otel-init'\n\nexport default defineNitroPlugin(() => {\n // OTel SDK is initialised at module-load via the side-effect import above.\n})\n`\n\nexport const NUXT_OTEL_PLUGIN_JS = `${FRAMEWORK_OTEL_INIT_HEADER}\nrequire('./otel-init')\n\nmodule.exports = defineNitroPlugin(() => {\n // OTel SDK is initialised at module-load via the side-effect import above.\n})\n`\n\n// Astro — `src/middleware.{ts,js}` runs once at module-load (and then per\n// request via onRequest). The top-of-module import of `./otel-init` boots\n// the SDK before the first request lands.\nexport const ASTRO_OTEL_INIT_TS = FRAMEWORK_OTEL_INIT_TS_BODY\nexport const ASTRO_OTEL_INIT_JS = FRAMEWORK_OTEL_INIT_JS_BODY\n\nexport const ASTRO_MIDDLEWARE_TS = `${FRAMEWORK_OTEL_INIT_HEADER}\nimport './otel-init'\n\nimport { defineMiddleware } from 'astro:middleware'\n\nexport const onRequest = defineMiddleware(async (context, next) => {\n return next()\n})\n`\n\nexport const ASTRO_MIDDLEWARE_JS = `${FRAMEWORK_OTEL_INIT_HEADER}\nimport './otel-init'\n\nimport { defineMiddleware } from 'astro:middleware'\n\nexport const onRequest = defineMiddleware(async (context, next) => {\n return next()\n})\n`\n","/**\n * Python SDK installer (ADR-047).\n *\n * `detect` matches on the canonical Python project markers — requirements.txt,\n * pyproject.toml, setup.py. `plan` produces dependency edits against the\n * primary manifest and entrypoint edits against a Procfile when one exists.\n *\n * MVP scope:\n * - requirements.txt is the full-fidelity manifest (read / append).\n * - pyproject.toml dependencies live inside a TOML `dependencies = [...]`\n * block; we line-insert into that block when found, otherwise hold off\n * on rewriting until a successor ADR addresses TOML editing properly.\n * - Procfile lines starting with `python` get prefixed with\n * `opentelemetry-instrument`.\n *\n * Lockfiles (poetry.lock, Pipfile.lock) are never touched. After `--apply`,\n * init's summary tells the user to run `pip install -r requirements.txt`\n * (or `poetry lock && poetry install`) so they own the lockfile commit.\n */\n\nimport { promises as fs } from 'node:fs'\nimport path from 'node:path'\nimport type {\n ApplyResult,\n DependencyEdit,\n EntrypointEdit,\n EnvEdit,\n Installer,\n InstallPlan,\n} from './shared.js'\n\nconst SDK_PACKAGES = [\n { name: 'opentelemetry-distro', version: '>=0.49b0' },\n { name: 'opentelemetry-exporter-otlp', version: '>=1.28.0' },\n] as const\n\nconst OTEL_ENV: EnvEdit = {\n file: null,\n key: 'OTEL_EXPORTER_OTLP_ENDPOINT',\n value: 'http://localhost:4318',\n}\n\nasync function exists(p: string): Promise<boolean> {\n try {\n await fs.stat(p)\n return true\n } catch {\n return false\n }\n}\n\nasync function detect(serviceDir: string): Promise<boolean> {\n const markers = ['requirements.txt', 'pyproject.toml', 'setup.py']\n for (const m of markers) {\n if (await exists(path.join(serviceDir, m))) return true\n }\n return false\n}\n\n// Strip a requirements.txt line down to its lower-cased package name.\n// `flask==3.0.0` → `flask`, `Flask>=2 ; python_version>\"3.6\"` → `flask`.\nfunction reqPackageName(line: string): string {\n const stripped = line.split('#')[0]?.trim() ?? ''\n const head = stripped.split(/[\\s;]/)[0] ?? ''\n return head.replace(/[<>=!~].*$/, '').toLowerCase()\n}\n\nasync function planRequirementsTxtEdits(\n serviceDir: string,\n): Promise<{ manifest: string; missing: typeof SDK_PACKAGES[number][] } | null> {\n const file = path.join(serviceDir, 'requirements.txt')\n if (!(await exists(file))) return null\n const raw = await fs.readFile(file, 'utf8')\n const presentNames = new Set(\n raw\n .split(/\\r?\\n/)\n .map(reqPackageName)\n .filter((n) => n.length > 0),\n )\n const missing = SDK_PACKAGES.filter((p) => !presentNames.has(p.name.toLowerCase()))\n return { manifest: file, missing: [...missing] }\n}\n\nasync function planProcfileEdits(serviceDir: string): Promise<EntrypointEdit[]> {\n const procfile = path.join(serviceDir, 'Procfile')\n if (!(await exists(procfile))) return []\n const raw = await fs.readFile(procfile, 'utf8')\n const edits: EntrypointEdit[] = []\n for (const line of raw.split(/\\r?\\n/)) {\n if (line.length === 0) continue\n // Procfile lines look like `<process>: <cmd>`. Prefix the cmd when it\n // starts with python and isn't already wrapped.\n const m = line.match(/^([a-zA-Z0-9_-]+):\\s*(.+)$/)\n if (!m) continue\n const cmd = m[2]!\n if (!/^python\\b/.test(cmd)) continue\n if (cmd.startsWith('opentelemetry-instrument ')) continue\n const after = `${m[1]}: opentelemetry-instrument ${cmd}`\n edits.push({ file: procfile, before: line, after })\n }\n return edits\n}\n\nasync function plan(serviceDir: string): Promise<InstallPlan> {\n const empty: InstallPlan = {\n language: 'python',\n serviceDir,\n dependencyEdits: [],\n entrypointEdits: [],\n envEdits: [],\n }\n\n const dependencyEdits: DependencyEdit[] = []\n const reqs = await planRequirementsTxtEdits(serviceDir)\n if (reqs) {\n for (const sdk of reqs.missing) {\n dependencyEdits.push({\n file: reqs.manifest,\n kind: 'add',\n name: sdk.name,\n version: sdk.version,\n })\n }\n }\n // pyproject.toml / setup.py without requirements.txt: deferred to a\n // successor ADR. The patch will note it; apply is a no-op for those\n // manifests in the MVP.\n\n const entrypointEdits = await planProcfileEdits(serviceDir)\n\n if (dependencyEdits.length === 0 && entrypointEdits.length === 0) {\n return empty\n }\n return {\n language: 'python',\n serviceDir,\n dependencyEdits,\n entrypointEdits,\n envEdits: [OTEL_ENV],\n }\n}\n\nasync function applyRequirementsTxt(\n manifest: string,\n edits: DependencyEdit[],\n original: string,\n): Promise<void> {\n // Append missing packages on their own lines. Preserve a trailing newline.\n const newlines = edits\n .filter((e) => e.kind === 'add')\n .map((e) => `${e.name}${e.version}`)\n const trailing = original.endsWith('\\n') ? '' : '\\n'\n const next = `${original}${trailing}${newlines.join('\\n')}\\n`\n const tmp = `${manifest}.${process.pid}.${Date.now()}.tmp`\n await fs.writeFile(tmp, next, 'utf8')\n await fs.rename(tmp, manifest)\n}\n\nasync function applyProcfile(\n procfile: string,\n edits: EntrypointEdit[],\n original: string,\n): Promise<void> {\n let next = original\n for (const e of edits) {\n if (!next.includes(e.before)) continue\n next = next.replace(e.before, e.after)\n }\n const tmp = `${procfile}.${process.pid}.${Date.now()}.tmp`\n await fs.writeFile(tmp, next, 'utf8')\n await fs.rename(tmp, procfile)\n}\n\nasync function apply(installPlan: InstallPlan): Promise<ApplyResult> {\n const { serviceDir } = installPlan\n const touched = new Set<string>()\n for (const e of installPlan.dependencyEdits) touched.add(e.file)\n for (const e of installPlan.entrypointEdits) touched.add(e.file)\n if (touched.size === 0) {\n return { serviceDir, outcome: 'already-instrumented', writtenFiles: [] }\n }\n\n const originals = new Map<string, string>()\n for (const file of touched) {\n try {\n originals.set(file, await fs.readFile(file, 'utf8'))\n } catch {\n // Mutation will fail loudly below; rollback covers what did land.\n }\n }\n\n const writtenFiles: string[] = []\n try {\n for (const file of touched) {\n const raw = originals.get(file)\n if (raw === undefined) {\n throw new Error(`python installer: cannot read ${file} during apply`)\n }\n const base = path.basename(file)\n if (base === 'requirements.txt') {\n const edits = installPlan.dependencyEdits.filter((e) => e.file === file)\n if (edits.length > 0) {\n await applyRequirementsTxt(file, edits, raw)\n writtenFiles.push(file)\n }\n } else if (base === 'Procfile') {\n const edits = installPlan.entrypointEdits.filter((e) => e.file === file)\n if (edits.length > 0) {\n await applyProcfile(file, edits, raw)\n writtenFiles.push(file)\n }\n }\n // pyproject.toml / setup.py: MVP no-op as planned above.\n }\n } catch (err) {\n await rollback(installPlan, originals)\n throw err\n }\n\n return { serviceDir, outcome: 'instrumented', writtenFiles }\n}\n\nasync function rollback(\n installPlan: InstallPlan,\n originals: Map<string, string>,\n): Promise<void> {\n const restored: string[] = []\n for (const [file, raw] of originals.entries()) {\n try {\n await fs.writeFile(file, raw, 'utf8')\n restored.push(file)\n } catch {\n // Best-effort.\n }\n }\n const lines = [\n '# neat-rollback.patch',\n '',\n `# Generated after a partial apply failure in the ${installPlan.language} installer.`,\n '# Files listed below were restored to their pre-apply contents.',\n '',\n ...restored.map((f) => `restored: ${f}`),\n '',\n ]\n const rollbackPath = path.join(installPlan.serviceDir, 'neat-rollback.patch')\n await fs.writeFile(rollbackPath, lines.join('\\n'), 'utf8')\n}\n\nexport const pythonInstaller: Installer = {\n name: 'python',\n detect,\n plan,\n apply,\n}\n","/**\n * Shared types for SDK installer modules (ADR-047).\n *\n * Each language has its own installer at `installers/<language>.ts` exporting\n * a `detect / plan / apply` triple. Plans are pure data — no fs side effects\n * during planning — so `init --dry-run` can render a patch without ever\n * touching the project. `apply` runs the codemod in place.\n *\n * Step 2 (this PR) ships the interface and an empty registry. Step 3 (Node\n * installer) and step 4 (Python installer) populate it.\n */\n\n// Field names match ADR-047's documented patch shape exactly: `file`, `kind`,\n// `name`, `version`. Patches will be reviewed by humans and matched in tests\n// by name; renaming for clarity would have cost more than it bought.\n\nexport interface DependencyEdit {\n file: string\n kind: 'add' | 'remove' | 'upgrade'\n name: string\n version: string\n fromVersion?: string\n}\n\nexport interface EntrypointEdit {\n file: string\n before: string\n after: string\n}\n\nexport interface EnvEdit {\n // `null` denotes a recommendation only — the user will set the env var in\n // their orchestration layer, NEAT does not write a `.env` file.\n file: string | null\n key: string\n value: string\n}\n\n// Files the installer generates from scratch (ADR-069 §1). The generated\n// `otel-init.{js,ts}` for the Node installer rides here, along with the\n// per-package `.env.neat` (ADR-069 §4). Treated as additive writes — the\n// apply phase skips any file already present (ADR-069 §6).\nexport interface GeneratedFile {\n file: string\n contents: string\n // When true, write only if the file does not already exist. The apply\n // phase logs an `already instrumented` / `already present` notice instead\n // of overwriting (ADR-069 §6).\n skipIfExists?: boolean\n}\n\nexport interface InstallPlan {\n // Free-form language tag matching the service node's language: `'javascript'`,\n // `'python'`, …\n language: string\n // Service directory the plan targets. Absolute path.\n serviceDir: string\n dependencyEdits: DependencyEdit[]\n entrypointEdits: EntrypointEdit[]\n envEdits: EnvEdit[]\n // ADR-069 §1, §4 — generated files (otel-init, .env.neat). Optional so\n // installers that don't generate files (the Python installer at MVP) can\n // omit it.\n generatedFiles?: GeneratedFile[]\n // ADR-069 §2 — flagged when entry-point resolution found nothing.\n // The apply phase records this in the summary and skips all file writes\n // for the package.\n libOnly?: boolean\n // ADR-069 §2 — resolved entry-point path (absolute). Present when the\n // installer is going to inject the require/import. Absent for libOnly\n // packages and for the Python installer.\n entryFile?: string\n // ADR-073 §1 + ADR-074 §3 — when a framework owns its own boot, the\n // installer skips `pkg.main` injection and emits framework-native\n // instrumentation files instead. Five values today: Next.js from v0.3.8,\n // then Remix / SvelteKit / Nuxt / Astro from v0.3.9.\n framework?: 'next' | 'remix' | 'sveltekit' | 'nuxt' | 'astro'\n // v0.4.4 / issue #370 — when a JavaScript package isn't a Node service\n // (browser bundle, React Native), the installer records the runtime here\n // and writes nothing. Absent → vanilla Node default (the existing apply\n // path). Browser-side OTel support (`@opentelemetry/sdk-trace-web`) lands\n // in a future release.\n runtimeKind?: 'browser-bundle' | 'react-native' | 'bun' | 'deno' | 'cloudflare-workers' | 'electron'\n // ADR-073 §1 — Next.js' `next.config.{js,ts,mjs}` may need the\n // `experimental.instrumentationHook: true` flag set when the major\n // version is < 15. The apply phase mutates the file in place when this\n // field is set. Absent → no config mutation planned.\n nextConfigEdit?: {\n file: string\n // Reason this edit is queued — surfaces in the dry-run patch and the\n // apply summary so the operator knows why their next.config moved.\n reason: string\n }\n}\n\n// ADR-069 §9 — apply outcome per service. The CLI surfaces these counts\n// at the end of `neat init --apply`. v0.4.4 / issue #370 — two new buckets\n// for non-Node JavaScript runtimes: `browser-bundle` (Vite, esbuild-shipped\n// SPAs) and `react-native` (Expo / RN bare). The Node SDK can't run in\n// either; both buckets skip every write and surface the package in the\n// summary so the operator knows the frontend wasn't instrumented.\nexport type ApplyOutcome =\n | 'instrumented'\n | 'already-instrumented'\n | 'lib-only'\n | 'failed'\n | 'browser-bundle'\n | 'react-native'\n | 'bun'\n | 'deno'\n | 'cloudflare-workers'\n | 'electron'\n\nexport interface ApplyResult {\n serviceDir: string\n outcome: ApplyOutcome\n // Free-form reason string for `lib-only` / `failed` outcomes. Surfaced\n // in the CLI summary so the user knows why a package was skipped.\n reason?: string\n // Absolute paths the apply phase actually wrote to. Used by the contract\n // test that asserts the allowed-path-set restriction (ADR-069 §7).\n writtenFiles: string[]\n}\n\n// Plan-time inputs the orchestrator threads through (v0.4.1 — refs #339).\n// `project` is the registered project name — the routing key the daemon\n// owns. When present the installer writes it as `OTEL_SERVICE_NAME` so the\n// OTLP wire and the registry agree end-to-end. Absent → installers fall\n// back to a package-local default for ad-hoc / test usage.\nexport interface PlanOptions {\n project?: string\n}\n\nexport interface Installer {\n // Free-form module name. Used for the patch header and for diagnostics.\n name: string\n // Returns true if the installer thinks `serviceDir` is shaped like a project\n // it can instrument. Cheap; no fs writes.\n detect(serviceDir: string): boolean | Promise<boolean>\n // Builds an `InstallPlan` describing the edits the installer would make.\n // Pure data; no fs writes. An empty plan (every edits array empty) means\n // the SDK is already installed and there is nothing to do.\n plan(serviceDir: string, opts?: PlanOptions): InstallPlan | Promise<InstallPlan>\n // Apply a previously-produced plan. Mutates files in place. On failure,\n // produces `<serviceDir>/neat-rollback.patch` per ADR-047 #7. Returns a\n // structured outcome so the CLI can surface coverage (ADR-069 §9).\n apply(plan: InstallPlan): Promise<ApplyResult>\n}\n\nexport function isEmptyPlan(plan: InstallPlan): boolean {\n return (\n plan.dependencyEdits.length === 0 &&\n plan.entrypointEdits.length === 0 &&\n plan.envEdits.length === 0 &&\n (plan.generatedFiles?.length ?? 0) === 0 &&\n plan.nextConfigEdit === undefined\n )\n}\n","/**\n * Installer registry. v0.2.5 step 2 ships the scaffolding; the JavaScript\n * installer (step 3) and Python installer (step 4) populate `INSTALLERS`.\n */\n\nimport type { Installer, InstallPlan } from './shared.js'\nimport { javascriptInstaller } from './javascript.js'\nimport { pythonInstaller } from './python.js'\nexport { isEmptyPlan } from './shared.js'\nexport { javascriptInstaller } from './javascript.js'\nexport { pythonInstaller } from './python.js'\nexport type {\n ApplyOutcome,\n ApplyResult,\n DependencyEdit,\n EntrypointEdit,\n EnvEdit,\n GeneratedFile,\n Installer,\n InstallPlan,\n} from './shared.js'\n\n// Lockfile basenames installers must never write to (ADR-047 — \"lockfiles\n// never touched\"). Used by the patch renderer's safety check below.\nexport const FORBIDDEN_LOCKFILES: ReadonlySet<string> = new Set([\n 'package-lock.json',\n 'pnpm-lock.yaml',\n 'yarn.lock',\n 'poetry.lock',\n 'Pipfile.lock',\n 'Gemfile.lock',\n 'Cargo.lock',\n 'go.sum',\n])\n\n// Order is priority — first match wins per service. JavaScript leads because\n// it's the most common shape in the projects NEAT targets; Python follows.\nexport const INSTALLERS: Installer[] = [javascriptInstaller, pythonInstaller]\n\n/**\n * Resolve the first installer that claims a given service directory. Returns\n * `null` if none match.\n *\n * Per language, the first matching installer wins. Order in `INSTALLERS`\n * defines that priority — declarations are explicit, not alphabetical.\n */\nexport async function pickInstaller(serviceDir: string): Promise<Installer | null> {\n for (const inst of INSTALLERS) {\n if (await inst.detect(serviceDir)) return inst\n }\n return null\n}\n\nexport interface PatchSection {\n installer: string\n plan: InstallPlan\n}\n\n/**\n * Render install plans into a single review-friendly text patch. The format\n * is intentionally human-shaped, not unified-diff: agents and humans both\n * read this. Determinism — same input, byte-identical output — is the\n * load-bearing property (ADR-047 #6).\n */\nexport function renderPatch(sections: PatchSection[]): string {\n if (sections.length === 0) {\n return [\n '# neat install plan',\n '',\n 'No SDK installers matched the discovered services. Two reasons this',\n 'normally happens:',\n ' - the project uses a language NEAT does not yet instrument',\n ' (Java / Ruby / .NET / Go / Rust are out of MVP scope per ADR-047);',\n ' - the SDK is already installed, so the installer returned an empty',\n ' plan.',\n '',\n 'You can re-run `neat init --apply` later to pick up new services.',\n '',\n ].join('\\n')\n }\n\n const lines: string[] = ['# neat install plan', '']\n for (const section of sections) {\n const { installer, plan } = section\n lines.push(`## ${installer} (${plan.language}) — ${plan.serviceDir}`)\n lines.push('')\n\n if (plan.libOnly) {\n lines.push('### skipped — no resolvable entry point (lib-only)')\n lines.push('')\n continue\n }\n\n if (plan.entryFile) {\n lines.push(`entry: ${plan.entryFile}`)\n lines.push('')\n }\n\n if (plan.dependencyEdits.length > 0) {\n lines.push('### dependencies')\n // Group by manifest file so each section names the path the apply phase\n // will write, satisfying the dry-run/apply path-parity contract\n // (ADR-069 §8).\n const byFile = new Map<string, typeof plan.dependencyEdits>()\n for (const dep of plan.dependencyEdits) {\n // Hard-fail rather than render a patch that could mislead the user\n // into thinking NEAT touches lockfiles.\n const base = dep.file.split(/[\\\\/]/).pop() ?? dep.file\n if (FORBIDDEN_LOCKFILES.has(base)) {\n throw new Error(\n `installer \"${installer}\" produced a dependency edit against a lockfile (${dep.file}); ` +\n `lockfiles must never be touched (ADR-047).`,\n )\n }\n const existing = byFile.get(dep.file) ?? []\n existing.push(dep)\n byFile.set(dep.file, existing)\n }\n for (const [file, deps] of byFile) {\n lines.push(`--- ${file}`)\n for (const dep of deps) {\n lines.push(`+ \"${dep.name}\": \"${dep.version}\"`)\n }\n }\n lines.push('')\n }\n\n if (plan.generatedFiles && plan.generatedFiles.length > 0) {\n lines.push('### generated files')\n for (const gen of plan.generatedFiles) {\n lines.push(`--- (new file) ${gen.file}`)\n for (const ln of gen.contents.split(/\\r?\\n/)) {\n lines.push(`+ ${ln}`)\n }\n }\n lines.push('')\n }\n\n if (plan.entrypointEdits.length > 0) {\n lines.push('### entry-point injection')\n for (const e of plan.entrypointEdits) {\n lines.push(`--- ${e.file}`)\n lines.push(`+ ${e.after}`)\n lines.push(` ${e.before}`)\n }\n lines.push('')\n }\n\n if (plan.envEdits.length > 0) {\n lines.push('### env (written to <package-dir>/.env.neat)')\n for (const env of plan.envEdits) {\n lines.push(`- ${env.key}=${env.value}`)\n }\n lines.push('')\n }\n\n // ADR-073 §1 — surface the next.config edit in the dry-run patch so the\n // operator can review the framework-flag change before it lands.\n if (plan.nextConfigEdit) {\n lines.push('### next.config (framework flag)')\n lines.push(`--- ${plan.nextConfigEdit.file}`)\n lines.push(`+ experimental: { instrumentationHook: true }, // ${plan.nextConfigEdit.reason}`)\n lines.push('')\n }\n }\n return lines.join('\\n')\n}\n","/**\n * One-command orchestrator (ADR-073 §1).\n *\n * Bare `neat <path>` dispatches here when the first positional argument\n * resolves to a directory and doesn't match a registered verb. Six steps,\n * in order:\n *\n * 1. Discovery + extraction (per static-extraction contract).\n * 2. `.gitignore` automation (ADR-073 §6) + project registration.\n * 3. SDK install apply — patches manifests + writes otel-init + writes\n * `.env.neat`. Default yes; `--no-instrument` opts out.\n * 4. Daemon spawn — `neatd start --detach` if no daemon is running.\n * Polls `/health` up to 15s for readiness.\n * 5. Browser open against the web UI on port 6328 (T9 NEAT).\n * Default yes; `--no-open` and headless runs skip the launch.\n * 6. Summary block — value-forward findings + OTel env-vars block.\n *\n * `neat init` retains its patch-by-default contract (ADR-046 §5). The\n * orchestrator runs apply unconditionally because the bare-`<path>` shape's\n * user intent is \"make this work end-to-end.\"\n */\n\nimport { promises as fs } from 'node:fs'\nimport http from 'node:http'\nimport net from 'node:net'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { spawn } from 'node:child_process'\nimport readline from 'node:readline'\nimport type { GraphEdge, GraphNode } from '@neat.is/types'\nimport { DEFAULT_PROJECT, getGraph, resetGraph } from './graph.js'\nimport { extractFromDirectory } from './extract.js'\nimport { discoverServices } from './extract/services.js'\nimport { ensureNeatOutIgnored } from './gitignore.js'\nimport { saveGraphToDisk } from './persist.js'\nimport { pathsForProject } from './projects.js'\nimport { addProject, listProjects, ProjectNameCollisionError, setStatus } from './registry.js'\nimport { readDaemonRecord, resolveHost, type DaemonPorts } from './daemon.js'\nimport { printBanner } from './banner.js'\nimport {\n isEmptyPlan,\n pickInstaller,\n type InstallPlan,\n} from './installers/index.js'\nimport { appFrameworkDependencies, uninstrumentedLibraries } from './installers/javascript.js'\nimport {\n detectPackageManager,\n runPackageManagerInstall,\n type PackageManager,\n type PackageManagerInvocation,\n} from './installers/package-manager.js'\n\nexport interface OrchestratorOptions {\n scanPath: string\n // Project name resolution mirrors `neat init` — basename of the scan\n // path unless overridden via --project.\n project: string\n projectExplicit: boolean\n // Skip step 3 (SDK install apply).\n noInstrument: boolean\n // Skip step 5 (browser open).\n noOpen: boolean\n // Skip the interactive prompt (CI invocation flag — implied when\n // stdin/stdout aren't a TTY).\n yes: boolean\n // Dashboard URL — defaults to http://localhost:6328 (T9 NEAT, ADR-059).\n dashboardUrl?: string\n // Health-check timeout in ms. Default 15s.\n daemonReadyTimeoutMs?: number\n}\n\nexport interface OrchestratorResult {\n exitCode: number\n // High-level step-by-step status for the test surface.\n steps: {\n discovery: { services: number; languages: string[] }\n extraction: { nodesAdded: number; edgesAdded: number }\n gitignore: 'added' | 'created' | 'unchanged'\n apply: {\n instrumented: number\n alreadyInstrumented: number\n libOnly: number\n skipped: boolean\n bun?: number\n deno?: number\n cloudflareWorkers?: number\n electron?: number\n // Issue #381 — package-manager invocations the orchestrator ran\n // after apply() mutated package.json. Absent for `--no-instrument`\n // runs and runs where every plan was empty.\n packageManagerInstalls?: PackageManagerInvocation[]\n }\n daemon: 'spawned' | 'already-running' | 'timed-out' | 'skipped'\n browser: 'opened' | 'skipped' | 'failed'\n }\n}\n\n// Shared sub-pipeline `neat sync` re-uses (ADR-074 §1). Discovery + extract\n// + snapshot write. Distinct from the first-run-only steps (registry add,\n// daemon spawn, browser open, summary block) that the orchestrator owns\n// directly.\nexport interface ExtractAndPersistOptions {\n scanPath: string\n project: string\n projectExplicit: boolean\n // When true, skip persisting to disk — for `neat sync --dry-run`.\n dryRun?: boolean\n}\n\nexport interface ExtractAndPersistResult {\n graph: ReturnType<typeof getGraph>\n graphKey: string\n services: Awaited<ReturnType<typeof discoverServices>>\n languages: string[]\n nodesAdded: number\n edgesAdded: number\n snapshotPath: string\n errorsPath: string\n}\n\nexport async function extractAndPersist(\n opts: ExtractAndPersistOptions,\n): Promise<ExtractAndPersistResult> {\n const services = await discoverServices(opts.scanPath)\n const languages = [...new Set(services.map((s) => s.node.language))].sort()\n\n const graphKey = opts.projectExplicit ? opts.project : DEFAULT_PROJECT\n resetGraph(graphKey)\n const graph = getGraph(graphKey)\n const projectPaths = pathsForProject(graphKey, path.join(opts.scanPath, 'neat-out'))\n const extraction = await extractFromDirectory(graph, opts.scanPath, {\n errorsPath: projectPaths.errorsPath,\n })\n if (!opts.dryRun) {\n await saveGraphToDisk(graph, projectPaths.snapshotPath)\n }\n return {\n graph,\n graphKey,\n services,\n languages,\n nodesAdded: extraction.nodesAdded,\n edgesAdded: extraction.edgesAdded,\n snapshotPath: projectPaths.snapshotPath,\n errorsPath: projectPaths.errorsPath,\n }\n}\n\n// SDK-install apply over a discovered service list. Returns the same shape\n// the orchestrator's result.steps.apply uses so callers (orchestrator + sync)\n// share the rollup logic. v0.4.1 / refs #339 — `project` is threaded through\n// to the installer so the per-package `.env.neat` carries\n// `OTEL_SERVICE_NAME=<project>`, matching the daemon's routing key.\nexport interface ApplyInstallersTally {\n instrumented: number\n alreadyInstrumented: number\n libOnly: number\n browserBundle: number\n reactNative: number\n // Issues #389 #390 — BYO-OTel out-of-scope runtime counters.\n bun: number\n deno: number\n cloudflareWorkers: number\n electron: number\n // Issue #381 — package-manager invocations the orchestrator ran after\n // apply() mutated package.json. One entry per distinct lockfile-owning\n // directory (monorepos share a single install run regardless of how\n // many sub-packages got instrumented). Empty when nothing was added to\n // any package.json.\n packageManagerInstalls: PackageManagerInvocation[]\n}\n\n// Knobs the test surface uses to swap the real spawn for a no-op. Default\n// uses the real installer; the contract suite passes a stub so the wiring\n// can be asserted without spawning npm against an unreliable registry.\nexport interface ApplyInstallersOptions {\n runInstall?: (cmd: { pm: PackageManager; cwd: string; args: string[] }) => Promise<PackageManagerInvocation>\n resolveManager?: (serviceDir: string) => Promise<{ pm: PackageManager; cwd: string; args: string[] }>\n}\n\nexport async function applyInstallersOver(\n services: Awaited<ReturnType<typeof discoverServices>>,\n project: string,\n options: ApplyInstallersOptions = {},\n): Promise<ApplyInstallersTally> {\n const resolveManager = options.resolveManager ?? detectPackageManager\n const runInstall = options.runInstall ?? runPackageManagerInstall\n let instrumented = 0\n let already = 0\n let libOnly = 0\n let browserBundle = 0\n let reactNative = 0\n let bun = 0\n let deno = 0\n let cloudflareWorkers = 0\n let electron = 0\n // Distinct install commands keyed by `<pm>:<cwd>` so a monorepo with\n // multiple instrumented sub-packages still runs install exactly once at\n // its workspace root. The first plan that landed a dep edit for a given\n // root wins; later sub-packages skip the re-run.\n const installPlans = new Map<string, { pm: PackageManager; cwd: string; args: string[] }>()\n for (const svc of services) {\n const installer = await pickInstaller(svc.dir)\n if (!installer) continue\n const plan: InstallPlan = await installer.plan(svc.dir, { project })\n if (isEmptyPlan(plan) && !plan.libOnly && plan.runtimeKind === undefined) {\n already++\n continue\n }\n const outcome = await installer.apply(plan)\n if (outcome.outcome === 'instrumented') {\n instrumented++\n // Schedule an install whenever apply() actually added deps. The\n // generated otel-init file lives under the service dir but the\n // packages the user must resolve at runtime (`@opentelemetry/sdk-node`,\n // `@prisma/instrumentation`) live in package.json — without the\n // install, the next `npm run dev` throws `Cannot find module ...`\n // before any of NEAT's code even loads.\n if (plan.dependencyEdits.length > 0) {\n const cmd = await resolveManager(svc.dir)\n const key = `${cmd.pm}:${cmd.cwd}`\n if (!installPlans.has(key)) installPlans.set(key, cmd)\n }\n } else if (outcome.outcome === 'already-instrumented') already++\n else if (outcome.outcome === 'lib-only') {\n libOnly++\n // Issue #545 / #570 — a lib-only package that carries a web-framework or\n // background-worker dependency is almost certainly a runnable app whose\n // entry the installer couldn't find, not a true library. Left in the\n // `lib-only N` tally it's silent; the runtime layer never engages and the\n // user has no idea why. Name the dependency we found and the recovery path\n // loudly. A genuine library with no app signal stays quiet — there's\n // nothing for its runtime layer to engage.\n const appDeps = svc.pkg ? appFrameworkDependencies(svc.pkg) : []\n if (appDeps.length > 0) {\n const svcName = path.basename(svc.dir)\n const list = appDeps.join(', ')\n console.warn(\n `neat: runtime layer won't engage for ${svcName}: no entry point found.\\n` +\n ` ${svc.dir} depends on ${list} — a runnable app — but neat couldn't resolve an entry to instrument.\\n` +\n ` Add a \"start\" script to package.json, or point neat at the entry file directly.`,\n )\n }\n }\n else if (outcome.outcome === 'browser-bundle') {\n browserBundle++\n console.log(`skipping ${svc.dir}: browser bundle; browser-OTel support lands in a future release.`)\n } else if (outcome.outcome === 'react-native') {\n reactNative++\n const svcName = path.basename(svc.dir)\n console.log(\n `neat: ${svc.dir} detected as React Native / Expo\\n` +\n ` The installer doesn't cover this runtime deterministically.\\n` +\n ` Configure your OTel binding to send spans to:\\n` +\n ` http://localhost:4318/projects/${project}/v1/traces\\n` +\n ` Set OTEL_SERVICE_NAME=${svcName}\\n` +\n ` See docs/installer-scope.md → \"Manual setup for out-of-scope runtimes\"`,\n )\n } else if (outcome.outcome === 'bun') {\n bun++\n const svcName = path.basename(svc.dir)\n console.log(\n `neat: ${svc.dir} detected as Bun\\n` +\n ` The installer doesn't cover this runtime deterministically.\\n` +\n ` Configure your OTel binding to send spans to:\\n` +\n ` http://localhost:4318/projects/${project}/v1/traces\\n` +\n ` Set OTEL_SERVICE_NAME=${svcName}\\n` +\n ` See docs/installer-scope.md → \"Manual setup for out-of-scope runtimes\"`,\n )\n } else if (outcome.outcome === 'deno') {\n deno++\n const svcName = path.basename(svc.dir)\n console.log(\n `neat: ${svc.dir} detected as Deno\\n` +\n ` The installer doesn't cover this runtime deterministically.\\n` +\n ` Configure your OTel binding to send spans to:\\n` +\n ` http://localhost:4318/projects/${project}/v1/traces\\n` +\n ` Set OTEL_SERVICE_NAME=${svcName}\\n` +\n ` See docs/installer-scope.md → \"Manual setup for out-of-scope runtimes\"`,\n )\n } else if (outcome.outcome === 'cloudflare-workers') {\n cloudflareWorkers++\n const svcName = path.basename(svc.dir)\n console.log(\n `neat: ${svc.dir} detected as Cloudflare Workers\\n` +\n ` The installer doesn't cover this runtime deterministically.\\n` +\n ` Configure your OTel binding to send spans to:\\n` +\n ` http://localhost:4318/projects/${project}/v1/traces\\n` +\n ` Set OTEL_SERVICE_NAME=${svcName}\\n` +\n ` See docs/installer-scope.md → \"Manual setup for out-of-scope runtimes\"`,\n )\n } else if (outcome.outcome === 'electron') {\n electron++\n const svcName = path.basename(svc.dir)\n console.log(\n `neat: ${svc.dir} detected as Electron\\n` +\n ` The installer doesn't cover this runtime deterministically.\\n` +\n ` Configure your OTel binding to send spans to:\\n` +\n ` http://localhost:4318/projects/${project}/v1/traces\\n` +\n ` Set OTEL_SERVICE_NAME=${svcName}\\n` +\n ` See docs/installer-scope.md → \"Manual setup for out-of-scope runtimes\"`,\n )\n }\n\n // Issue #546 — a service can be fully instrumented and still produce an\n // empty OBSERVED layer when it leans on a library the default\n // auto-instrumentation set doesn't cover (sqlite3 is the motivating case:\n // an in-process driver whose calls never cross an instrumented wire). The\n // differentiator goes silently empty. Name the libraries and point at the\n // extend path so the user knows why and what to do. Skip the lib-only and\n // out-of-scope buckets — there's no OBSERVED layer for them to be missing\n // from yet.\n if (svc.pkg && (outcome.outcome === 'instrumented' || outcome.outcome === 'already-instrumented')) {\n const gaps = uninstrumentedLibraries(svc.pkg)\n if (gaps.length > 0) {\n const svcName = path.basename(svc.dir)\n const list = gaps.join(', ')\n const subject = gaps.length === 1 ? 'this library' : 'these libraries'\n const aux = gaps.length === 1 ? \"isn't\" : \"aren't\"\n console.warn(\n `neat: calls to ${list} won't be observed by default in ${svcName}.\\n` +\n ` ${subject} ${aux} in the default instrumentation set, so they produce no OBSERVED edges.\\n` +\n ` Run \\`neat list-uninstrumented\\` to review them, then \\`neat extend\\` to capture them.`,\n )\n }\n }\n }\n\n // Run each distinct install command serially. Parallelism would race the\n // lockfile in the rare monorepo-of-monorepos case and most package\n // managers serialise themselves internally anyway — the time saving is\n // tiny next to the operator-trust cost of a corrupted lockfile.\n const packageManagerInstalls: PackageManagerInvocation[] = []\n for (const cmd of installPlans.values()) {\n console.log(`running \\`${cmd.pm} ${cmd.args.join(' ')}\\` in ${cmd.cwd}`)\n const result = await runInstall(cmd)\n packageManagerInstalls.push(result)\n if (result.exitCode !== 0) {\n console.error(\n `neat: ${cmd.pm} install failed in ${cmd.cwd} (exit ${result.exitCode}); run it manually to surface the error.`,\n )\n if (result.stderr.length > 0) {\n for (const line of result.stderr.split(/\\r?\\n/).slice(0, 20)) {\n console.error(` ${line}`)\n }\n }\n }\n }\n\n return {\n instrumented,\n alreadyInstrumented: already,\n libOnly,\n browserBundle,\n reactNative,\n bun,\n deno,\n cloudflareWorkers,\n electron,\n packageManagerInstalls,\n }\n}\n\nasync function promptYesNo(question: string): Promise<boolean> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout })\n return new Promise((resolve) => {\n rl.question(`${question} [Y/n] `, (answer) => {\n rl.close()\n const trimmed = answer.trim().toLowerCase()\n resolve(trimmed === '' || trimmed === 'y' || trimmed === 'yes')\n })\n })\n}\n\n// 60s covers boot + per-project graph load across a registry with several\n// sibling projects. Issue #340 — `app.listen()` now returns the moment the\n// socket binds, so the steady-state happy path lands well inside the first\n// second; the longer ceiling is the cold-clone window where multi-project\n// bootstraps run in the background after listen.\nconst DEFAULT_DAEMON_READY_TIMEOUT_MS = 60_000\n\n// 500ms poll cadence — responsive enough that the operator sees a fresh\n// status line on every transition without spamming the daemon.\nconst PROBE_INTERVAL_MS = 500\n\ninterface DaemonHealthResponse {\n ok?: boolean\n uptimeMs?: number\n projects?: Array<{\n name: string\n status?: 'bootstrapping' | 'active' | 'broken'\n elapsedMs?: number\n }>\n}\n\nasync function fetchDaemonHealth(restPort: number): Promise<DaemonHealthResponse | null> {\n return new Promise((resolve) => {\n const req = http.get(`http://127.0.0.1:${restPort}/health`, (res) => {\n const ok = res.statusCode !== undefined && res.statusCode >= 200 && res.statusCode < 300\n if (!ok) {\n res.resume()\n resolve(null)\n return\n }\n let body = ''\n res.setEncoding('utf8')\n res.on('data', (chunk: string) => { body += chunk })\n res.on('end', () => {\n try {\n resolve(JSON.parse(body) as DaemonHealthResponse)\n } catch {\n resolve({ ok: true })\n }\n })\n })\n req.on('error', () => resolve(null))\n req.setTimeout(1000, () => {\n req.destroy()\n resolve(null)\n })\n })\n}\n\n\nasync function probeProjectHealth(\n restPort: number,\n name: string,\n): Promise<'bootstrapping' | 'active' | 'broken'> {\n return new Promise((resolve) => {\n const req = http.get(\n `http://127.0.0.1:${restPort}/projects/${encodeURIComponent(name)}/health`,\n (res) => {\n const code = res.statusCode ?? 0\n res.resume()\n if (code >= 200 && code < 300) resolve('active')\n else resolve('bootstrapping')\n },\n )\n req.on('error', () => resolve('bootstrapping'))\n req.setTimeout(1000, () => {\n req.destroy()\n resolve('bootstrapping')\n })\n })\n}\n\n// Resolve the status of the one project this run just started — and only that\n// project (ADR-096: the orchestrator spawns a daemon scoped to a single\n// project, so readiness is a single-project question). A broken or stale\n// sibling sitting in the machine registry must never gate this run; it\n// belongs to a different daemon and would otherwise poison an otherwise-healthy\n// start. Prefers the daemon-wide /health entry for the project when one is\n// carried (the legacy multi-project shape); otherwise probes that project's\n// per-project /health directly. The registry is not consulted — siblings are\n// out of scope by construction.\nasync function snapshotProjectStatus(\n restPort: number,\n project: string,\n body: DaemonHealthResponse,\n): Promise<Array<{ name: string; status: 'bootstrapping' | 'active' | 'broken' }>> {\n if (body.projects && body.projects.length > 0) {\n const mine = body.projects.filter((p) => p.name === project)\n if (mine.length > 0) {\n return mine.map((p) => ({ name: p.name, status: p.status ?? 'active' }))\n }\n }\n return [{ name: project, status: await probeProjectHealth(restPort, project) }]\n}\n\ninterface DaemonReadyResult {\n ready: boolean\n brokenProjects: string[]\n stillBootstrapping: string[]\n}\n\nasync function waitForDaemonReady(\n restPort: number,\n project: string,\n timeoutMs: number,\n): Promise<DaemonReadyResult> {\n const deadline = Date.now() + timeoutMs\n let lastBootstrapping: string[] = []\n while (Date.now() < deadline) {\n const body = await fetchDaemonHealth(restPort)\n if (body !== null) {\n const projects = await snapshotProjectStatus(restPort, project, body)\n const bootstrapping = projects\n .filter((p) => p.status === 'bootstrapping')\n .map((p) => p.name)\n const broken = projects.filter((p) => p.status === 'broken').map((p) => p.name)\n if (bootstrapping.length === 0) {\n return { ready: true, brokenProjects: broken, stillBootstrapping: [] }\n }\n const key = bootstrapping.slice().sort().join(',')\n const prevKey = lastBootstrapping.slice().sort().join(',')\n if (key !== prevKey) {\n const plural = bootstrapping.length === 1 ? '' : 's'\n console.log(\n `neat: waiting on ${bootstrapping.length} project${plural}: ${bootstrapping.join(', ')}`,\n )\n lastBootstrapping = bootstrapping\n }\n }\n await new Promise((r) => setTimeout(r, PROBE_INTERVAL_MS))\n }\n const final = await fetchDaemonHealth(restPort)\n const projects = final ? await snapshotProjectStatus(restPort, project, final) : []\n return {\n ready: false,\n brokenProjects: projects.filter((p) => p.status === 'broken').map((p) => p.name),\n stillBootstrapping: projects\n .filter((p) => p.status === 'bootstrapping')\n .map((p) => p.name),\n }\n}\n\n// Port-availability probe (#377 / ADR-079 §2).\n//\n// The orchestrator's daemon-spawn step assumes `:8080` (REST), `:4318` (OTLP\n// HTTP), and `:6328` (web UI) are free. When a sibling daemon from another\n// terminal session — or any unrelated listener — is holding one of them, the\n// spawn exits 1 with no actionable message. The probe runs before\n// `spawnDaemonDetached()` and surfaces the named port plus recovery commands\n// on collision, exiting with code 3 (environmental) per the CLI exit-code\n// surface.\nexport const NEAT_PORTS = [8080, 4318, 6328] as const\n\n// Probe `host` so the availability answer reflects the interface the daemon\n// will actually bind. The daemon binds 0.0.0.0 on the authenticated path\n// (resolveHost) and 127.0.0.1 otherwise; probing loopback while the daemon\n// binds the wildcard reads a wildcard-held port as free, hands it to the\n// spawn, and the daemon dies on EADDRINUSE before it can write daemon.json —\n// the silent \"daemon.json timeout\" (#574). Check host must equal bind host.\n//\n// #580 — and the answer must span both IP families. A daemon binds one host,\n// but clients reach it through `localhost`, which resolves `::1` ahead of\n// `127.0.0.1` on macOS and other dual-stack systems. A foreign listener on the\n// IPv6 side of a port we bind only on IPv4 swallows every `localhost` query\n// while a pure-IPv4 probe still reads the port as free, so allocation hands\n// over a port that's already shadowed. We probe the bind host's family AND its\n// cross-family loopback/wildcard sibling, and call the port taken if a holder\n// sits on either. A family the machine genuinely lacks (no IPv6 stack →\n// EADDRNOTAVAIL / EAFNOSUPPORT on the sibling) is not a holder and doesn't\n// block allocation; only an EADDRINUSE on the sibling does.\ntype ProbeOutcome = 'free' | 'in-use' | 'unavailable'\n\nfunction probeBind(port: number, host: string): Promise<ProbeOutcome> {\n return new Promise((resolve) => {\n const server = net.createServer()\n server.once('error', (err) => {\n resolve((err as NodeJS.ErrnoException).code === 'EADDRINUSE' ? 'in-use' : 'unavailable')\n })\n server.once('listening', () => server.close(() => resolve('free')))\n server.listen(port, host)\n })\n}\n\n// The cross-family sibling to also probe for a shadowing holder. Loopback and\n// wildcard are the only hosts that have a meaningful sibling; a specific IP is\n// probed on its own.\nfunction crossFamilyHost(host: string): string | null {\n switch (host) {\n case '127.0.0.1':\n case 'localhost':\n return '::1'\n case '::1':\n return '127.0.0.1'\n case '0.0.0.0':\n return '::'\n case '::':\n return '0.0.0.0'\n default:\n return null\n }\n}\n\nexport async function isPortFree(port: number, host = '127.0.0.1'): Promise<boolean> {\n // Primary interface: any failure (in-use or otherwise) means we can't bind\n // it, so the port isn't usable — preserve the pre-#580 \"any error → false\".\n if ((await probeBind(port, host)) !== 'free') return false\n // Cross-family sibling: only a live holder (EADDRINUSE) counts. A missing\n // family answers 'unavailable' and is not a shadow.\n const sibling = crossFamilyHost(host)\n if (sibling && (await probeBind(port, sibling)) === 'in-use') return false\n return true\n}\n\nexport async function probePortsFree(): Promise<\n { free: true } | { free: false; held: number }\n> {\n for (const port of NEAT_PORTS) {\n if (!(await isPortFree(port))) return { free: false, held: port }\n }\n return { free: true }\n}\n\nexport function formatPortCollisionMessage(port: number): string[] {\n return [\n `neat: port ${port} is in use; the NEAT daemon needs it.`,\n ` run \\`neatd stop\\` to release the previous daemon, or`,\n ` \\`lsof -i :${port}\\` to find the holding process.`,\n ]\n}\n\n// ── Per-project port allocation (ADR-096 §3 / project-daemon contract) ──────\n//\n// One daemon per project means a second project's daemon must coexist with the\n// first rather than fight for one binding. The canonical triple\n// (8080/4318/6328) stays the first choice; when any of it is taken, allocation\n// steps to the next free triple. Each project's ports are persisted (in its\n// daemon.json, written by the daemon) and reused across restarts, so the\n// instrumented app's endpoint stays constant — critical, because the generated\n// otel-init reads `ports.otlp` back and a drifting port would silently dark the\n// OBSERVED layer (§1).\n\n// How far to step before giving up. 8 triples (8080→8101 etc.) is far more\n// concurrent projects than a laptop ever runs; past it the environment is\n// genuinely saturated and the operator wants the collision message, not an\n// ever-climbing search.\nconst PORT_ALLOCATION_ATTEMPTS = 8\n// Stride between candidate triples. Keeping rest/otlp/web on the same offset\n// keeps each project's three ports visually grouped (8080/4318/6328 →\n// 8081/4319/6329 …) so `neat ps` output reads cleanly.\nconst PORT_STRIDE = 1\n\nexport interface AllocatedPorts extends DaemonPorts {}\n\n// True when all three ports of a candidate triple are free on `host` — the\n// interface the daemon will bind (see isPortFree).\nasync function tripleFree(ports: AllocatedPorts, host = '127.0.0.1'): Promise<boolean> {\n for (const p of [ports.rest, ports.otlp, ports.web]) {\n if (!(await isPortFree(p, host))) return false\n }\n return true\n}\n\n// Allocate a free port triple, canonical 8080/4318/6328 first, stepping by\n// PORT_STRIDE to the next free triple when the canonical set is taken (a\n// sibling project's daemon already holds it). Returns null when nothing in the\n// search window is free — a genuinely saturated environment. Reuse of a\n// project's persisted ports is the caller's decision (it has the /health\n// identity result); this only finds fresh free ports.\nexport async function allocatePorts(host = '127.0.0.1'): Promise<AllocatedPorts | null> {\n const [baseRest, baseOtlp, baseWeb] = NEAT_PORTS\n for (let i = 0; i < PORT_ALLOCATION_ATTEMPTS; i++) {\n const candidate: AllocatedPorts = {\n rest: baseRest + i * PORT_STRIDE,\n otlp: baseOtlp + i * PORT_STRIDE,\n web: baseWeb + i * PORT_STRIDE,\n }\n if (await tripleFree(candidate, host)) return candidate\n }\n return null\n}\n\n// Read this project's persisted ports from its daemon.json, if any. Returns\n// null when the project has never run a daemon (fresh install) or the record\n// is malformed — the caller falls back to fresh allocation.\nexport async function persistedPortsFor(scanPath: string): Promise<AllocatedPorts | null> {\n const record = await readDaemonRecord(scanPath)\n if (!record) return null\n return { rest: record.ports.rest, otlp: record.ports.otlp, web: record.ports.web }\n}\n\n// Project-local concurrent-spawn guard (contract §1 \"exactly one daemon\").\n// Two `neat init` on the same project in the same instant would each find no\n// healthy daemon, allocate the same canonical triple, and the second daemon's\n// bind would crash on the conflict. A best-effort lockfile under the project's\n// own neat-out/ serialises them: the loser waits for the winner's daemon to\n// answer /health rather than racing it to the bind. It's project-local — no\n// machine-wide lock — so two DIFFERENT projects never contend here.\nasync function acquireSpawnLock(scanPath: string): Promise<(() => Promise<void>) | null> {\n const lockPath = path.join(scanPath, 'neat-out', 'daemon.spawn.lock')\n await fs.mkdir(path.dirname(lockPath), { recursive: true })\n const STALE_LOCK_MS = 60_000\n try {\n const fd = await fs.open(lockPath, 'wx')\n await fd.writeFile(`${process.pid}\\n`, 'utf8')\n await fd.close()\n return async () => {\n await fs.unlink(lockPath).catch(() => {})\n }\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'EEXIST') return null\n // A lock exists. If it's stale (a crashed prior spawn), reclaim it.\n try {\n const stat = await fs.stat(lockPath)\n if (Date.now() - stat.mtimeMs > STALE_LOCK_MS) {\n await fs.unlink(lockPath).catch(() => {})\n return acquireSpawnLock(scanPath)\n }\n } catch {\n // stat raced with the holder's unlink — treat as not-held and retry once.\n return acquireSpawnLock(scanPath)\n }\n return null\n }\n}\n\n// Wait (briefly) for another concurrent spawn to bring up a daemon that answers\n// /health for this project. Used by the loser of the spawn-lock race so it\n// reuses the winner's daemon instead of erroring.\nasync function waitForPeerDaemon(\n restPort: number,\n project: string,\n timeoutMs: number,\n): Promise<boolean> {\n const deadline = Date.now() + timeoutMs\n while (Date.now() < deadline) {\n if (await healthIsForProject(restPort, project)) return true\n await new Promise((r) => setTimeout(r, PROBE_INTERVAL_MS))\n }\n return healthIsForProject(restPort, project)\n}\n\n// The spawn-vs-reuse identity check (contract §7). A daemon found answering\n// /health on a candidate REST port is reused only when it reports THIS project;\n// a different project's daemon on a reused port answers with its own name and\n// is correctly treated as not-mine. Returns true only on a confirmed match.\nasync function healthIsForProject(restPort: number, project: string): Promise<boolean> {\n const body = await fetchDaemonHealth(restPort)\n if (body === null) return false\n // Single-project daemons stamp a top-level `project`; be tolerant of the\n // legacy daemon-wide shape that lists projects in an array, so a transitional\n // daemon still matches by name.\n const named = (body as { project?: string }).project\n if (typeof named === 'string') return named === project\n if (Array.isArray(body.projects)) {\n return body.projects.some((p) => p.name === project)\n }\n return false\n}\n\n// Test seam for the spawn-reuse identity check (project-daemon contract §7).\n// Production callers go through the spawn flow; the integration suite asserts\n// the matching-vs-not-mine decision directly.\nexport function healthIsForProjectForTest(restPort: number, project: string): Promise<boolean> {\n return healthIsForProject(restPort, project)\n}\n\n// Test seam for the readiness wait (one-command-cli contract §1 / ADR-096).\n// The integration suite drives a fake single-project daemon against this to\n// prove the gate scopes to the just-started project and never blocks on a\n// broken sibling sitting in the registry.\nexport function waitForDaemonReadyForTest(\n restPort: number,\n project: string,\n timeoutMs: number,\n): Promise<DaemonReadyResult> {\n return waitForDaemonReady(restPort, project, timeoutMs)\n}\n\n// Where a project's daemon writes its stdout/stderr. Lives beside the\n// snapshot under the project's own `neat-out/` so the operator finds it next\n// to everything else NEAT wrote for that project.\nexport function daemonLogPath(projectPath: string): string {\n return path.join(projectPath, 'neat-out', 'daemon.log')\n}\n\n// Spawn the daemon as a fully detached background process and hand the terminal\n// back. `detached: true` puts it in its own session and `unref()` lets the\n// orchestrator exit cleanly the moment its own work is done — the one-command\n// flow prints its summary and returns the prompt (#639/#529). The daemon's\n// stdout and stderr go to `<project>/neat-out/daemon.log`, never the caller's\n// fds: an inherited stderr keeps the shell attached and streams the daemon's\n// ongoing logs into the operator's terminal indefinitely. Startup faults (a\n// `BindAuthorityError`, a bind collision) land in that log; the caller's\n// `/health` readiness poll is what tells the operator a start failed, and\n// points them at the log for the detail.\n//\n// ADR-096 — when `spec` is given the daemon is spawned scoped to that one\n// project on the allocated ports (passed through the env neatd + startDaemon\n// read). The legacy no-arg form spawns the multi-project daemon on the\n// canonical ports; it stays so callers we haven't migrated keep working.\nexport interface DaemonSpawnSpec {\n project: string\n projectPath: string\n ports: AllocatedPorts\n}\n\nfunction spawnDaemonDetached(\n spec?: DaemonSpawnSpec,\n): import('node:child_process').ChildProcess {\n // Resolve the neatd entry inside the @neat.is/core dist next to this\n // file. `import.meta.url` is post-bundling — at runtime, this resolves\n // to `<core>/dist/neatd.{js,cjs}`. We pick the .cjs because tsup ships\n // it in both forms and node tolerates either. `fileURLToPath` (not\n // `URL().pathname`) so the Windows drive-letter path resolves to\n // `C:\\…\\neatd.cjs`, not the invalid `/C:/…` a raw URL pathname yields.\n const here = path.dirname(fileURLToPath(import.meta.url))\n const candidates = [\n path.join(here, 'neatd.cjs'),\n path.join(here, 'neatd.js'),\n ]\n let entry: string | null = null\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const fsSync = require('node:fs') as typeof import('node:fs')\n for (const c of candidates) {\n try {\n fsSync.accessSync(c)\n entry = c\n break\n } catch {\n // try next\n }\n }\n if (!entry) {\n throw new Error(`orchestrator: cannot locate neatd entry in ${here}`)\n }\n\n // ADR-073 §3 + issue #341 — first-touch path is loopback-only. When the\n // operator hasn't set `NEAT_AUTH_TOKEN` the orchestrator hard-pins\n // HOST=127.0.0.1 in the child env so `assertBindAuthority` lets the bind\n // through. Public-bind is opt-in via the token (and an explicit\n // `HOST=0.0.0.0` if the operator wants the literal). The parent's HOST is\n // preserved untouched when the token is set — that's the deploy path,\n // where the platform owns the bind decision.\n const env = { ...process.env }\n const hasToken = typeof env.NEAT_AUTH_TOKEN === 'string' && env.NEAT_AUTH_TOKEN.length > 0\n if (!hasToken && (!env.HOST || env.HOST.length === 0)) {\n env.HOST = '127.0.0.1'\n }\n\n // ADR-096 — scope the spawned daemon to one project on the allocated ports.\n // neatd reads NEAT_PROJECT/NEAT_PROJECT_PATH and PORT/OTEL_PORT/NEAT_WEB_PORT\n // and threads them into startDaemon, which serves only this project and\n // writes its daemon.json self-description with these ports.\n if (spec) {\n env.NEAT_PROJECT = spec.project\n env.NEAT_PROJECT_PATH = spec.projectPath\n env.PORT = String(spec.ports.rest)\n env.OTEL_PORT = String(spec.ports.otlp)\n env.NEAT_WEB_PORT = String(spec.ports.web)\n }\n\n // Redirect the daemon's output to a log file rather than inheriting the\n // caller's fds (#639/#529). Inherited stderr keeps the shell attached — the\n // prompt never returns and the daemon's ongoing warnings spill into the\n // operator's terminal. A per-project `neat-out/daemon.log` keeps the output\n // reachable without holding the terminal. We open once and hand the same fd\n // to stdout and stderr; the OS dups it into the child at spawn, so the parent\n // closes its copy right after. With no spec (legacy multi-project form) there\n // is no project dir to write into, so output is discarded.\n let logFd: number | null = null\n if (spec) {\n const logPath = daemonLogPath(spec.projectPath)\n fsSync.mkdirSync(path.dirname(logPath), { recursive: true })\n logFd = fsSync.openSync(logPath, 'a')\n }\n const child = spawn(process.execPath, [entry, 'start'], {\n detached: true,\n stdio: ['ignore', logFd ?? 'ignore', logFd ?? 'ignore'],\n env,\n })\n child.unref()\n if (logFd !== null) fsSync.closeSync(logFd)\n return child\n}\n\nfunction openBrowser(url: string): 'opened' | 'failed' {\n // Skip when running headlessly; we don't want CI invocations to fail\n // because xdg-open isn't installed.\n if (!process.stdout.isTTY) return 'failed'\n const platform = process.platform\n const cmd =\n platform === 'darwin' ? 'open' :\n platform === 'win32' ? 'cmd' :\n 'xdg-open'\n const args = platform === 'win32' ? ['/c', 'start', '', url] : [url]\n try {\n const child = spawn(cmd, args, { detached: true, stdio: 'ignore' })\n child.on('error', () => {})\n child.unref()\n return 'opened'\n } catch {\n return 'failed'\n }\n}\n\nexport async function runOrchestrator(opts: OrchestratorOptions): Promise<OrchestratorResult> {\n const result: OrchestratorResult = {\n exitCode: 0,\n steps: {\n discovery: { services: 0, languages: [] },\n extraction: { nodesAdded: 0, edgesAdded: 0 },\n gitignore: 'unchanged',\n apply: { instrumented: 0, alreadyInstrumented: 0, libOnly: 0, skipped: false },\n daemon: 'skipped',\n browser: 'skipped',\n },\n }\n\n // ── Path validation ───────────────────────────────────────────────────\n const stat = await fs.stat(opts.scanPath).catch(() => null)\n if (!stat || !stat.isDirectory()) {\n console.error(`neat: ${opts.scanPath} is not a directory`)\n result.exitCode = 2\n return result\n }\n\n // ASCII banner up front — this is the one-command zero-to-graph path's\n // first impression (issue #483). Same artwork `neat init` prints, shared\n // through banner.ts so it's never duplicated.\n printBanner()\n console.log(`neat: ${opts.scanPath}`)\n console.log('')\n\n // ── Step 1: discovery, Step 2: extraction + snapshot ─────────────────\n // Shared with `neat sync` (ADR-074 §1) via extractAndPersist.\n const persisted = await extractAndPersist({\n scanPath: opts.scanPath,\n project: opts.project,\n projectExplicit: opts.projectExplicit,\n })\n const { graph, services, languages } = persisted\n result.steps.discovery = { services: services.length, languages }\n console.log(`discovered ${services.length} service(s) across ${languages.length} language(s)`)\n\n // No services means nothing to instrument and no graph worth spawning a\n // daemon for. Bail with a clear pointer instead of standing up an empty\n // daemon (issue #483) — most often the operator ran from outside their\n // project root.\n if (services.length === 0) {\n console.error(\n `neat: no services found in ${opts.scanPath} — run from inside your project root, or \\`npx neat.is <path>\\``,\n )\n result.exitCode = 2\n return result\n }\n\n // ── Confirmation prompt (default yes; --no-instrument or no-TTY skip)\n let runApply = !opts.noInstrument\n if (runApply && !opts.yes && process.stdout.isTTY && process.stdin.isTTY) {\n runApply = await promptYesNo('instrument your services and open the dashboard?')\n }\n\n result.steps.extraction = {\n nodesAdded: persisted.nodesAdded,\n edgesAdded: persisted.edgesAdded,\n }\n\n const gi = await ensureNeatOutIgnored(opts.scanPath)\n result.steps.gitignore = gi.action\n if (gi.action !== 'unchanged') {\n console.log(`${gi.action} .gitignore (neat-out/)`)\n }\n\n let currentProjectName = opts.project\n try {\n const entry = await addProject({\n name: opts.project,\n path: opts.scanPath,\n languages,\n status: 'active',\n })\n currentProjectName = entry.name\n } catch (err) {\n if (!(err instanceof ProjectNameCollisionError)) throw err\n // Same path, same name → re-init. Different path → bail with a clear\n // message so the operator can pass --project <other-name>.\n console.error(`neat: ${err.message}`)\n console.error('pass --project <other-name> to register under a different name.')\n result.exitCode = 1\n return result\n }\n\n // Narrow the active-project surface to what the operator is currently in.\n // Every other `active` entry transitions to `paused`; `broken` is left alone\n // so the daemon's broken-path handling still surfaces. `neat resume <name>`\n // brings any of them back when cross-project work is the explicit intent.\n const siblings = await listProjects()\n const paused: string[] = []\n for (const p of siblings) {\n if (p.name !== currentProjectName && p.status === 'active') {\n await setStatus(p.name, 'paused')\n paused.push(p.name)\n }\n }\n if (paused.length > 0) {\n const plural = paused.length === 1 ? '' : 's'\n console.log(\n `neat: paused ${paused.length} sibling project${plural}; run \\`neat resume <name>\\` to bring one back active.`,\n )\n }\n\n // ── Step 3: SDK install apply (default yes; --no-instrument skips) ───\n if (!runApply) {\n result.steps.apply.skipped = true\n console.log('skipped instrumentation (--no-instrument)')\n } else {\n const tally = await applyInstallersOver(services, opts.project)\n result.steps.apply = { ...tally, skipped: false }\n console.log(\n `instrumented ${tally.instrumented}, already ${tally.alreadyInstrumented}, lib-only ${tally.libOnly}`,\n )\n const failedInstalls = tally.packageManagerInstalls.filter((i) => i.exitCode !== 0)\n if (failedInstalls.length > 0) {\n result.exitCode = 1\n }\n }\n\n // ── Step 4: daemon spawn + health poll (ADR-096 per-project daemon) ──\n //\n // One daemon per project: this project either has a live daemon to reuse,\n // or we allocate ports and spawn one scoped to it. The spawn-vs-reuse\n // decision turns on the /health identity check — a daemon answering on a\n // port must report THIS project to count as ours (a sibling project's\n // daemon on a port we'd otherwise reuse is correctly seen as not-mine).\n const timeoutMs = opts.daemonReadyTimeoutMs ?? DEFAULT_DAEMON_READY_TIMEOUT_MS\n // The interface the spawned daemon will bind — 0.0.0.0 on the authenticated\n // path, 127.0.0.1 otherwise. resolveHost is the single source of that\n // decision (the daemon calls it too), so the free-port probe below checks the\n // exact interface the bind will use; a wildcard-held port must read as taken\n // on the token path or the spawn collides on EADDRINUSE (#574).\n const bindHost = resolveHost(\n {},\n typeof process.env.NEAT_AUTH_TOKEN === 'string' && process.env.NEAT_AUTH_TOKEN.length > 0,\n )\n // Ports the project used last time (its daemon.json), if any — reuse keeps\n // the instrumented app's exporter endpoint stable across restarts (§3).\n const persistedPorts = await persistedPortsFor(opts.scanPath)\n // Allocated ports the spawned daemon binds. Settled below; defaults to the\n // canonical web port so the dashboard URL has a value even on early bailouts.\n let allocated: AllocatedPorts | null = null\n\n // Already running? A daemon answering /health on the persisted REST port and\n // reporting this project is reused outright.\n if (persistedPorts && (await healthIsForProject(persistedPorts.rest, currentProjectName))) {\n result.steps.daemon = 'already-running'\n allocated = persistedPorts\n } else {\n // Decide the ports to bind. Reuse the persisted triple when its REST port\n // is free (the prior daemon is gone, so we take its ports back and the\n // app's endpoint stays put); otherwise allocate a fresh free triple,\n // stepping past the canonical set when a sibling project holds it.\n if (\n persistedPorts &&\n (await isPortFree(persistedPorts.rest, bindHost)) &&\n (await tripleFree(persistedPorts, bindHost))\n ) {\n allocated = persistedPorts\n } else {\n allocated = await allocatePorts(bindHost)\n }\n if (!allocated) {\n // The search window is saturated — surface the canonical REST port as the\n // representative collision so the operator gets the recovery hints.\n for (const line of formatPortCollisionMessage(NEAT_PORTS[0])) {\n console.error(line)\n }\n result.exitCode = 3\n return result\n }\n\n // Concurrent-spawn guard (§1). The winner spawns; a loser that couldn't\n // take the lock waits for the winner's daemon to answer /health and reuses\n // it rather than racing it into a bind conflict.\n const release = await acquireSpawnLock(opts.scanPath)\n if (!release) {\n const reused = await waitForPeerDaemon(allocated.rest, currentProjectName, timeoutMs)\n if (reused) {\n result.steps.daemon = 'already-running'\n } else {\n console.error('neat: another `neat` is spawning this project but its daemon did not come up in time')\n result.exitCode = 1\n return result\n }\n } else {\n try {\n // Re-check under the lock: a daemon the winner brought up between our\n // first probe and acquiring the lock is reused instead of double-spawned.\n if (await healthIsForProject(allocated.rest, currentProjectName)) {\n result.steps.daemon = 'already-running'\n } else {\n spawnDaemonDetached({\n project: currentProjectName,\n projectPath: opts.scanPath,\n ports: allocated,\n })\n const ready = await waitForDaemonReady(allocated.rest, currentProjectName, timeoutMs)\n result.steps.daemon = ready.ready ? 'spawned' : 'timed-out'\n if (!ready.ready) {\n console.error(`neat: daemon did not become ready within ${timeoutMs}ms`)\n if (ready.stillBootstrapping.length > 0) {\n console.error(`neat: still bootstrapping: ${ready.stillBootstrapping.join(', ')}`)\n }\n if (ready.brokenProjects.length > 0) {\n console.error(`neat: broken projects: ${ready.brokenProjects.join(', ')}`)\n }\n result.exitCode = 1\n return result\n }\n if (ready.brokenProjects.length > 0) {\n console.warn(\n `neat: ${ready.brokenProjects.length} project(s) reported broken: ${ready.brokenProjects.join(', ')}`,\n )\n }\n }\n } catch (err) {\n console.error(`neat: daemon spawn failed — ${(err as Error).message}`)\n result.exitCode = 1\n return result\n } finally {\n await release()\n }\n }\n }\n\n // ── Step 5: browser open ─────────────────────────────────────────────\n // The dashboard lives on the daemon's allocated web port (§5), not a fixed\n // 6328 — a second project's daemon serves its dashboard one port over.\n const webPort = allocated?.web ?? NEAT_PORTS[2]\n const dashboardUrl = opts.dashboardUrl ?? `http://localhost:${webPort}`\n if (opts.noOpen || !process.stdout.isTTY) {\n result.steps.browser = 'skipped'\n } else {\n result.steps.browser = openBrowser(dashboardUrl)\n }\n\n // ── Step 6: summary + onboarding signpost ────────────────────────────\n // The daemon runs in the background writing to its own log; point the\n // operator at it and at the honest next step (run their own app/tests).\n const daemonRunning =\n result.steps.daemon === 'spawned' || result.steps.daemon === 'already-running'\n // Show the log path relative to the project root — the summary already\n // printed the project path up top, so `neat-out/daemon.log` reads cleanly\n // and matches what the operator sees on disk.\n const daemonLog = daemonRunning\n ? path.relative(opts.scanPath, daemonLogPath(opts.scanPath))\n : null\n printSummary(result, graph, dashboardUrl, daemonLog)\n\n return result\n}\n\nfunction printSummary(\n result: OrchestratorResult,\n graph: ReturnType<typeof getGraph>,\n dashboardUrl: string,\n daemonLog: string | null,\n): void {\n const nodes: GraphNode[] = []\n graph.forEachNode((_id, attrs) => nodes.push(attrs))\n const edges: GraphEdge[] = []\n graph.forEachEdge((_id, attrs) => edges.push(attrs))\n\n const byNode = new Map<string, number>()\n for (const n of nodes) byNode.set(n.type, (byNode.get(n.type) ?? 0) + 1)\n const byEdge = new Map<string, number>()\n for (const e of edges) byEdge.set(e.type, (byEdge.get(e.type) ?? 0) + 1)\n\n console.log('')\n console.log('=== summary ===')\n console.log(`graph: ${graph.order} nodes, ${graph.size} edges`)\n for (const [t, c] of [...byNode.entries()].sort()) console.log(` ${t}: ${c}`)\n for (const [t, c] of [...byEdge.entries()].sort()) console.log(` ${t}: ${c}`)\n console.log('')\n console.log(`dashboard: ${dashboardUrl}`)\n // Be honest about the auth posture (issue #483). The bare first-touch path\n // pins the daemon to loopback with no token (see spawnDaemonDetached), so\n // there's nothing to log in with. When the operator has set\n // NEAT_AUTH_TOKEN, the daemon enforces it and the user needs it to reach\n // the dashboard and to route OTel — so we print the real value rather than\n // fabricating one the daemon wouldn't accept.\n const token = process.env.NEAT_AUTH_TOKEN\n if (typeof token === 'string' && token.length > 0) {\n console.log(`auth token: ${token}`)\n } else {\n console.log('running locally — open the dashboard, no token needed')\n }\n\n // Onboarding signpost — the one-command flow returns here, so the last thing\n // the operator reads has to tell them the daemon is up (and where its log is)\n // and what to do next. The honest next step is to run their own app or test\n // suite: the graph fills its OBSERVED layer as their code executes, and\n // divergences surface where code and runtime disagree. Never suggest\n // synthetic traffic — the point is what their real system does.\n if (daemonLog !== null) {\n console.log('')\n console.log(`daemon running in the background (logs: ${daemonLog})`)\n console.log(\n 'next: run your app or your test suite — OBSERVED edges fill in as it executes,',\n )\n console.log(' and divergences surface where code and runtime disagree.')\n }\n}\n","// `neat connector add/list/remove/test` — the write side of the ADR-130\n// on-ramp (docs/contracts/connector-config.md §3). The daemon-read chain\n// (#730) already turns a `~/.neat/connectors.json` entry into a running poll\n// loop; this is the command a human actually touches to put an entry there.\n//\n// Everything provider-specific is dispatched through the registry table\n// (connectors/registry.ts §5) — the required-field schema this prompts for and\n// the auth round-trip `add`/`test` run both come from the entry, so no per-\n// provider branch lives here. The two security non-negotiables the contract\n// names ride through this module: validate-on-add by default (the credential\n// is proven against the provider before it's written), and env-ref-by-default /\n// `0600` / never-a-resolved-secret-on-screen (the write helpers in\n// connectors-config.ts own the file mode; this module only ever prints the\n// redacted pointer, never a resolved value).\n//\n// Handlers take their filesystem home, environment, `fetch`, prompt, and output\n// streams as injected deps so the whole surface is testable against a temp home\n// and a stubbed provider — no live account, no real `~/.neat`.\n\nimport readline from 'node:readline'\nimport {\n autoSlugConnectorId,\n describeCredential,\n isEnvRef,\n readConnectorsConfig,\n removeConnectorEntry,\n upsertConnectorEntry,\n type ConnectorEntry,\n type CredentialRef,\n} from './connectors-config.js'\nimport {\n getProviderDispatch,\n PROVIDER_DISPATCH,\n validateConnectorEntry,\n type ProviderDispatch,\n type ValidateOutcome,\n} from './connectors/registry.js'\n\n// ── deps / injection ──────────────────────────────────────────────────────\n\nexport interface ConnectorCliDeps {\n // NEAT_HOME override. Undefined uses connectors-config.ts's own env-based\n // resolution (the real CLI); tests pass a temp home.\n home?: string\n env?: NodeJS.ProcessEnv\n // Test seam for the provider auth round-trip (contract §4). Undefined → the\n // junction's real `fetch`.\n fetchImpl?: typeof fetch\n // Interactive prompt. Undefined → a readline prompt that returns '' when\n // stdin isn't a TTY, so CI never hangs waiting on input.\n prompt?: (question: string) => Promise<string>\n // Whether to prompt at all for missing fields. Undefined → `process.stdin`\n // is a TTY. Non-interactive runs require every field as a flag.\n interactive?: boolean\n out?: (line: string) => void\n err?: (line: string) => void\n}\n\ninterface ResolvedDeps {\n home: string | undefined\n env: NodeJS.ProcessEnv\n fetchImpl?: typeof fetch\n prompt: (question: string) => Promise<string>\n interactive: boolean\n out: (line: string) => void\n err: (line: string) => void\n}\n\nasync function defaultPrompt(question: string): Promise<string> {\n if (!process.stdin.isTTY) return ''\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout })\n try {\n return await new Promise<string>((resolve) => rl.question(`${question} `, resolve))\n } finally {\n rl.close()\n }\n}\n\nfunction resolveDeps(deps: ConnectorCliDeps): ResolvedDeps {\n return {\n home: deps.home,\n env: deps.env ?? process.env,\n ...(deps.fetchImpl ? { fetchImpl: deps.fetchImpl } : {}),\n prompt: deps.prompt ?? defaultPrompt,\n interactive: deps.interactive ?? Boolean(process.stdin.isTTY),\n out: deps.out ?? ((l) => console.log(l)),\n err: deps.err ?? ((l) => console.error(l)),\n }\n}\n\n// ── argument parsing ──────────────────────────────────────────────────────\n\nexport interface ConnectorArgs {\n subcommand: string\n positional: string[]\n project?: string\n // Single-field credential from --credential / --token (an env-ref or a\n // literal). Multi-field providers read their fields from `fields` instead.\n credential?: string\n id?: string\n skipValidate: boolean\n plaintext: boolean\n // Provider-specific option/credential fields, camelCased from their kebab\n // flag (`--account-id` → accountId). Object-valued flags (`--workers '{…}'`)\n // are JSON-parsed; `*Ms` flags are numbered; everything else stays a string.\n fields: Record<string, unknown>\n}\n\nfunction kebabToCamel(name: string): string {\n return name.replace(/-([a-z0-9])/g, (_, c: string) => c.toUpperCase())\n}\n\nfunction coerceFieldValue(name: string, raw: string): unknown {\n const t = raw.trim()\n if (t.startsWith('{') || t.startsWith('[')) {\n try {\n return JSON.parse(t)\n } catch {\n return raw\n }\n }\n // Only numeric-shaped option names become numbers, so string ids that happen\n // to be all-digits (rare, but possible) are never silently retyped.\n if (/Ms$/.test(name) && /^\\d+$/.test(t)) return Number(t)\n return raw\n}\n\nexport function parseConnectorArgs(\n args: string[],\n): { ok: true; value: ConnectorArgs } | { ok: false; error: string } {\n const out: ConnectorArgs = {\n subcommand: '',\n positional: [],\n skipValidate: false,\n plaintext: false,\n fields: {},\n }\n const positional: string[] = []\n for (let i = 0; i < args.length; i++) {\n const arg = args[i] as string\n if (arg === '--skip-validate') {\n out.skipValidate = true\n continue\n }\n if (arg === '--plaintext') {\n out.plaintext = true\n continue\n }\n if (arg.startsWith('--')) {\n let flag = arg\n let value: string | undefined\n const eq = arg.indexOf('=')\n if (eq >= 0) {\n flag = arg.slice(0, eq)\n value = arg.slice(eq + 1)\n } else {\n const next = args[i + 1]\n if (next === undefined || next.startsWith('--')) {\n return { ok: false, error: `${flag} requires a value` }\n }\n value = next\n i++\n }\n const name = flag.slice(2)\n if (name === 'project') {\n out.project = value\n continue\n }\n if (name === 'credential' || name === 'token') {\n out.credential = value\n continue\n }\n if (name === 'id') {\n out.id = value\n continue\n }\n const field = kebabToCamel(name)\n out.fields[field] = coerceFieldValue(field, value)\n continue\n }\n positional.push(arg)\n }\n out.subcommand = positional[0] ?? ''\n out.positional = positional.slice(1)\n return { ok: true, value: out }\n}\n\n// ── credential assembly ───────────────────────────────────────────────────\n\n// Build the credential ref from flags + prompts. A single-field provider takes\n// one ref (--credential/--token or its primary key flag); a multi-field\n// provider (Firebase carries projectId + accessToken) takes one ref per\n// required field. Values are stored verbatim: a leading `$` is an env-ref\n// pointer, anything else is a literal — the exact rule the daemon resolves by,\n// so no transformation happens here.\nasync function buildCredentialRef(\n dispatch: ProviderDispatch,\n args: ConnectorArgs,\n deps: ResolvedDeps,\n): Promise<CredentialRef> {\n const hint = 'an env-var reference like $PROVIDER_TOKEN is recommended (stored as a pointer, not the secret); a literal value is stored as-is'\n if (dispatch.requiredCredentialFields.length <= 1) {\n const key = dispatch.primaryCredentialKey\n let value = args.credential\n if (value === undefined && typeof args.fields[key] === 'string') {\n value = args.fields[key] as string\n }\n if (value === undefined && deps.interactive) {\n value = await deps.prompt(`Credential for ${dispatch.provider} (${hint}):`)\n }\n return (value ?? '').trim()\n }\n const out: Record<string, string> = {}\n for (const f of dispatch.requiredCredentialFields) {\n let value: string | undefined\n if (typeof args.fields[f] === 'string') value = args.fields[f] as string\n else if (f === dispatch.primaryCredentialKey && args.credential !== undefined) value = args.credential\n if (value === undefined && deps.interactive) {\n value = await deps.prompt(`Credential field \"${f}\" for ${dispatch.provider} (${hint}):`)\n }\n out[f] = (value ?? '').trim()\n }\n return out\n}\n\n// Whether every required credential field carries a non-empty value.\nfunction credentialComplete(dispatch: ProviderDispatch, ref: CredentialRef): string[] {\n if (typeof ref === 'string') {\n return ref.length > 0 ? [] : [dispatch.primaryCredentialKey]\n }\n return dispatch.requiredCredentialFields.filter((f) => !ref[f] || ref[f].length === 0)\n}\n\n// The plaintext (non-env-ref) fields in a credential — the ones that put a\n// secret at rest and so warrant the opt-in warning.\nfunction plaintextFields(ref: CredentialRef): string[] {\n if (typeof ref === 'string') return isEnvRef(ref) ? [] : ['credential']\n return Object.entries(ref)\n .filter(([, v]) => !isEnvRef(v))\n .map(([k]) => k)\n}\n\n// ── `add` ─────────────────────────────────────────────────────────────────\n\nasync function connectorAdd(args: ConnectorArgs, deps: ResolvedDeps): Promise<number> {\n // Provider — positional or prompt. Must be a known, built provider.\n let provider = args.positional[0]\n if (!provider && deps.interactive) {\n provider = (await deps.prompt(`Provider (${Object.keys(PROVIDER_DISPATCH).sort().join(', ')}):`)).trim()\n }\n if (!provider) {\n deps.err('neat connector add: a provider is required (e.g. `neat connector add supabase`)')\n return 2\n }\n const dispatch = getProviderDispatch(provider)\n if (!dispatch) {\n deps.err(\n `neat connector add: unknown provider \"${provider}\". known providers: ${Object.keys(PROVIDER_DISPATCH).sort().join(', ')}`,\n )\n return 2\n }\n\n // Project — optional; blank binds to whatever project the daemon bootstraps.\n let project = args.project\n if (project === undefined && deps.interactive) {\n const answer = (await deps.prompt('Project (blank = the project the daemon is bootstrapping):')).trim()\n if (answer.length > 0) project = answer\n }\n\n // Credential + non-secret options.\n const credential = await buildCredentialRef(dispatch, args, deps)\n const options: Record<string, unknown> = { ...args.fields }\n // The credential fields aren't options — strip any that arrived via a\n // generic flag so they don't double-write into `options`.\n for (const k of dispatch.requiredCredentialFields) delete options[k]\n\n // Prompt for any still-missing required option field (interactive only).\n for (const field of dispatch.requiredOptionFields) {\n if (field in options) continue\n if (!deps.interactive) continue\n const answer = (await deps.prompt(`Option \"${field}\" for ${provider}:`)).trim()\n if (answer.length > 0) options[field] = coerceFieldValue(field, answer)\n }\n\n // Structural completeness — caught before any write, even under\n // --skip-validate, so an entry that can never run isn't silently stored.\n const missingCred = credentialComplete(dispatch, credential)\n if (missingCred.length > 0) {\n deps.err(\n `neat connector add: credential is incomplete — missing ${missingCred.join(', ')}. ` +\n 'Pass it as a flag (e.g. `--token $PROVIDER_TOKEN`) or run interactively.',\n )\n return 2\n }\n const missingOpts = dispatch.requiredOptionFields.filter((f) => !(f in options))\n if (missingOpts.length > 0) {\n deps.err(\n `neat connector add: missing required option(s) for ${provider}: ${missingOpts.join(', ')}. ` +\n `Pass e.g. \\`--${missingOpts[0].replace(/([A-Z])/g, '-$1').toLowerCase()} <value>\\`.`,\n )\n return 2\n }\n\n // Assemble the entry — auto-slug the id unless one was given.\n const existing = await readConnectorsConfig(deps.home)\n const existingIds = new Set(existing.connectors.map((c) => c.id))\n const id = args.id ?? autoSlugConnectorId(provider, project, existingIds)\n const entry: ConnectorEntry = {\n id,\n provider,\n ...(project ? { project } : {}),\n credential,\n ...(Object.keys(options).length > 0 ? { options } : {}),\n }\n\n // Validate-on-add by default (contract §4) — a wrong credential fails fast\n // here rather than quietly at the first poll. An unset env-ref is its own\n // distinct outcome, never conflated with a rejected token.\n if (!args.skipValidate) {\n const outcome = await validateConnectorEntry(entry, deps.env, deps.fetchImpl)\n const code = reportPreWriteValidation(outcome, deps)\n if (code !== 0) return code\n }\n\n // Plaintext is the explicit opt-in; surface it so a secret never lands at\n // rest by accident (contract §2).\n const plaintext = plaintextFields(credential)\n if (plaintext.length > 0 && !args.plaintext) {\n deps.err(\n `neat connector add: storing a literal secret at rest for ${plaintext.join(', ')} — ` +\n 'prefer an env-var reference like `$PROVIDER_TOKEN` (pass --plaintext to silence this).',\n )\n }\n\n const { replaced } = await upsertConnectorEntry(entry, deps.home)\n const verb = replaced ? 'updated' : 'added'\n const where = project ? `project \"${project}\"` : 'the bootstrapping project'\n deps.out(`${verb} connector \"${id}\" (${provider}) for ${where}.`)\n if (args.skipValidate) {\n deps.out('skipped validation (--skip-validate) — the credential is checked at the next daemon poll.')\n }\n deps.out('Restart the project\\'s daemon (or start it) to begin polling this connector.')\n return 0\n}\n\n// Turn a pre-write validation outcome into an exit code, printing the distinct\n// message each case warrants. 0 means proceed to write.\nfunction reportPreWriteValidation(outcome: ValidateOutcome, deps: ResolvedDeps): number {\n switch (outcome.status) {\n case 'ok':\n deps.out('credential validated against the provider.')\n return 0\n case 'unset-env':\n deps.err(\n `neat connector add: ${outcome.reason}. Export the variable before adding, ` +\n 'or pass --skip-validate to add now and set it before the daemon runs.',\n )\n return 1\n case 'rejected':\n deps.err(\n `neat connector add: the provider rejected the credential — ${outcome.reason}. ` +\n 'Nothing was written. Fix the credential, or pass --skip-validate to store it anyway.',\n )\n return 1\n case 'missing-field':\n deps.err(`neat connector add: ${outcome.reason}.`)\n return 2\n case 'unknown-provider':\n deps.err(`neat connector add: ${outcome.reason}.`)\n return 2\n }\n}\n\n// ── `list` ────────────────────────────────────────────────────────────────\n\nasync function connectorList(deps: ResolvedDeps, filterProject?: string): Promise<number> {\n const config = await readConnectorsConfig(deps.home)\n let entries = config.connectors\n if (filterProject) entries = entries.filter((e) => e.project === filterProject)\n if (entries.length === 0) {\n deps.out(\n filterProject\n ? `no connectors configured for project \"${filterProject}\".`\n : 'no connectors configured. run `neat connector add <provider>` to add one.',\n )\n return 0\n }\n deps.out('id\\tprovider\\tproject\\tcredential')\n for (const e of entries) {\n const project = e.project ?? '(bootstrapping project)'\n const credential = describeCredential(e.credential, deps.env)\n .map((c) => {\n const status = c.status ? ` (${c.status})` : c.kind === 'plaintext' ? ' (plaintext)' : ''\n return c.field ? `${c.field}=${c.display}${status}` : `${c.display}${status}`\n })\n .join(', ')\n deps.out(`${e.id}\\t${e.provider}\\t${project}\\t${credential}`)\n }\n return 0\n}\n\n// ── `remove` ──────────────────────────────────────────────────────────────\n\nasync function connectorRemove(deps: ResolvedDeps, id: string | undefined): Promise<number> {\n if (!id) {\n deps.err('neat connector remove: missing <id>. run `neat connector list` to see configured ids.')\n return 2\n }\n const removed = await removeConnectorEntry(id, deps.home)\n if (!removed) {\n deps.err(`neat connector remove: no connector with id \"${id}\". run \\`neat connector list\\` to see configured ids.`)\n return 1\n }\n deps.out(`removed connector \"${id}\" (${removed.provider}).`)\n return 0\n}\n\n// ── `test` ────────────────────────────────────────────────────────────────\n\nasync function connectorTest(deps: ResolvedDeps, id: string | undefined): Promise<number> {\n if (!id) {\n deps.err('neat connector test: missing <id>. run `neat connector list` to see configured ids.')\n return 2\n }\n const config = await readConnectorsConfig(deps.home)\n const entry = config.connectors.find((c) => c.id === id)\n if (!entry) {\n deps.err(`neat connector test: no connector with id \"${id}\". run \\`neat connector list\\` to see configured ids.`)\n return 1\n }\n const outcome = await validateConnectorEntry(entry, deps.env, deps.fetchImpl)\n switch (outcome.status) {\n case 'ok':\n deps.out(`ok: \"${id}\" (${entry.provider}) authenticated against the provider.`)\n return 0\n case 'unset-env':\n deps.err(`unset: \"${id}\" (${entry.provider}) — ${outcome.reason}. Export the variable so the daemon can resolve it.`)\n return 1\n case 'rejected':\n deps.err(`rejected: \"${id}\" (${entry.provider}) — ${outcome.reason}.`)\n return 1\n case 'missing-field':\n deps.err(`incomplete: \"${id}\" (${entry.provider}) — ${outcome.reason}.`)\n return 2\n case 'unknown-provider':\n deps.err(`unknown provider: \"${id}\" — ${outcome.reason}.`)\n return 2\n }\n}\n\n// ── dispatch ──────────────────────────────────────────────────────────────\n\nexport function printConnectorUsage(write: (line: string) => void): void {\n write('usage: neat connector <add|list|remove|test> [args]')\n write(' add <provider> add a connector; validates the credential first (--skip-validate to skip)')\n write(' flags: --project <name> --credential/--token <$VAR|value> --id <id>')\n write(' --<option> <value> (provider-specific) --plaintext --skip-validate')\n write(' list list configured connectors (credentials shown redacted)')\n write(' flags: --project <name>')\n write(' remove <id> remove a connector by id')\n write(' test <id> re-run the credential validation for an existing connector')\n}\n\n/**\n * Entry point the CLI wires `neat connector …` to. `rawArgs` is argv past the\n * `connector` token. Returns a process exit code; never calls `process.exit`\n * itself so the caller (and tests) own control flow.\n */\nexport async function runConnectorCommand(\n rawArgs: string[],\n deps: ConnectorCliDeps = {},\n): Promise<number> {\n const resolved = resolveDeps(deps)\n const parsed = parseConnectorArgs(rawArgs)\n if (!parsed.ok) {\n resolved.err(`neat connector: ${parsed.error}`)\n return 2\n }\n const a = parsed.value\n switch (a.subcommand) {\n case 'add':\n return connectorAdd(a, resolved)\n case 'list':\n return connectorList(resolved, a.project)\n case 'remove':\n return connectorRemove(resolved, a.positional[0])\n case 'test':\n return connectorTest(resolved, a.positional[0])\n case '':\n resolved.err('neat connector: missing subcommand.')\n printConnectorUsage(resolved.err)\n return 2\n default:\n resolved.err(`neat connector: unknown subcommand \"${a.subcommand}\".`)\n printConnectorUsage(resolved.err)\n return 2\n }\n}\n","/**\n * Lifecycle-verb implementations for the CLI. Query verbs live in\n * `cli-client.ts` next to the REST client; lifecycle verbs (currently\n * `neat sync`) live here because they orchestrate filesystem work and\n * daemon-state probes rather than wrapping a single REST endpoint.\n */\n\nimport path from 'node:path'\nimport type { RegistryEntry } from '@neat.is/types'\nimport {\n applyInstallersOver,\n extractAndPersist,\n type ExtractAndPersistResult,\n} from './orchestrator.js'\nimport { listProjects, normalizeProjectPath } from './registry.js'\nimport { saveGraphToDisk, SCHEMA_VERSION, type PersistedGraph } from './persist.js'\nimport {\n HttpError,\n pushSnapshotToRemote,\n resolveAuthToken,\n TransportError,\n} from './cli-client.js'\n\nexport interface SyncOptions {\n // Project name from `--project <name>`. When absent, sync resolves the\n // project by matching the cwd against the registered project paths.\n project?: string\n // Push the snapshot to a remote daemon URL. When absent, sync runs against\n // the local daemon on http://localhost:8080.\n to?: string\n // Bearer token for the remote daemon. Falls back to NEAT_REMOTE_TOKEN env.\n token?: string\n // Skip writing the snapshot or notifying the daemon. Mirrors `neat <path>\n // --dry-run`.\n dryRun: boolean\n // Skip the SDK install apply step.\n noInstrument: boolean\n // Emit a structured JSON payload on stdout instead of human text.\n json: boolean\n // Override the local daemon URL. Defaults to NEAT_API_URL or\n // http://localhost:8080. Useful for tests.\n daemonUrl?: string\n // Working directory the verb resolves against when `--project` isn't\n // passed. Defaults to process.cwd(); tests override.\n cwd?: string\n}\n\nexport interface SyncResult {\n exitCode: number\n // Stable shape across human / json output paths. cli.ts decides which\n // formatter to invoke based on `--json`.\n project: string\n scanPath: string\n nodesAdded: number\n edgesAdded: number\n snapshotPath: string | null\n // Tracks which branch the run took for `--json` consumers.\n mode: 'dry-run' | 'local' | 'remote'\n daemon: 'reloaded' | 'down' | 'remote-ok' | 'skipped'\n apply: {\n instrumented: number\n alreadyInstrumented: number\n libOnly: number\n skipped: boolean\n }\n // Soft warning lines surfaced to stderr in the human path. Empty when the\n // run was fully clean.\n warnings: string[]\n}\n\nasync function resolveProjectEntry(opts: SyncOptions): Promise<RegistryEntry | null> {\n const entries = await listProjects()\n if (opts.project) {\n const match = entries.find((e) => e.name === opts.project)\n return match ?? null\n }\n const cwd = opts.cwd ?? process.cwd()\n const resolvedCwd = await normalizeProjectPath(cwd)\n // Match by path: the cwd must be inside (or equal to) the registered path.\n for (const entry of entries) {\n if (\n resolvedCwd === entry.path ||\n resolvedCwd.startsWith(`${entry.path}${path.sep}`)\n ) {\n return entry\n }\n }\n return null\n}\n\nasync function checkDaemonHealth(baseUrl: string): Promise<boolean> {\n try {\n const res = await fetch(`${baseUrl.replace(/\\/$/, '')}/health`, {\n signal: AbortSignal.timeout(1500),\n })\n return res.ok\n } catch {\n return false\n }\n}\n\nfunction snapshotForGraph(persisted: ExtractAndPersistResult): PersistedGraph {\n return {\n // Stamp the live schema version the daemon validates against on the\n // receiving `/snapshot` merge. Tracking the constant keeps the push\n // aligned with the current snapshot shape across schema migrations.\n schemaVersion: SCHEMA_VERSION,\n exportedAt: new Date().toISOString(),\n graph: persisted.graph.export(),\n }\n}\n\nfunction emitResult(result: SyncResult, json: boolean): void {\n if (json) {\n process.stdout.write(JSON.stringify(result, null, 2) + '\\n')\n return\n }\n const verb =\n result.mode === 'dry-run'\n ? 'dry-run'\n : result.mode === 'remote'\n ? 'pushed'\n : 'synced'\n console.log(\n `${verb}: ${result.project} — ${result.nodesAdded} node(s) and ${result.edgesAdded} edge(s) added` +\n (result.snapshotPath ? `; snapshot at ${result.snapshotPath}` : ''),\n )\n if (!result.apply.skipped) {\n const { instrumented, alreadyInstrumented, libOnly } = result.apply\n console.log(\n `instrumented ${instrumented}, already ${alreadyInstrumented}, lib-only ${libOnly}`,\n )\n } else {\n console.log('skipped instrumentation (--no-instrument)')\n }\n for (const warn of result.warnings) console.error(warn)\n}\n\nexport async function runSync(opts: SyncOptions): Promise<SyncResult> {\n const entry = await resolveProjectEntry(opts)\n if (!entry) {\n const target = opts.project ?? opts.cwd ?? process.cwd()\n console.error(\n `neat sync: no registered project ${\n opts.project ? `named \"${opts.project}\"` : `covers ${target}`\n }. Run \\`neat <path>\\` or \\`neat init <path>\\` first.`,\n )\n return {\n exitCode: 1,\n project: opts.project ?? '',\n scanPath: target,\n nodesAdded: 0,\n edgesAdded: 0,\n snapshotPath: null,\n mode: opts.to ? 'remote' : 'local',\n daemon: 'skipped',\n apply: { instrumented: 0, alreadyInstrumented: 0, libOnly: 0, skipped: true },\n warnings: [],\n }\n }\n\n // ── Step 1 + 2: discovery + extraction (no snapshot in dry-run) ─────\n const persisted = await extractAndPersist({\n scanPath: entry.path,\n project: entry.name,\n projectExplicit: true,\n dryRun: true,\n })\n\n let snapshotPath: string | null = null\n if (!opts.dryRun) {\n const target = persisted.snapshotPath\n await saveGraphToDisk(persisted.graph, target)\n snapshotPath = target\n }\n\n // ── Step 3: SDK install apply (default yes; --dry-run + --no-instrument skip)\n const skipApply = opts.dryRun || opts.noInstrument\n const applyTally = skipApply\n ? { instrumented: 0, alreadyInstrumented: 0, libOnly: 0, browserBundle: 0, reactNative: 0 }\n : await applyInstallersOver(persisted.services, entry.name)\n\n // ── Step 4: daemon notify ────────────────────────────────────────────\n const warnings: string[] = []\n let daemonState: SyncResult['daemon'] = 'skipped'\n let exitCode = 0\n const mode: SyncResult['mode'] = opts.dryRun ? 'dry-run' : opts.to ? 'remote' : 'local'\n\n if (!opts.dryRun) {\n const snapshot = snapshotForGraph(persisted)\n if (opts.to) {\n const token = opts.token ?? process.env.NEAT_REMOTE_TOKEN\n try {\n await pushSnapshotToRemote({\n baseUrl: opts.to,\n token,\n project: entry.name,\n snapshot,\n })\n daemonState = 'remote-ok'\n } catch (err) {\n if (err instanceof HttpError) {\n console.error(`neat sync: ${err.message}`)\n exitCode = 1\n } else if (err instanceof TransportError) {\n console.error(`neat sync: ${err.message}`)\n exitCode = 3\n } else {\n console.error(`neat sync: ${(err as Error).message}`)\n exitCode = 1\n }\n daemonState = 'skipped'\n }\n } else {\n const daemonUrl =\n opts.daemonUrl ?? process.env.NEAT_API_URL ?? 'http://localhost:8080'\n const healthy = await checkDaemonHealth(daemonUrl)\n if (healthy) {\n try {\n await pushSnapshotToRemote({\n baseUrl: daemonUrl,\n token: resolveAuthToken(),\n project: entry.name,\n snapshot,\n })\n daemonState = 'reloaded'\n } catch (err) {\n warnings.push(\n `neat sync: daemon merge failed — ${(err as Error).message}. Snapshot is on disk at ${snapshotPath}.`,\n )\n daemonState = 'down'\n exitCode = 2\n }\n } else {\n warnings.push(\n 'neat sync: daemon not running; snapshot updated, run `neatd start` to serve it',\n )\n daemonState = 'down'\n exitCode = 2\n }\n }\n }\n\n const result: SyncResult = {\n exitCode,\n project: entry.name,\n scanPath: entry.path,\n nodesAdded: persisted.nodesAdded,\n edgesAdded: persisted.edgesAdded,\n snapshotPath,\n mode,\n daemon: daemonState,\n apply: { ...applyTally, skipped: skipApply },\n warnings,\n }\n\n emitResult(result, opts.json)\n return result\n}\n","// REST helper + CLI verb implementations for `neat <verb>` (ADR-050).\n//\n// The HttpClient and its createHttpClient factory are the \"shared REST helper\n// module\" the contract calls for — one endpoint surface, two consumers\n// (`packages/mcp/src/client.ts` re-exports from here, the CLI dispatcher\n// imports it directly).\n//\n// Verb handlers live alongside the client because they're tightly coupled:\n// each verb maps 1:1 to an MCP tool from ADR-039, but produces the structured\n// `{ summary, block, confidence, provenance }` shape (ADR-050 #3) in pure\n// data form. cli.ts formats that shape into either human-readable text or\n// `--json` output.\n\nimport type {\n BlastRadiusAffectedNode,\n BlastRadiusResult,\n Divergence,\n DivergenceResult,\n DivergenceType,\n ErrorEvent,\n GraphEdge,\n GraphNode,\n HypotheticalAction,\n ObservedDependenciesResult,\n PolicyViolation,\n RootCauseResult,\n TransitiveDependenciesResult,\n} from '@neat.is/types'\nimport { Provenance } from '@neat.is/types'\n\n// ──────────────────────────────────────────────────────────────────────────\n// REST client\n// ──────────────────────────────────────────────────────────────────────────\n\nexport interface HttpClient {\n get<T>(path: string): Promise<T>\n post?<T>(path: string, body: unknown): Promise<T>\n}\n\nexport class HttpError extends Error {\n constructor(\n public readonly status: number,\n message: string,\n public readonly responseBody: string = '',\n ) {\n super(message)\n this.name = 'HttpError'\n }\n}\n\n// Network-level failures (ECONNREFUSED, ETIMEDOUT, DNS) — distinct from\n// HttpError so the CLI can map them to exit code 3 (daemon-down) without\n// parsing error strings.\nexport class TransportError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'TransportError'\n }\n}\n\n// Single-source the bearer for every first-party read (ADR-073 §3). The CLI\n// query verbs, `neat sync`, the MCP server, and the snapshot push all read the\n// token from here so a new read site can't quietly skip auth. Returns\n// undefined when the env var is unset or empty — a loopback dev daemon stays\n// reachable without a token.\nexport function resolveAuthToken(env: NodeJS.ProcessEnv = process.env): string | undefined {\n const t = env.NEAT_AUTH_TOKEN\n return t && t.length > 0 ? t : undefined\n}\n\nexport function createHttpClient(baseUrl: string, bearerToken?: string): HttpClient {\n const root = baseUrl.replace(/\\/$/, '')\n const authHeader: Record<string, string> = bearerToken && bearerToken.length > 0\n ? { authorization: `Bearer ${bearerToken}` }\n : {}\n return {\n async get<T>(path: string): Promise<T> {\n let res: Response\n try {\n res = await fetch(`${root}${path}`, {\n headers: { ...authHeader },\n })\n } catch (err) {\n throw new TransportError(\n `cannot reach neat-core at ${root}: ${(err as Error).message}`,\n )\n }\n if (!res.ok) {\n const body = await res.text().catch(() => '')\n throw new HttpError(\n res.status,\n `${res.status} ${res.statusText} on GET ${path}: ${body}`,\n body,\n )\n }\n return (await res.json()) as T\n },\n async post<T>(path: string, body: unknown): Promise<T> {\n let res: Response\n try {\n res = await fetch(`${root}${path}`, {\n method: 'POST',\n headers: { 'content-type': 'application/json', ...authHeader },\n body: JSON.stringify(body),\n })\n } catch (err) {\n throw new TransportError(\n `cannot reach neat-core at ${root}: ${(err as Error).message}`,\n )\n }\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new HttpError(\n res.status,\n `${res.status} ${res.statusText} on POST ${path}: ${text}`,\n text,\n )\n }\n return (await res.json()) as T\n },\n }\n}\n\n// Project routing per ADR-050 #2: `--project <name>` (handled in cli.ts) →\n// `NEAT_PROJECT` env → `default`. The default routes hit the legacy\n// unprefixed URLs which the core resolves to project=`default`.\nfunction projectPath(project: string | undefined, suffix: string): string {\n if (!project) return suffix\n return `/projects/${encodeURIComponent(project)}${suffix}`\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Verb result shape (ADR-050 #3)\n// ──────────────────────────────────────────────────────────────────────────\n\nexport interface VerbResult {\n // NL paragraph. What was found and why it matters.\n summary: string\n // Structured payload — usually a bulleted list. Empty when the summary\n // already conveys everything.\n block?: string\n // Per-result confidence in [0, 1]. Undefined → footer reads \"n/a\".\n confidence?: number\n // Per-result provenance. String, array (mixed paths), or undefined.\n provenance?: string | string[]\n}\n\n// Common shape the nine verbs produce. cli.ts renders this to text or JSON.\n\n// ──────────────────────────────────────────────────────────────────────────\n// Verbs\n// ──────────────────────────────────────────────────────────────────────────\n\nexport interface RootCauseInput {\n errorNode: string\n errorId?: string\n project?: string\n}\n\nexport async function runRootCause(\n client: HttpClient,\n input: RootCauseInput,\n): Promise<VerbResult> {\n const qs = input.errorId ? `?errorId=${encodeURIComponent(input.errorId)}` : ''\n const path = projectPath(\n input.project,\n `/graph/root-cause/${encodeURIComponent(input.errorNode)}${qs}`,\n )\n try {\n const result = await client.get<RootCauseResult>(path)\n const arrowPath = result.traversalPath.join(' ← ')\n const provenances = result.edgeProvenances.length\n ? result.edgeProvenances.join(', ')\n : '(direct, no edges traversed)'\n const summary =\n `Root cause for ${input.errorNode} is ${result.rootCauseNode}. ` +\n result.rootCauseReason +\n (result.fixRecommendation ? ` Recommended fix: ${result.fixRecommendation}.` : '')\n const blockLines = [\n `Traversal path: ${arrowPath}`,\n `Edge provenances: ${provenances}`,\n ]\n if (result.fixRecommendation) blockLines.push(`Recommended fix: ${result.fixRecommendation}`)\n return {\n summary,\n block: blockLines.join('\\n'),\n confidence: result.confidence,\n provenance: result.edgeProvenances.length ? result.edgeProvenances : undefined,\n }\n } catch (err) {\n if (err instanceof HttpError && err.status === 404) {\n return {\n summary: `No root cause found for ${input.errorNode}. The node may be healthy, or it may not exist in the graph.`,\n }\n }\n throw err\n }\n}\n\nexport interface BlastRadiusInput {\n nodeId: string\n depth?: number\n project?: string\n}\n\nexport async function runBlastRadius(\n client: HttpClient,\n input: BlastRadiusInput,\n): Promise<VerbResult> {\n const qs = input.depth !== undefined ? `?depth=${input.depth}` : ''\n const path = projectPath(\n input.project,\n `/graph/blast-radius/${encodeURIComponent(input.nodeId)}${qs}`,\n )\n try {\n const result = await client.get<BlastRadiusResult>(path)\n if (result.totalAffected === 0) {\n return {\n summary: `${result.origin} has no dependents. Nothing else would break if it failed.`,\n }\n }\n const sorted = [...result.affectedNodes].sort(\n (a, b) => a.distance - b.distance || a.nodeId.localeCompare(b.nodeId),\n )\n const blockLines = sorted.map(formatBlastEntry)\n const minConfidence = sorted.reduce(\n (m, n) => Math.min(m, n.confidence),\n Number.POSITIVE_INFINITY,\n )\n const provenances = [...new Set(sorted.map((n) => n.edgeProvenance))]\n return {\n summary: `Blast radius for ${result.origin}: ${result.totalAffected} dependent node${result.totalAffected === 1 ? '' : 's'} would break if it changed.`,\n block: blockLines.join('\\n'),\n confidence: Number.isFinite(minConfidence) ? minConfidence : undefined,\n provenance: provenances.length ? provenances : undefined,\n }\n } catch (err) {\n if (err instanceof HttpError && err.status === 404) {\n return { summary: `Node ${input.nodeId} not found in the graph.` }\n }\n throw err\n }\n}\n\nfunction formatBlastEntry(n: BlastRadiusAffectedNode): string {\n const tag = n.edgeProvenance === Provenance.STALE ? ' [STALE — last seen too long ago]' : ''\n return ` • ${n.nodeId} (distance ${n.distance}, ${n.edgeProvenance})${tag}`\n}\n\nexport interface DependenciesInput {\n nodeId: string\n depth?: number\n project?: string\n}\n\nexport async function runDependencies(\n client: HttpClient,\n input: DependenciesInput,\n): Promise<VerbResult> {\n const depth = input.depth ?? 3\n const path = projectPath(\n input.project,\n `/graph/dependencies/${encodeURIComponent(input.nodeId)}?depth=${depth}`,\n )\n try {\n const result = await client.get<TransitiveDependenciesResult>(path)\n if (result.total === 0) {\n return {\n summary:\n depth === 1\n ? `${input.nodeId} has no direct dependencies in the graph.`\n : `${input.nodeId} has no dependencies (BFS to depth ${depth}).`,\n }\n }\n const byDistance = new Map<number, typeof result.dependencies>()\n for (const dep of result.dependencies) {\n const ring = byDistance.get(dep.distance) ?? []\n ring.push(dep)\n byDistance.set(dep.distance, ring)\n }\n const blockLines: string[] = []\n for (const distance of [...byDistance.keys()].sort((a, b) => a - b)) {\n const label = distance === 1 ? 'Direct (distance 1)' : `Distance ${distance}`\n blockLines.push(`${label}:`)\n for (const dep of byDistance.get(distance)!) {\n blockLines.push(` • ${dep.nodeId} — ${dep.edgeType} (${dep.provenance})`)\n }\n }\n const provenances = [...new Set(result.dependencies.map((d) => d.provenance))]\n const directCount = byDistance.get(1)?.length ?? 0\n const summary =\n depth === 1\n ? `${input.nodeId} has ${directCount} direct dependenc${directCount === 1 ? 'y' : 'ies'}.`\n : `${input.nodeId} has ${result.total} dependenc${result.total === 1 ? 'y' : 'ies'} reachable to depth ${depth} (${directCount} direct).`\n return { summary, block: blockLines.join('\\n'), provenance: provenances }\n } catch (err) {\n if (err instanceof HttpError && err.status === 404) {\n return { summary: `Node ${input.nodeId} not found in the graph.` }\n }\n throw err\n }\n}\n\n// Render one OBSERVED dependency. The edge is file-grained, so when its source\n// isn't the node we asked about (a service's owned file made the call) name the\n// originating file — that's the file-first answer, not a service rollup.\nfunction observedDepLine(nodeId: string, e: GraphEdge): string {\n const via = e.source !== nodeId ? ` (via ${e.source})` : ''\n return ` • ${e.target} — ${e.type}${via}${edgeMeta(e)}`\n}\n\nexport async function runObservedDependencies(\n client: HttpClient,\n input: DependenciesInput,\n): Promise<VerbResult> {\n try {\n const result = await client.get<ObservedDependenciesResult>(\n projectPath(\n input.project,\n `/graph/observed-dependencies/${encodeURIComponent(input.nodeId)}`,\n ),\n )\n if (result.dependencies.length === 0) {\n // A pure receiver — hit at runtime but calling nothing downstream — is\n // fully observed, so don't imply OTel is down. That note is honest only\n // when nothing has been observed and static deps exist.\n if (result.observed) {\n return {\n summary:\n `${input.nodeId} makes no outbound runtime calls, but OTel has observed it ` +\n `receiving traffic on ${result.inboundObservedCount} inbound call ` +\n `path${result.inboundObservedCount === 1 ? '' : 's'} — it's a pure receiver.`,\n provenance: Provenance.OBSERVED,\n }\n }\n const note = result.hasExtractedOutbound\n ? ' Static (EXTRACTED) dependencies exist but no runtime traffic has been seen — is OTel running?'\n : ''\n return { summary: `No OBSERVED dependencies for ${input.nodeId}.${note}` }\n }\n const blockLines = result.dependencies.map((e) => observedDepLine(input.nodeId, e))\n return {\n summary: `${input.nodeId} has ${result.dependencies.length} runtime dependenc${result.dependencies.length === 1 ? 'y' : 'ies'} confirmed by OTel.`,\n block: blockLines.join('\\n'),\n provenance: Provenance.OBSERVED,\n }\n } catch (err) {\n if (err instanceof HttpError && err.status === 404) {\n return { summary: `Node ${input.nodeId} not found in the graph.` }\n }\n throw err\n }\n}\n\nfunction edgeMeta(e: GraphEdge): string {\n const bits: string[] = []\n if (e.signal) {\n bits.push(`spans=${e.signal.spanCount}`)\n if (e.signal.errorCount > 0) bits.push(`errors=${e.signal.errorCount}`)\n if (e.signal.lastObservedAgeMs !== undefined) {\n bits.push(`age=${formatDuration(e.signal.lastObservedAgeMs)}`)\n }\n } else if (e.callCount !== undefined) {\n bits.push(`callCount=${e.callCount}`)\n }\n if (e.lastObserved) bits.push(`lastObserved=${e.lastObserved}`)\n if (e.confidence !== undefined) bits.push(`confidence=${e.confidence}`)\n return bits.length ? ` [${bits.join(', ')}]` : ''\n}\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${Math.round(ms)}ms`\n const s = Math.round(ms / 1000)\n if (s < 60) return `${s}s`\n const m = Math.round(s / 60)\n if (m < 60) return `${m}m`\n const h = Math.round(m / 60)\n if (h < 48) return `${h}h`\n return `${Math.round(h / 24)}d`\n}\n\nexport interface IncidentsInput {\n nodeId?: string\n limit?: number\n project?: string\n}\n\n// `neat incidents` shape: with a node id, returns that node's incidents.\n// Without one, returns the global recent log.\nexport async function runIncidents(\n client: HttpClient,\n input: IncidentsInput,\n): Promise<VerbResult> {\n const path = input.nodeId\n ? projectPath(input.project, `/incidents/${encodeURIComponent(input.nodeId)}`)\n : projectPath(input.project, '/incidents')\n try {\n const body = await client.get<{ count: number; total: number; events: ErrorEvent[] }>(path)\n const events = body.events\n if (events.length === 0) {\n return {\n summary: input.nodeId\n ? `No incidents recorded against ${input.nodeId}.`\n : 'No incidents recorded.',\n }\n }\n const ordered = [...events].reverse().slice(0, input.limit ?? 20)\n const blockLines: string[] = []\n for (const ev of ordered) {\n blockLines.push(` ${ev.timestamp} — ${ev.service}: ${ev.errorMessage}`)\n blockLines.push(` trace=${ev.traceId} span=${ev.spanId}`)\n }\n const target = input.nodeId ?? 'the project'\n return {\n summary: `${target} has ${body.total} recorded incident${body.total === 1 ? '' : 's'}; showing the ${ordered.length} most recent.`,\n block: blockLines.join('\\n'),\n provenance: Provenance.OBSERVED,\n }\n } catch (err) {\n if (err instanceof HttpError && err.status === 404) {\n return { summary: `Node ${input.nodeId ?? ''} not found in the graph.` }\n }\n throw err\n }\n}\n\nexport interface SearchInput {\n query: string\n project?: string\n}\n\ninterface SearchResponse {\n query: string\n provider?: 'ollama' | 'transformers' | 'substring'\n matches: (GraphNode & { score?: number })[]\n}\n\nexport async function runSearch(\n client: HttpClient,\n input: SearchInput,\n): Promise<VerbResult> {\n const result = await client.get<SearchResponse>(\n projectPath(input.project, `/search?q=${encodeURIComponent(input.query)}`),\n )\n if (result.matches.length === 0) {\n return { summary: `No matches for \"${input.query}\".` }\n }\n const provider = result.provider ?? 'substring'\n const blockLines: string[] = []\n let topScore: number | undefined\n for (const n of result.matches) {\n const score = provider !== 'substring' && typeof n.score === 'number' ? n.score : undefined\n const scoreBit = score !== undefined ? ` [score=${score.toFixed(2)}]` : ''\n if (score !== undefined && (topScore === undefined || score > topScore)) topScore = score\n blockLines.push(\n ` • ${n.id} (${n.type}) — ${(n as { name?: string }).name ?? n.id}${scoreBit}`,\n )\n }\n return {\n summary: `Found ${result.matches.length} match${result.matches.length === 1 ? '' : 'es'} for \"${input.query}\" via ${provider} provider.`,\n block: blockLines.join('\\n'),\n confidence: topScore,\n }\n}\n\nexport interface DiffInput {\n againstSnapshot: string\n project?: string\n}\n\ninterface GraphDiffResponse {\n base: { exportedAt?: string }\n current: { exportedAt: string }\n added: { nodes: GraphNode[]; edges: GraphEdge[] }\n removed: { nodes: GraphNode[]; edges: GraphEdge[] }\n changed: {\n nodes: { id: string; before: GraphNode; after: GraphNode }[]\n edges: { id: string; before: GraphEdge; after: GraphEdge }[]\n }\n}\n\nexport async function runDiff(client: HttpClient, input: DiffInput): Promise<VerbResult> {\n const result = await client.get<GraphDiffResponse>(\n projectPath(\n input.project,\n `/graph/diff?against=${encodeURIComponent(input.againstSnapshot)}`,\n ),\n )\n const total =\n result.added.nodes.length +\n result.added.edges.length +\n result.removed.nodes.length +\n result.removed.edges.length +\n result.changed.nodes.length +\n result.changed.edges.length\n const baseLabel = result.base.exportedAt ?? 'unknown'\n if (total === 0) {\n return {\n summary: `No differences between the current graph and ${input.againstSnapshot} (base exportedAt=${baseLabel}).`,\n }\n }\n const blockLines: string[] = [\n ` base exportedAt: ${baseLabel}`,\n ` current exportedAt: ${result.current.exportedAt}`,\n '',\n ]\n if (result.added.nodes.length || result.added.edges.length) {\n blockLines.push('Added:')\n for (const n of result.added.nodes) blockLines.push(` + node ${n.id} (${n.type})`)\n for (const e of result.added.edges)\n blockLines.push(` + edge ${e.id} — ${e.source} -> ${e.target} (${e.type}, ${e.provenance})`)\n blockLines.push('')\n }\n if (result.removed.nodes.length || result.removed.edges.length) {\n blockLines.push('Removed:')\n for (const n of result.removed.nodes) blockLines.push(` - node ${n.id} (${n.type})`)\n for (const e of result.removed.edges)\n blockLines.push(` - edge ${e.id} — ${e.source} -> ${e.target} (${e.type}, ${e.provenance})`)\n blockLines.push('')\n }\n if (result.changed.nodes.length || result.changed.edges.length) {\n blockLines.push('Changed:')\n for (const c of result.changed.nodes) {\n blockLines.push(` ~ node ${c.id} — ${summariseAttrDiff(c.before, c.after)}`)\n }\n for (const c of result.changed.edges) {\n const provBit =\n c.before.provenance !== c.after.provenance\n ? `provenance ${c.before.provenance} → ${c.after.provenance}`\n : summariseAttrDiff(c.before, c.after)\n blockLines.push(` ~ edge ${c.id} — ${provBit}`)\n }\n }\n return {\n summary: `Diff against ${input.againstSnapshot}: ${total} change${total === 1 ? '' : 's'} between the snapshot and the live graph.`,\n block: blockLines.join('\\n').trimEnd(),\n }\n}\n\nfunction summariseAttrDiff(\n before: Record<string, unknown>,\n after: Record<string, unknown>,\n): string {\n const keys = new Set([...Object.keys(before), ...Object.keys(after)])\n const changed: string[] = []\n for (const k of keys) {\n if (JSON.stringify(before[k]) !== JSON.stringify(after[k])) changed.push(k)\n }\n return changed.length === 0 ? 'attributes differ' : `fields changed: ${changed.sort().join(', ')}`\n}\n\nexport interface StaleEdgesInput {\n limit?: number\n edgeType?: string\n project?: string\n}\n\ninterface StaleEventResponse {\n edgeId: string\n source: string\n target: string\n edgeType: string\n thresholdMs: number\n ageMs: number\n lastObserved: string\n transitionedAt: string\n}\n\nexport async function runStaleEdges(\n client: HttpClient,\n input: StaleEdgesInput,\n): Promise<VerbResult> {\n const params = new URLSearchParams()\n if (input.limit !== undefined) params.set('limit', String(input.limit))\n if (input.edgeType) params.set('edgeType', input.edgeType)\n const qs = params.size > 0 ? `?${params.toString()}` : ''\n const body = await client.get<{ count: number; total: number; events: StaleEventResponse[] }>(\n projectPath(input.project, `/stale-events${qs}`),\n )\n const events = body.events\n if (events.length === 0) {\n return {\n summary: input.edgeType\n ? `No stale ${input.edgeType} edges recorded.`\n : 'No stale-edge transitions recorded yet.',\n }\n }\n const blockLines = events.map(\n (e) =>\n ` ${e.transitionedAt} — ${e.source} -[${e.edgeType}]-> ${e.target}` +\n ` (last seen ${e.lastObserved}, threshold ${formatDuration(e.thresholdMs)})`,\n )\n return {\n summary: `${events.length} stale-edge transition${events.length === 1 ? '' : 's'} recorded${input.edgeType ? ` for ${input.edgeType}` : ''}.`,\n block: blockLines.join('\\n'),\n provenance: Provenance.STALE,\n }\n}\n\nexport interface PoliciesInput {\n nodeId?: string\n policyId?: string\n hypotheticalAction?: HypotheticalAction\n project?: string\n}\n\ninterface PoliciesCheckResponse {\n allowed: boolean\n hypotheticalAction?: HypotheticalAction\n violations: PolicyViolation[]\n}\n\nexport async function runPolicies(\n client: HttpClient,\n input: PoliciesInput,\n): Promise<VerbResult> {\n let violations: PolicyViolation[]\n let allowed = true\n let hypothetical: HypotheticalAction | undefined\n\n if (input.hypotheticalAction) {\n if (typeof client.post !== 'function') {\n throw new Error('HttpClient does not support POST — required for policies dry-run')\n }\n const body = await client.post<PoliciesCheckResponse>(\n projectPath(input.project, '/policies/check'),\n { hypotheticalAction: input.hypotheticalAction },\n )\n violations = body.violations\n allowed = body.allowed\n hypothetical = body.hypotheticalAction\n } else {\n const params = new URLSearchParams()\n if (input.policyId) params.set('policyId', input.policyId)\n const qs = params.size > 0 ? `?${params.toString()}` : ''\n const body = await client.get<{ violations: PolicyViolation[] }>(\n projectPath(input.project, `/policies/violations${qs}`),\n )\n violations = body.violations\n allowed = violations.every((v) => v.onViolation !== 'block')\n }\n\n // Optional --node filter is applied here against the returned set; the\n // server-side endpoint doesn't take a node-id query yet.\n if (input.nodeId) {\n violations = violations.filter(\n (v) => v.subject.nodeId === input.nodeId || v.subject.path?.includes(input.nodeId!),\n )\n }\n\n if (violations.length === 0) {\n return {\n summary: hypothetical\n ? `No violations would result from the hypothetical action (${hypothetical.kind}).`\n : 'No policy violations recorded.',\n }\n }\n\n const blockCount = violations.filter((v) => v.onViolation === 'block').length\n const summaryParts: string[] = []\n if (hypothetical) {\n summaryParts.push(\n `Hypothetical ${hypothetical.kind} would surface ${violations.length} violation${violations.length === 1 ? '' : 's'}`,\n )\n } else {\n summaryParts.push(\n `${violations.length} policy violation${violations.length === 1 ? '' : 's'} currently recorded`,\n )\n }\n if (blockCount > 0) summaryParts.push(`${blockCount} of which block`)\n if (!allowed && hypothetical) summaryParts.push('action denied')\n const summary = summaryParts.join('; ') + '.'\n\n const blockLines = violations.map((v) => {\n const subject = v.subject.nodeId ?? v.subject.edgeId ?? v.subject.path?.[0] ?? '(global)'\n return ` • [${v.severity}/${v.onViolation}] ${v.policyName}: ${v.message} — ${subject}`\n })\n const severities = [...new Set(violations.map((v) => v.severity))]\n return {\n summary,\n block: blockLines.join('\\n'),\n confidence: hypothetical ? 0.7 : 1,\n provenance: severities.join(' '),\n }\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// divergences (ADR-060) — the tenth verb. Amends ADR-050's nine-verb\n// allowlist; the verb mirrors the get_divergences MCP tool.\n// ──────────────────────────────────────────────────────────────────────────\n\nexport interface DivergencesInput {\n type?: ReadonlyArray<DivergenceType>\n minConfidence?: number\n node?: string\n project?: string\n}\n\nfunction formatDivergenceLine(d: Divergence): string {\n switch (d.type) {\n case 'missing-observed':\n case 'missing-extracted':\n return ` • [${d.type}] ${d.source} → ${d.target} (${d.edgeType}) — confidence ${d.confidence.toFixed(2)}`\n case 'version-mismatch':\n return ` • [${d.type}] ${d.source} → ${d.target} — declared ${d.extractedVersion}, observed engine ${d.observedVersion} (${d.compatibility})`\n case 'host-mismatch':\n return ` • [${d.type}] ${d.source} → ${d.target} — declared host ${d.extractedHost}, observed host ${d.observedHost}`\n case 'compat-violation':\n return ` • [${d.type}] ${d.source} → ${d.target} — ${d.rule.kind}${d.rule.package ? ` (${d.rule.package})` : ''}`\n }\n}\n\nexport async function runDivergences(\n client: HttpClient,\n input: DivergencesInput,\n): Promise<VerbResult> {\n const params = new URLSearchParams()\n if (input.type && input.type.length > 0) params.set('type', input.type.join(','))\n if (input.minConfidence !== undefined) {\n params.set('minConfidence', String(input.minConfidence))\n }\n if (input.node) params.set('node', input.node)\n const qs = params.size > 0 ? `?${params.toString()}` : ''\n const result = await client.get<DivergenceResult>(\n projectPath(input.project, `/graph/divergences${qs}`),\n )\n if (result.totalAffected === 0) {\n return {\n summary:\n 'No divergences found between the declared (EXTRACTED) and observed (OBSERVED) views of the graph.',\n }\n }\n const headline = result.divergences[0]!\n const summary =\n `Found ${result.totalAffected} divergence${result.totalAffected === 1 ? '' : 's'} between code and production. ` +\n `Highest-confidence: ${headline.type} on ${headline.source} → ${headline.target}. ${headline.reason}`\n const blockLines: string[] = []\n for (const d of result.divergences) {\n blockLines.push(formatDivergenceLine(d))\n blockLines.push(` reason: ${d.reason}`)\n blockLines.push(` recommendation: ${d.recommendation}`)\n }\n const maxConfidence = result.divergences.reduce(\n (m, d) => Math.max(m, d.confidence),\n 0,\n )\n return {\n summary,\n block: blockLines.join('\\n'),\n confidence: maxConfidence,\n provenance: 'composite (EXTRACTED + OBSERVED)',\n }\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Output formatting (ADR-050 #3)\n// ──────────────────────────────────────────────────────────────────────────\n\nfunction formatFooter(\n confidence: number | undefined,\n provenance: string | string[] | undefined,\n): string {\n const c = confidence === undefined ? 'n/a' : confidence.toFixed(2)\n const p =\n provenance === undefined\n ? 'n/a'\n : Array.isArray(provenance)\n ? [...new Set(provenance)].join(', ')\n : provenance\n return `confidence: ${c} · provenance: ${p}`\n}\n\n// Default human output (NL summary + table-shaped block + footer). Mirrors\n// the three-part MCP response from ADR-039 in plain text.\nexport function formatHuman(result: VerbResult): string {\n const sections: string[] = [result.summary.trim()]\n if (result.block && result.block.trim().length > 0) sections.push(result.block.trimEnd())\n sections.push(formatFooter(result.confidence, result.provenance))\n return sections.join('\\n\\n')\n}\n\n// `--json` output. Same three sections as named fields per ADR-050 #3.\nexport function formatJson(result: VerbResult): string {\n return JSON.stringify(\n {\n summary: result.summary,\n block: result.block ?? '',\n confidence: result.confidence ?? null,\n provenance: result.provenance ?? null,\n },\n null,\n 2,\n )\n}\n\n// Exit-code mapping for thrown errors (ADR-050 #4):\n// 0 — success (handled at the call site, never via throw)\n// 1 — server error (HttpError)\n// 2 — misuse (handled in cli.ts before any network call)\n// 3 — daemon unreachable (TransportError)\nexport function exitCodeForError(err: unknown): number {\n if (err instanceof TransportError) return 3\n if (err instanceof HttpError) return 1\n return 1\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Snapshot push (ADR-074 §1)\n//\n// `neat sync` (local + --to <url>) feeds the freshly extracted snapshot into\n// either the local daemon or a remote one. The endpoint is dual-mounted via\n// registerRoutes — default project lands at /snapshot, named projects at\n// /projects/:project/snapshot. The helper goes through the shared\n// HttpClient so the verb stays on the same network path as every query verb.\n// ──────────────────────────────────────────────────────────────────────────\n\nexport interface PushSnapshotInput {\n baseUrl: string\n token: string | undefined\n project: string\n snapshot: unknown\n}\n\nexport interface PushSnapshotResult {\n project: string\n nodesAdded: number\n edgesAdded: number\n nodeCount: number\n edgeCount: number\n}\n\nexport function createSnapshotPushClient(\n baseUrl: string,\n token: string | undefined,\n): HttpClient {\n return createHttpClient(baseUrl, token && token.length > 0 ? token : undefined)\n}\n\nexport async function pushSnapshotToRemote(\n input: PushSnapshotInput,\n): Promise<PushSnapshotResult> {\n const client = createSnapshotPushClient(input.baseUrl, input.token)\n if (typeof client.post !== 'function') {\n throw new Error('HttpClient does not support POST — required for snapshot push')\n }\n return client.post<PushSnapshotResult>(\n `/projects/${encodeURIComponent(input.project)}/snapshot`,\n { snapshot: input.snapshot },\n )\n}\n"],"mappings":"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","names":["path","fs","path","fs","path","path","fs","fs","path","renderOtelEnvBlock","fs","path","path","fs","entry","fs","path","SDK_PACKAGES","OTEL_ENV","exists","detect","plan","apply","rollback","plan","plan","fs","path","fileURLToPath","spawn","path","plan","projects","path","fs","projectPath","path","fileURLToPath","entry","spawn","fs","readline","readline","entry","path","Provenance","path","entry","path","entry","plan","fs","path","entry","orchestratorCode","apply","projectPath","renderOtelEnvBlock"]}