@neat.is/core 0.3.2 → 0.3.4
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/{chunk-FIXKIYNF.js → chunk-33ZZ2ZID.js} +606 -240
- package/dist/chunk-33ZZ2ZID.js.map +1 -0
- package/dist/{chunk-66Z5IEFY.js → chunk-T3A2GK3X.js} +2 -2
- package/dist/cli.cjs +674 -337
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +26 -26
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +565 -249
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +2 -2
- package/dist/neatd.cjs +572 -256
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +2 -2
- package/dist/server.cjs +535 -219
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-FIXKIYNF.js.map +0 -1
- /package/dist/{chunk-66Z5IEFY.js.map → chunk-T3A2GK3X.js.map} +0 -0
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/watch.ts","../src/extract/retire.ts","../src/installers/javascript.ts","../src/installers/python.ts","../src/installers/shared.ts","../src/installers/index.ts","../src/cli-client.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport path from 'node:path'\nimport { promises as fs } from 'node:fs'\nimport type { GraphEdge, GraphNode, ServiceNode } from '@neat.is/types'\nimport { DEFAULT_PROJECT, getGraph, resetGraph } from './graph.js'\nimport { extractFromDirectory } from './extract.js'\nimport { discoverServices } from './extract/services.js'\nimport type { DiscoveredService } from './extract/shared.js'\nimport { saveGraphToDisk } from './persist.js'\nimport { startWatch, type WatchHandle } from './watch.js'\nimport { pathsForProject } from './projects.js'\nimport {\n addProject,\n listProjects,\n ProjectNameCollisionError,\n removeProject,\n setStatus,\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 { DivergenceTypeSchema, type DivergenceType } from '@neat.is/types'\nimport {\n createHttpClient,\n exitCodeForError,\n formatHuman,\n formatJson,\n HttpError,\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}\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\nfunction usage(): void {\n console.log('usage: neat <command> [args] [--project <name>]')\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 List every project registered in the machine-level registry.')\n console.log(' pause <name> Mark a project paused — daemon stops watching until resumed.')\n console.log(' resume <name> Mark a project active again.')\n console.log(' uninstall <name>')\n console.log(' Remove a project from the registry. Does not touch')\n console.log(' neat-out/, policy.json, or any user file.')\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('')\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 outbound — what would 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 daemon not reachable (connection refused / timeout)')\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(' 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 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 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] 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 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 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 === '--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\nfunction summarise(nodes: GraphNode[], edges: GraphEdge[]): string {\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 const nodeLines = [...byNode.entries()]\n .sort((a, b) => a[0].localeCompare(b[0]))\n .map(([t, c]) => ` ${t}: ${c}`)\n const edgeLines = [...byEdge.entries()]\n .sort((a, b) => a[0].localeCompare(b[0]))\n .map(([t, c]) => ` ${t}: ${c}`)\n\n return ['nodes:', ...nodeLines, 'edges:', ...edgeLines].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\nfunction findIncompatibilities(nodes: GraphNode[]): ServiceNode[] {\n return nodes.filter(\n (n): n is ServiceNode =>\n n.type === 'ServiceNode' &&\n Array.isArray((n as ServiceNode).incompatibilities) &&\n ((n as ServiceNode).incompatibilities ?? []).length > 0,\n )\n}\n\nfunction 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 · v0.2.5 · BSL 1.1')\n console.log('')\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): Promise<PatchSection[]> {\n const sections: PatchSection[] = []\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)\n if (isEmptyPlan(plan)) 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)\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 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 const result = await extractFromDirectory(graph, opts.scanPath)\n await saveGraphToDisk(graph, opts.outPath)\n written.push(opts.outPath)\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 try {\n await addProject({\n name: opts.project,\n path: opts.scanPath,\n languages,\n status: 'active',\n })\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 // ── Step 7: write or apply patch ─────────────────────────────────────\n if (!opts.noInstall) {\n if (opts.apply) {\n for (const section of sections) {\n const installer = INSTALLERS.find((i) => i.name === section.installer)\n if (!installer) continue\n await installer.apply(section.plan)\n }\n if (sections.length > 0) {\n console.log('')\n console.log('patch applied. 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 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 console.log('')\n console.log('=== neat init: summary ===')\n console.log(`snapshot: ${opts.outPath}`)\n console.log(`added: ${result.nodesAdded} nodes, ${result.edgesAdded} edges`)\n console.log(`total: ${graph.order} nodes, ${graph.size} edges`)\n console.log(summarise(nodes, edges))\n\n const incompatibilities = findIncompatibilities(nodes)\n if (incompatibilities.length > 0) {\n console.log('')\n console.log(`incompatibilities found in ${incompatibilities.length} service(s):`)\n for (const svc of incompatibilities) {\n for (const inc of svc.incompatibilities ?? []) {\n console.log(` ${svc.name}: ${formatIncompat(inc)}`)\n }\n }\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_API_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 return { exitCode: 0 }\n}\n\nasync function main(): Promise<void> {\n const [, , cmd, ...rest] = process.argv\n\n if (!cmd || cmd === '-h' || cmd === '--help') {\n usage()\n process.exit(0)\n }\n\n const parsed = parseArgs(rest)\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 })\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 if (cmd === 'list') {\n const projects = await listProjects()\n if (projects.length === 0) {\n console.log('no projects registered. run `neat init <path>` to register one.')\n return\n }\n for (const p of projects) {\n const seen = p.lastSeenAt ? p.lastSeenAt : 'never'\n const langs = p.languages.length > 0 ? p.languages.join(',') : '-'\n console.log(`${p.name}\\t${p.status}\\t${langs}\\t${p.path}\\tlast-seen=${seen}`)\n }\n return\n }\n\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 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 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 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 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 removed = await removeProject(name)\n if (!removed) {\n console.error(`neat uninstall: no project named \"${name}\"`)\n process.exit(1)\n }\n console.log(`unregistered: ${removed.name} (${removed.path})`)\n console.log('note: neat-out/, policy.json, and other files at the project path were left in place.')\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 console.error(`neat: unknown command \"${cmd}\"`)\n usage()\n process.exit(1)\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/...\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\nexport async function runQueryVerb(cmd: string, parsed: ParsedArgs): Promise<number> {\n const baseUrl = process.env.NEAT_API_URL ?? 'http://localhost:8080'\n const client = createHttpClient(baseUrl)\n const project = resolveProjectFlag(parsed)\n const positional = parsed.positional\n\n // Per-verb arg/flag validation. Misuse exits 2 before any network call.\n let work: 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 work = 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 work = 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 work = 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 work = 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 work = 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 work = 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 work = runDiff(client, {\n againstSnapshot: against,\n ...(project ? { project } : {}),\n })\n break\n }\n case 'stale-edges': {\n work = 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 work = 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 work = 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 const result = await work\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 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? (NEAT_API_URL=${process.env.NEAT_API_URL ?? 'http://localhost:8080'})`)\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')) {\n main().catch((err) => {\n console.error(err)\n process.exit(1)\n })\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 { ensureCompatLoaded } from './compat.js'\nimport { discoverServices, addServiceNodes } from './extract/services.js'\nimport { addServiceAliases } from './extract/aliases.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 } from './otel.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 | 'databases'\n | 'configs'\n | 'calls'\n | 'infra'\n\nconst ALL_PHASES: ExtractPhase[] = [\n 'services',\n 'aliases',\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 → calls\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('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 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\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 '**/.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 /[\\\\/]?\\.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 const host = opts.host ?? '0.0.0.0'\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 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 project: projectName,\n writeErrorEventInline: false,\n onPolicyTrigger,\n })\n const onErrorSpanSync = makeErrorSpanWriter(opts.errorsPath)\n const otelHttp = await buildOtelReceiver({ onSpan, onErrorSpanSync })\n await otelHttp.listen({ port: otelPort, host })\n console.log(`neat-core OTLP receiver on http://${host}:${otelPort}/v1/traces`)\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 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 }\n\n return { api, stop }\n}\n","import type { GraphEdge } from '@neat.is/types'\nimport { Provenance } from '@neat.is/types'\nimport type { NeatGraph } from '../graph.js'\n\n// Drop every EXTRACTED edge whose evidence.file matches the given path.\n// Called from watch.ts before re-running an extract phase, so the producer's\n// idempotent re-write recreates only the edges that still apply. Edges from\n// the deleted code stay deleted. See docs/contracts/static-extraction.md\n// §Ghost-edge cleanup. Mutation authority lives under extract/* per\n// ADR-030, so the dropEdge call must happen here, not in watch.ts.\nexport function retireEdgesByFile(graph: NeatGraph, file: string): number {\n const normalized = file.split('\\\\').join('/')\n const toDrop: string[] = []\n graph.forEachEdge((id, attrs) => {\n const edge = attrs as GraphEdge\n if (edge.provenance !== Provenance.EXTRACTED) return\n if (!edge.evidence?.file) return\n if (edge.evidence.file === normalized) toDrop.push(id)\n })\n for (const id of toDrop) graph.dropEdge(id)\n return toDrop.length\n}\n","/**\n * Node / TypeScript SDK installer (ADR-047).\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 three OTel packages to `dependencies` and, if\n * a `scripts.start` exists, prefixes it with the auto-instrumentation hook.\n *\n * Lockfiles are never touched. After `--apply`, init prints \"run npm install\"\n * so the user owns the lockfile commit (ADR-047 — \"Lockfiles never touched\").\n */\n\nimport { promises as fs } from 'node:fs'\nimport path from 'node:path'\nimport type { DependencyEdit, EntrypointEdit, EnvEdit, Installer, InstallPlan } from './shared.js'\n\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\nconst AUTO_INSTRUMENT_REQUIRE = '--require @opentelemetry/auto-instrumentations-node/register'\n\nconst OTEL_ENV: EnvEdit = {\n // null target — NEAT does not write `.env` itself; the user sets the env\n // var in their orchestration layer.\n file: null,\n key: 'OTEL_EXPORTER_OTLP_ENDPOINT',\n value: 'http://localhost:4318',\n}\n\ninterface PackageJsonShape {\n name?: string\n scripts?: Record<string, string>\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n}\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 detect(serviceDir: string): Promise<boolean> {\n const pkg = await readPackageJson(serviceDir)\n return pkg !== null && typeof pkg.name === 'string'\n}\n\nfunction rewriteStartScript(start: string): string {\n // Already wired via auto-instrumentation? Don't touch — idempotency\n // (ADR-047 — \"Re-running init --apply produces no diff\").\n if (start.includes(AUTO_INSTRUMENT_REQUIRE)) return start\n // Most start scripts begin with `node …`. Keep the rest of the command and\n // splice the require flag in. Non-`node` starts (e.g. `next start`,\n // `tsx server.ts`) get the require flag prefixed via `node` since the\n // OTel hook needs a Node entry to attach to.\n if (/^\\s*node\\b/.test(start)) {\n return start.replace(/^\\s*node\\b\\s*/, `node ${AUTO_INSTRUMENT_REQUIRE} `)\n }\n return `node ${AUTO_INSTRUMENT_REQUIRE} -- ${start}`\n}\n\nasync function plan(serviceDir: string): Promise<InstallPlan> {\n const pkg = await readPackageJson(serviceDir)\n const manifestPath = path.join(serviceDir, 'package.json')\n const empty: InstallPlan = {\n language: 'javascript',\n serviceDir,\n dependencyEdits: [],\n entrypointEdits: [],\n envEdits: [],\n }\n if (!pkg) return empty\n\n const existingDeps = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) }\n const dependencyEdits: DependencyEdit[] = []\n for (const sdk of SDK_PACKAGES) {\n if (sdk.name in existingDeps) continue\n dependencyEdits.push({\n file: manifestPath,\n kind: 'add',\n name: sdk.name,\n version: sdk.version,\n })\n }\n // SDK_PACKAGES is already in stable declaration order, so the slice above\n // is deterministic across runs (ADR-047 #6).\n\n const entrypointEdits: EntrypointEdit[] = []\n const startScript = pkg.scripts?.start\n if (typeof startScript === 'string' && startScript.trim().length > 0) {\n const rewritten = rewriteStartScript(startScript)\n if (rewritten !== startScript) {\n entrypointEdits.push({ file: manifestPath, before: startScript, after: rewritten })\n }\n }\n\n // Empty plan when nothing needs to change anywhere — that is, every SDK\n // dep is present and the start script already wires the hook (or there's\n // no start script to wire). Surfaces ADR-047 #5: \"plan(dir) returns an\n // empty plan when SDK is already installed.\"\n if (dependencyEdits.length === 0 && entrypointEdits.length === 0) {\n return empty\n }\n\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits,\n entrypointEdits,\n envEdits: [OTEL_ENV],\n }\n}\n\nasync function apply(installPlan: InstallPlan): Promise<void> {\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) return\n\n // Snapshot every file we're about to mutate so a partial failure can roll\n // back the whole batch (ADR-047 #7). Missing files are intentionally not\n // an early-exit: the per-file mutation loop will hit them, fail, and\n // trigger rollback for the files we already wrote.\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 // No snapshot for this file. Mutation will fail loudly below.\n }\n }\n\n try {\n for (const file of touched) {\n const raw = originals.get(file) ?? ''\n const pkg = JSON.parse(raw) as PackageJsonShape\n pkg.dependencies = pkg.dependencies ?? {}\n\n for (const dep of installPlan.dependencyEdits) {\n if (dep.file !== file) continue\n if (dep.kind === 'add') {\n pkg.dependencies[dep.name] = dep.version\n } else {\n delete pkg.dependencies[dep.name]\n }\n }\n\n for (const ep of installPlan.entrypointEdits) {\n if (ep.file !== file) continue\n pkg.scripts = pkg.scripts ?? {}\n if (pkg.scripts.start === ep.before) {\n pkg.scripts.start = ep.after\n }\n }\n\n // Match the most common npm formatting (two-space indent, trailing\n // newline) so the diff stays minimal on review.\n const newRaw = JSON.stringify(pkg, null, 2) + '\\n'\n const tmp = `${file}.${process.pid}.${Date.now()}.tmp`\n await fs.writeFile(tmp, newRaw, 'utf8')\n await fs.rename(tmp, file)\n }\n } catch (err) {\n await rollback(installPlan, originals)\n throw err\n }\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: keep going so we restore as much as we can.\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 javascriptInstaller: Installer = {\n name: 'javascript',\n detect,\n plan,\n apply,\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 { DependencyEdit, EntrypointEdit, EnvEdit, Installer, InstallPlan } 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<void> {\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) return\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 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) await applyRequirementsTxt(file, edits, raw)\n } else if (base === 'Procfile') {\n const edits = installPlan.entrypointEdits.filter((e) => e.file === file)\n if (edits.length > 0) await applyProcfile(file, edits, raw)\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\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'\n name: string\n version: 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\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}\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): 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.\n apply(plan: InstallPlan): Promise<void>\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 )\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 DependencyEdit,\n EntrypointEdit,\n EnvEdit,\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.dependencyEdits.length > 0) {\n lines.push('### dependencies')\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 lines.push(`- ${dep.kind} ${dep.name}@${dep.version} in ${dep.file}`)\n }\n lines.push('')\n }\n\n if (plan.entrypointEdits.length > 0) {\n lines.push('### entrypoint')\n for (const e of plan.entrypointEdits) {\n lines.push(`- ${e.file}`)\n lines.push(` - before: ${e.before}`)\n lines.push(` - after: ${e.after}`)\n }\n lines.push('')\n }\n\n if (plan.envEdits.length > 0) {\n lines.push('### env')\n for (const env of plan.envEdits) {\n const target = env.file ?? '(set in your orchestration layer)'\n lines.push(`- ${env.key}=${env.value} → ${target}`)\n }\n lines.push('')\n }\n }\n return lines.join('\\n')\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 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\nexport function createHttpClient(baseUrl: string): HttpClient {\n const root = baseUrl.replace(/\\/$/, '')\n return {\n async get<T>(path: string): Promise<T> {\n let res: Response\n try {\n res = await fetch(`${root}${path}`)\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' },\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 downstream dependencies. 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} affected node${result.totalAffected === 1 ? '' : 's'} reachable downstream.`,\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\ninterface EdgesResponse {\n inbound: GraphEdge[]\n outbound: GraphEdge[]\n}\n\nexport async function runObservedDependencies(\n client: HttpClient,\n input: DependenciesInput,\n): Promise<VerbResult> {\n try {\n const edges = await client.get<EdgesResponse>(\n projectPath(input.project, `/graph/edges/${encodeURIComponent(input.nodeId)}`),\n )\n const observed = edges.outbound.filter((e) => e.provenance === Provenance.OBSERVED)\n if (observed.length === 0) {\n const hasExtracted = edges.outbound.some((e) => e.provenance === Provenance.EXTRACTED)\n const note = hasExtracted\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 = observed.map((e) => ` • ${e.target} — ${e.type}${edgeMeta(e)}`)\n return {\n summary: `${input.nodeId} has ${observed.length} runtime dependenc${observed.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"],"mappings":"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","names":["path","fs","fs","path","fs","path","SDK_PACKAGES","OTEL_ENV","detect","plan","apply","rollback","plan","plan","Provenance","path","plan","fs","path","apply","entry"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/watch.ts","../src/installers/javascript.ts","../src/installers/python.ts","../src/installers/shared.ts","../src/installers/index.ts","../src/cli-client.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport path from 'node:path'\nimport { promises as fs } from 'node:fs'\nimport type { GraphEdge, GraphNode, ServiceNode } from '@neat.is/types'\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 { saveGraphToDisk } from './persist.js'\nimport { startWatch, type WatchHandle } from './watch.js'\nimport { pathsForProject } from './projects.js'\nimport {\n addProject,\n listProjects,\n ProjectNameCollisionError,\n removeProject,\n setStatus,\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 { DivergenceTypeSchema, type DivergenceType } from '@neat.is/types'\nimport {\n createHttpClient,\n exitCodeForError,\n formatHuman,\n formatJson,\n HttpError,\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}\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\nfunction usage(): void {\n console.log('usage: neat <command> [args] [--project <name>]')\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 List every project registered in the machine-level registry.')\n console.log(' pause <name> Mark a project paused — daemon stops watching until resumed.')\n console.log(' resume <name> Mark a project active again.')\n console.log(' uninstall <name>')\n console.log(' Remove a project from the registry. Does not touch')\n console.log(' neat-out/, policy.json, or any user file.')\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('')\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 outbound — what would 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 daemon not reachable (connection refused / timeout)')\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(' 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 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 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] 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 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 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 === '--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\nfunction summarise(nodes: GraphNode[], edges: GraphEdge[]): string {\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 const nodeLines = [...byNode.entries()]\n .sort((a, b) => a[0].localeCompare(b[0]))\n .map(([t, c]) => ` ${t}: ${c}`)\n const edgeLines = [...byEdge.entries()]\n .sort((a, b) => a[0].localeCompare(b[0]))\n .map(([t, c]) => ` ${t}: ${c}`)\n\n return ['nodes:', ...nodeLines, 'edges:', ...edgeLines].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\nfunction findIncompatibilities(nodes: GraphNode[]): ServiceNode[] {\n return nodes.filter(\n (n): n is ServiceNode =>\n n.type === 'ServiceNode' &&\n Array.isArray((n as ServiceNode).incompatibilities) &&\n ((n as ServiceNode).incompatibilities ?? []).length > 0,\n )\n}\n\nfunction 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 · v0.2.5 · BSL 1.1')\n console.log('')\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): Promise<PatchSection[]> {\n const sections: PatchSection[] = []\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)\n if (isEmptyPlan(plan)) 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)\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 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 // ── 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 try {\n await addProject({\n name: opts.project,\n path: opts.scanPath,\n languages,\n status: 'active',\n })\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 // ── Step 7: write or apply patch ─────────────────────────────────────\n if (!opts.noInstall) {\n if (opts.apply) {\n for (const section of sections) {\n const installer = INSTALLERS.find((i) => i.name === section.installer)\n if (!installer) continue\n await installer.apply(section.plan)\n }\n if (sections.length > 0) {\n console.log('')\n console.log('patch applied. 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 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 console.log('')\n console.log('=== neat init: summary ===')\n console.log(`snapshot: ${opts.outPath}`)\n console.log(`added: ${result.nodesAdded} nodes, ${result.edgesAdded} edges`)\n console.log(`total: ${graph.order} nodes, ${graph.size} edges`)\n console.log(summarise(nodes, edges))\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 const incompatibilities = findIncompatibilities(nodes)\n if (incompatibilities.length > 0) {\n console.log('')\n console.log(`incompatibilities found in ${incompatibilities.length} service(s):`)\n for (const svc of incompatibilities) {\n for (const inc of svc.incompatibilities ?? []) {\n console.log(` ${svc.name}: ${formatIncompat(inc)}`)\n }\n }\n }\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_API_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 return { exitCode: 0 }\n}\n\nasync function main(): Promise<void> {\n const [, , cmd, ...rest] = process.argv\n\n if (!cmd || cmd === '-h' || cmd === '--help') {\n usage()\n process.exit(0)\n }\n\n const parsed = parseArgs(rest)\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 })\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 if (cmd === 'list') {\n const projects = await listProjects()\n if (projects.length === 0) {\n console.log('no projects registered. run `neat init <path>` to register one.')\n return\n }\n for (const p of projects) {\n const seen = p.lastSeenAt ? p.lastSeenAt : 'never'\n const langs = p.languages.length > 0 ? p.languages.join(',') : '-'\n console.log(`${p.name}\\t${p.status}\\t${langs}\\t${p.path}\\tlast-seen=${seen}`)\n }\n return\n }\n\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 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 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 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 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 removed = await removeProject(name)\n if (!removed) {\n console.error(`neat uninstall: no project named \"${name}\"`)\n process.exit(1)\n }\n console.log(`unregistered: ${removed.name} (${removed.path})`)\n console.log('note: neat-out/, policy.json, and other files at the project path were left in place.')\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 console.error(`neat: unknown command \"${cmd}\"`)\n usage()\n process.exit(1)\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/...\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\nexport async function runQueryVerb(cmd: string, parsed: ParsedArgs): Promise<number> {\n const baseUrl = process.env.NEAT_API_URL ?? 'http://localhost:8080'\n const client = createHttpClient(baseUrl)\n const project = resolveProjectFlag(parsed)\n const positional = parsed.positional\n\n // Per-verb arg/flag validation. Misuse exits 2 before any network call.\n let work: 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 work = 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 work = 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 work = 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 work = 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 work = 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 work = 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 work = runDiff(client, {\n againstSnapshot: against,\n ...(project ? { project } : {}),\n })\n break\n }\n case 'stale-edges': {\n work = 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 work = 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 work = 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 const result = await work\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 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? (NEAT_API_URL=${process.env.NEAT_API_URL ?? 'http://localhost:8080'})`)\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')) {\n main().catch((err) => {\n console.error(err)\n process.exit(1)\n })\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 { ensureCompatLoaded } from './compat.js'\nimport { discoverServices, addServiceNodes } from './extract/services.js'\nimport { addServiceAliases } from './extract/aliases.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 } from './otel.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 | 'databases'\n | 'configs'\n | 'calls'\n | 'infra'\n\nconst ALL_PHASES: ExtractPhase[] = [\n 'services',\n 'aliases',\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 → calls\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('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 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\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 '**/.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 /[\\\\/]?\\.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 const host = opts.host ?? '0.0.0.0'\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 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 project: projectName,\n writeErrorEventInline: false,\n onPolicyTrigger,\n })\n const onErrorSpanSync = makeErrorSpanWriter(opts.errorsPath)\n const otelHttp = await buildOtelReceiver({ onSpan, onErrorSpanSync })\n await otelHttp.listen({ port: otelPort, host })\n console.log(`neat-core OTLP receiver on http://${host}:${otelPort}/v1/traces`)\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 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 }\n\n return { api, stop }\n}\n","/**\n * Node / TypeScript SDK installer (ADR-047).\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 three OTel packages to `dependencies` and, if\n * a `scripts.start` exists, prefixes it with the auto-instrumentation hook.\n *\n * Lockfiles are never touched. After `--apply`, init prints \"run npm install\"\n * so the user owns the lockfile commit (ADR-047 — \"Lockfiles never touched\").\n */\n\nimport { promises as fs } from 'node:fs'\nimport path from 'node:path'\nimport type { DependencyEdit, EntrypointEdit, EnvEdit, Installer, InstallPlan } from './shared.js'\n\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\nconst AUTO_INSTRUMENT_REQUIRE = '--require @opentelemetry/auto-instrumentations-node/register'\n\nconst OTEL_ENV: EnvEdit = {\n // null target — NEAT does not write `.env` itself; the user sets the env\n // var in their orchestration layer.\n file: null,\n key: 'OTEL_EXPORTER_OTLP_ENDPOINT',\n value: 'http://localhost:4318',\n}\n\ninterface PackageJsonShape {\n name?: string\n scripts?: Record<string, string>\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n}\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 detect(serviceDir: string): Promise<boolean> {\n const pkg = await readPackageJson(serviceDir)\n return pkg !== null && typeof pkg.name === 'string'\n}\n\nfunction rewriteStartScript(start: string): string {\n // Already wired via auto-instrumentation? Don't touch — idempotency\n // (ADR-047 — \"Re-running init --apply produces no diff\").\n if (start.includes(AUTO_INSTRUMENT_REQUIRE)) return start\n // Most start scripts begin with `node …`. Keep the rest of the command and\n // splice the require flag in. Non-`node` starts (e.g. `next start`,\n // `tsx server.ts`) get the require flag prefixed via `node` since the\n // OTel hook needs a Node entry to attach to.\n if (/^\\s*node\\b/.test(start)) {\n return start.replace(/^\\s*node\\b\\s*/, `node ${AUTO_INSTRUMENT_REQUIRE} `)\n }\n return `node ${AUTO_INSTRUMENT_REQUIRE} -- ${start}`\n}\n\nasync function plan(serviceDir: string): Promise<InstallPlan> {\n const pkg = await readPackageJson(serviceDir)\n const manifestPath = path.join(serviceDir, 'package.json')\n const empty: InstallPlan = {\n language: 'javascript',\n serviceDir,\n dependencyEdits: [],\n entrypointEdits: [],\n envEdits: [],\n }\n if (!pkg) return empty\n\n const existingDeps = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) }\n const dependencyEdits: DependencyEdit[] = []\n for (const sdk of SDK_PACKAGES) {\n if (sdk.name in existingDeps) continue\n dependencyEdits.push({\n file: manifestPath,\n kind: 'add',\n name: sdk.name,\n version: sdk.version,\n })\n }\n // SDK_PACKAGES is already in stable declaration order, so the slice above\n // is deterministic across runs (ADR-047 #6).\n\n const entrypointEdits: EntrypointEdit[] = []\n const startScript = pkg.scripts?.start\n if (typeof startScript === 'string' && startScript.trim().length > 0) {\n const rewritten = rewriteStartScript(startScript)\n if (rewritten !== startScript) {\n entrypointEdits.push({ file: manifestPath, before: startScript, after: rewritten })\n }\n }\n\n // Empty plan when nothing needs to change anywhere — that is, every SDK\n // dep is present and the start script already wires the hook (or there's\n // no start script to wire). Surfaces ADR-047 #5: \"plan(dir) returns an\n // empty plan when SDK is already installed.\"\n if (dependencyEdits.length === 0 && entrypointEdits.length === 0) {\n return empty\n }\n\n return {\n language: 'javascript',\n serviceDir,\n dependencyEdits,\n entrypointEdits,\n envEdits: [OTEL_ENV],\n }\n}\n\nasync function apply(installPlan: InstallPlan): Promise<void> {\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) return\n\n // Snapshot every file we're about to mutate so a partial failure can roll\n // back the whole batch (ADR-047 #7). Missing files are intentionally not\n // an early-exit: the per-file mutation loop will hit them, fail, and\n // trigger rollback for the files we already wrote.\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 // No snapshot for this file. Mutation will fail loudly below.\n }\n }\n\n try {\n for (const file of touched) {\n const raw = originals.get(file) ?? ''\n const pkg = JSON.parse(raw) as PackageJsonShape\n pkg.dependencies = pkg.dependencies ?? {}\n\n for (const dep of installPlan.dependencyEdits) {\n if (dep.file !== file) continue\n if (dep.kind === 'add') {\n pkg.dependencies[dep.name] = dep.version\n } else {\n delete pkg.dependencies[dep.name]\n }\n }\n\n for (const ep of installPlan.entrypointEdits) {\n if (ep.file !== file) continue\n pkg.scripts = pkg.scripts ?? {}\n if (pkg.scripts.start === ep.before) {\n pkg.scripts.start = ep.after\n }\n }\n\n // Match the most common npm formatting (two-space indent, trailing\n // newline) so the diff stays minimal on review.\n const newRaw = JSON.stringify(pkg, null, 2) + '\\n'\n const tmp = `${file}.${process.pid}.${Date.now()}.tmp`\n await fs.writeFile(tmp, newRaw, 'utf8')\n await fs.rename(tmp, file)\n }\n } catch (err) {\n await rollback(installPlan, originals)\n throw err\n }\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: keep going so we restore as much as we can.\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 javascriptInstaller: Installer = {\n name: 'javascript',\n detect,\n plan,\n apply,\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 { DependencyEdit, EntrypointEdit, EnvEdit, Installer, InstallPlan } 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<void> {\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) return\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 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) await applyRequirementsTxt(file, edits, raw)\n } else if (base === 'Procfile') {\n const edits = installPlan.entrypointEdits.filter((e) => e.file === file)\n if (edits.length > 0) await applyProcfile(file, edits, raw)\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\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'\n name: string\n version: 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\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}\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): 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.\n apply(plan: InstallPlan): Promise<void>\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 )\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 DependencyEdit,\n EntrypointEdit,\n EnvEdit,\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.dependencyEdits.length > 0) {\n lines.push('### dependencies')\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 lines.push(`- ${dep.kind} ${dep.name}@${dep.version} in ${dep.file}`)\n }\n lines.push('')\n }\n\n if (plan.entrypointEdits.length > 0) {\n lines.push('### entrypoint')\n for (const e of plan.entrypointEdits) {\n lines.push(`- ${e.file}`)\n lines.push(` - before: ${e.before}`)\n lines.push(` - after: ${e.after}`)\n }\n lines.push('')\n }\n\n if (plan.envEdits.length > 0) {\n lines.push('### env')\n for (const env of plan.envEdits) {\n const target = env.file ?? '(set in your orchestration layer)'\n lines.push(`- ${env.key}=${env.value} → ${target}`)\n }\n lines.push('')\n }\n }\n return lines.join('\\n')\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 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\nexport function createHttpClient(baseUrl: string): HttpClient {\n const root = baseUrl.replace(/\\/$/, '')\n return {\n async get<T>(path: string): Promise<T> {\n let res: Response\n try {\n res = await fetch(`${root}${path}`)\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' },\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 downstream dependencies. 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} affected node${result.totalAffected === 1 ? '' : 's'} reachable downstream.`,\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\ninterface EdgesResponse {\n inbound: GraphEdge[]\n outbound: GraphEdge[]\n}\n\nexport async function runObservedDependencies(\n client: HttpClient,\n input: DependenciesInput,\n): Promise<VerbResult> {\n try {\n const edges = await client.get<EdgesResponse>(\n projectPath(input.project, `/graph/edges/${encodeURIComponent(input.nodeId)}`),\n )\n const observed = edges.outbound.filter((e) => e.provenance === Provenance.OBSERVED)\n if (observed.length === 0) {\n const hasExtracted = edges.outbound.some((e) => e.provenance === Provenance.EXTRACTED)\n const note = hasExtracted\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 = observed.map((e) => ` • ${e.target} — ${e.type}${edgeMeta(e)}`)\n return {\n summary: `${input.nodeId} has ${observed.length} runtime dependenc${observed.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"],"mappings":"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","names":["path","fs","fs","path","fs","path","SDK_PACKAGES","OTEL_ENV","detect","plan","apply","rollback","plan","plan","path","plan","fs","path","apply","entry"]}
|