@datasynx/agentic-ai-cartography 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1800,7 +1800,7 @@ Session: ${session.id}
1800
1800
  const yellow = (s) => `\x1B[33m${s}\x1B[0m`;
1801
1801
  const line = () => out(dim("\u2500".repeat(60)) + "\n");
1802
1802
  out("\n");
1803
- out(b(" CARTOGRAPHY") + " " + dim("v0.1.0") + "\n");
1803
+ out(b(" CARTOGRAPHY") + " " + dim("v0.1.2") + "\n");
1804
1804
  out(dim(" AI-powered Infrastructure Cartography & SOP Generation\n"));
1805
1805
  out("\n");
1806
1806
  line();
@@ -1942,6 +1942,80 @@ Session: ${session.id}
1942
1942
  out(dim(" PID: ~/.cartography/daemon.pid\n"));
1943
1943
  out("\n");
1944
1944
  });
1945
+ program.command("doctor").description("Pr\xFCft ob alle Voraussetzungen erf\xFCllt sind").action(async () => {
1946
+ const { execSync: execSync3 } = await import("child_process");
1947
+ const { existsSync: existsSync4, readFileSync: readFileSync3 } = await import("fs");
1948
+ const { join: join3 } = await import("path");
1949
+ const out = (s) => process.stdout.write(s);
1950
+ const ok = (msg) => out(` \x1B[32m\u2713\x1B[0m ${msg}
1951
+ `);
1952
+ const err = (msg) => out(` \x1B[31m\u2717\x1B[0m ${msg}
1953
+ `);
1954
+ const warn = (msg) => out(` \x1B[33m\u26A0\x1B[0m ${msg}
1955
+ `);
1956
+ const dim = (s) => `\x1B[2m${s}\x1B[0m`;
1957
+ let allGood = true;
1958
+ out("\n \x1B[1mCartography \u2014 Doctor\x1B[0m\n");
1959
+ out(dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n"));
1960
+ const nodeVer = process.versions.node;
1961
+ const [major] = nodeVer.split(".").map(Number);
1962
+ if ((major ?? 0) >= 18) {
1963
+ ok(`Node.js ${nodeVer}`);
1964
+ } else {
1965
+ err(`Node.js ${nodeVer} \u2014 ben\xF6tigt >=18`);
1966
+ allGood = false;
1967
+ }
1968
+ try {
1969
+ const v = execSync3("claude --version", { stdio: "pipe" }).toString().trim();
1970
+ ok(`Claude CLI ${dim(v)}`);
1971
+ } catch {
1972
+ err("Claude CLI nicht gefunden \u2014 npm i -g @anthropic-ai/claude-code");
1973
+ allGood = false;
1974
+ }
1975
+ const hasApiKey = Boolean(process.env.ANTHROPIC_API_KEY);
1976
+ const home = process.env.HOME ?? process.env.USERPROFILE ?? "/tmp";
1977
+ let hasOAuth = false;
1978
+ try {
1979
+ const creds = JSON.parse(readFileSync3(join3(home, ".claude", ".credentials.json"), "utf8"));
1980
+ const oauth = creds["claudeAiOauth"];
1981
+ hasOAuth = typeof oauth?.["accessToken"] === "string" && oauth["accessToken"].length > 0;
1982
+ } catch {
1983
+ }
1984
+ if (hasApiKey) {
1985
+ ok("ANTHROPIC_API_KEY gesetzt");
1986
+ } else if (hasOAuth) {
1987
+ ok("claude login (Subscription)");
1988
+ } else {
1989
+ err("Keine Authentifizierung \u2014 claude login oder export ANTHROPIC_API_KEY=sk-ant-...");
1990
+ allGood = false;
1991
+ }
1992
+ const optional = [
1993
+ ["docker", "docker --version"],
1994
+ ["kubectl", "kubectl version --client --short"],
1995
+ ["ss", "ss --version"]
1996
+ ];
1997
+ for (const [name, cmd] of optional) {
1998
+ try {
1999
+ execSync3(cmd, { stdio: "pipe" });
2000
+ ok(`${name} ${dim("(Discovery-Tool)")}`);
2001
+ } catch {
2002
+ warn(`${name} nicht gefunden ${dim("\u2014 Discovery ohne " + name + " eingeschr\xE4nkt")}`);
2003
+ }
2004
+ }
2005
+ const dbDir = join3(home, ".cartography");
2006
+ if (existsSync4(dbDir)) {
2007
+ ok(`~/.cartography ${dim("(Daten-Verzeichnis vorhanden)")}`);
2008
+ } else {
2009
+ warn("~/.cartography existiert noch nicht " + dim("\u2014 wird beim ersten Start angelegt"));
2010
+ }
2011
+ out(dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n"));
2012
+ if (allGood) {
2013
+ out(" \x1B[32m\x1B[1mAlle Checks bestanden \u2014 cartography discover\x1B[0m\n\n");
2014
+ } else {
2015
+ out(" \x1B[31m\x1B[1mEinige Checks fehlgeschlagen. Bitte oben beheben.\x1B[0m\n\n");
2016
+ process.exitCode = 1;
2017
+ }
2018
+ });
1945
2019
  program.exitOverride((err) => {
1946
2020
  if (err.code === "commander.helpDisplayed") {
1947
2021
  process.exitCode = 0;
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/preflight.ts","../src/types.ts","../src/db.ts","../src/tools.ts","../src/safety.ts","../src/agent.ts","../src/exporter.ts","../src/daemon.ts","../src/ipc.ts","../src/notify.ts","../src/client.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { checkPrerequisites, checkPollInterval } from './preflight.js';\nimport { CartographyDB } from './db.js';\nimport { defaultConfig } from './types.js';\nimport { runDiscovery, generateSOPs } from './agent.js';\nimport { exportAll } from './exporter.js';\nimport {\n forkDaemon, isDaemonRunning, stopDaemon, startDaemonProcess,\n} from './daemon.js';\nimport { ForegroundClient, AttachClient } from './client.js';\n\n// ── Daemon child-process entry ────────────────────────────────────────────────\nif (process.env.CARTOGRAPHYY_DAEMON === '1') {\n const config = JSON.parse(process.env.CARTOGRAPHYY_CONFIG ?? '{}') as ReturnType<typeof defaultConfig>;\n startDaemonProcess(config).catch((err) => {\n process.stderr.write(`Daemon fatal: ${err}\\n`);\n process.exitCode = 1;\n });\n} else {\n main();\n}\n\nfunction main(): void {\n const program = new Command();\n\n program\n .name('cartography')\n .description('AI-powered Infrastructure Cartography & SOP Generation')\n .version('0.1.0');\n\n // ── DISCOVERY ──────────────────────────────────────────────────────────────\n\n program\n .command('discover')\n .description('Infrastruktur scannen und kartographieren')\n .option('--entry <hosts...>', 'Startpunkte', ['localhost'])\n .option('--depth <n>', 'Max Tiefe', '8')\n .option('--max-turns <n>', 'Max Agent-Turns', '50')\n .option('--model <m>', 'Agent-Model', 'claude-sonnet-4-5-20250929')\n .option('--org <name>', 'Organisation (für Backstage)')\n .option('-o, --output <dir>', 'Output-Dir', './cartography-output')\n .option('--db <path>', 'DB-Pfad')\n .option('-v, --verbose', 'Agent-Reasoning anzeigen', false)\n .action(async (opts) => {\n checkPrerequisites();\n\n const config = defaultConfig({\n mode: 'discover',\n entryPoints: opts.entry,\n maxDepth: parseInt(opts.depth, 10),\n maxTurns: parseInt(opts.maxTurns, 10),\n agentModel: opts.model,\n organization: opts.org,\n outputDir: opts.output,\n ...(opts.db ? { dbPath: opts.db } : {}),\n verbose: opts.verbose,\n });\n\n const db = new CartographyDB(config.dbPath);\n const sessionId = db.createSession('discover', config);\n\n process.stderr.write(`🔍 Scanning ${config.entryPoints.join(', ')}...\\n`);\n process.stderr.write(` Model: ${config.agentModel} | MaxTurns: ${config.maxTurns}\\n\\n`);\n\n try {\n await runDiscovery(config, db, sessionId, (text) => {\n if (config.verbose) process.stdout.write(text + '\\n');\n });\n } catch (err) {\n process.stderr.write(`❌ Discovery fehlgeschlagen: ${err}\\n`);\n db.close();\n process.exitCode = 1;\n return;\n }\n\n db.endSession(sessionId);\n const stats = db.getStats(sessionId);\n\n process.stderr.write(`\\n✓ ${stats.nodes} nodes, ${stats.edges} edges discovered\\n`);\n\n exportAll(db, sessionId, config.outputDir);\n process.stderr.write(`✓ Exported to: ${config.outputDir}\\n`);\n\n db.close();\n });\n\n // ── SHADOW ────────────────────────────────────────────────────────────────\n\n const shadow = program.command('shadow').description('Shadow-Daemon verwalten');\n\n shadow\n .command('start')\n .description('Shadow-Daemon starten')\n .option('--interval <ms>', 'Poll-Intervall in ms', '30000')\n .option('--inactivity <ms>', 'Task-Grenze in ms', '300000')\n .option('--track-windows', 'Fenster-Focus tracken', false)\n .option('--auto-save', 'Nodes ohne Rückfrage speichern', false)\n .option('--no-notifications', 'Desktop-Notifications deaktivieren')\n .option('--model <m>', 'Analysis-Model', 'claude-haiku-4-5-20251001')\n .option('--foreground', 'Kein Daemon, im Terminal bleiben', false)\n .option('--db <path>', 'DB-Pfad')\n .option('--daemon-child', 'Internal: marks this as a daemon child process') // internal flag\n .action(async (opts) => {\n checkPrerequisites();\n\n const intervalMs = checkPollInterval(parseInt(opts.interval, 10));\n\n const config = defaultConfig({\n mode: 'shadow',\n shadowMode: opts.foreground ? 'foreground' : 'daemon',\n pollIntervalMs: intervalMs,\n inactivityTimeoutMs: parseInt(opts.inactivity, 10),\n trackWindowFocus: opts.trackWindows,\n autoSaveNodes: opts.autoSave,\n enableNotifications: opts.notifications !== false,\n shadowModel: opts.model,\n ...(opts.db ? { dbPath: opts.db } : {}),\n });\n\n // Check if already running\n const { running } = isDaemonRunning(config.pidFile);\n if (running) {\n process.stderr.write('❌ Shadow-Daemon läuft bereits. cartography shadow status\\n');\n process.exitCode = 1;\n return;\n }\n\n if (opts.foreground) {\n const client = new ForegroundClient();\n await client.run(config);\n } else {\n const pid = forkDaemon(config);\n process.stderr.write(`👁 Shadow daemon started (PID ${pid})\\n`);\n process.stderr.write(` Intervall: ${intervalMs / 1000}s | Modell: ${config.shadowModel}\\n`);\n process.stderr.write(' cartography shadow attach — ankoppeln\\n');\n process.stderr.write(' cartography shadow stop — stoppen\\n\\n');\n }\n });\n\n shadow\n .command('stop')\n .description('Shadow-Daemon stoppen')\n .action(() => {\n const config = defaultConfig();\n const stopped = stopDaemon(config.pidFile);\n if (stopped) {\n process.stderr.write('✓ Shadow-Daemon gestoppt\\n');\n } else {\n process.stderr.write('⚠ Kein laufender Shadow-Daemon gefunden\\n');\n }\n });\n\n shadow\n .command('status')\n .description('Shadow-Daemon Status anzeigen')\n .action(() => {\n const config = defaultConfig();\n const { running, pid } = isDaemonRunning(config.pidFile);\n if (running) {\n process.stdout.write(`✓ Shadow-Daemon läuft (PID ${pid})\\n`);\n process.stdout.write(` Socket: ${config.socketPath}\\n`);\n } else {\n process.stdout.write('✗ Shadow-Daemon gestoppt\\n');\n }\n });\n\n shadow\n .command('attach')\n .description('An laufenden Shadow-Daemon ankoppeln')\n .action(async () => {\n const config = defaultConfig();\n const client = new AttachClient();\n await client.attach(config.socketPath);\n });\n\n // ── ANALYSE & EXPORT ──────────────────────────────────────────────────────\n\n program\n .command('sops [session-id]')\n .description('SOPs aus beobachteten Workflows generieren')\n .action(async (sessionId?: string) => {\n checkPrerequisites();\n\n const config = defaultConfig();\n const db = new CartographyDB(config.dbPath);\n\n const session = sessionId\n ? db.getSession(sessionId)\n : db.getLatestSession('shadow');\n\n if (!session) {\n process.stderr.write('❌ Keine Shadow-Session gefunden. cartography shadow start\\n');\n db.close();\n process.exitCode = 1;\n return;\n }\n\n process.stderr.write(`🔄 Generiere SOPs aus Session ${session.id}...\\n`);\n const count = await generateSOPs(db, session.id);\n process.stderr.write(`✓ ${count} SOPs generiert\\n`);\n\n db.close();\n });\n\n program\n .command('export [session-id]')\n .description('Alle Outputs generieren')\n .option('-o, --output <dir>', 'Output-Dir', './cartography-output')\n .option('--format <fmt...>', 'Formate: mermaid,json,yaml,html,sops')\n .action((sessionId: string | undefined, opts) => {\n const config = defaultConfig({ outputDir: opts.output });\n const db = new CartographyDB(config.dbPath);\n\n const session = sessionId\n ? db.getSession(sessionId)\n : db.getLatestSession();\n\n if (!session) {\n process.stderr.write('❌ Keine Session gefunden\\n');\n db.close();\n process.exitCode = 1;\n return;\n }\n\n const formats = opts.format ?? ['mermaid', 'json', 'yaml', 'html', 'sops'];\n exportAll(db, session.id, opts.output, formats);\n process.stderr.write(`✓ Exported to: ${opts.output}\\n`);\n\n db.close();\n });\n\n program\n .command('show [session-id]')\n .description('Session-Details anzeigen')\n .action((sessionId?: string) => {\n const config = defaultConfig();\n const db = new CartographyDB(config.dbPath);\n\n const session = sessionId\n ? db.getSession(sessionId)\n : db.getLatestSession();\n\n if (!session) {\n process.stderr.write('❌ Keine Session gefunden\\n');\n db.close();\n process.exitCode = 1;\n return;\n }\n\n const stats = db.getStats(session.id);\n const nodes = db.getNodes(session.id);\n\n process.stdout.write(`\\nSession: ${session.id}\\n`);\n process.stdout.write(` Mode: ${session.mode}\\n`);\n process.stdout.write(` Started: ${session.startedAt}\\n`);\n if (session.completedAt) process.stdout.write(` Ended: ${session.completedAt}\\n`);\n process.stdout.write(` Nodes: ${stats.nodes}\\n`);\n process.stdout.write(` Edges: ${stats.edges}\\n`);\n process.stdout.write(` Events: ${stats.events}\\n`);\n process.stdout.write(` Tasks: ${stats.tasks}\\n`);\n\n if (nodes.length > 0) {\n process.stdout.write('\\n Discovered nodes:\\n');\n for (const node of nodes.slice(0, 20)) {\n process.stdout.write(` ${node.id} (${node.type}, confidence: ${node.confidence})\\n`);\n }\n if (nodes.length > 20) {\n process.stdout.write(` ... and ${nodes.length - 20} more\\n`);\n }\n }\n\n process.stdout.write('\\n');\n db.close();\n });\n\n program\n .command('sessions')\n .description('Alle Sessions auflisten')\n .action(() => {\n const config = defaultConfig();\n const db = new CartographyDB(config.dbPath);\n const sessions = db.getSessions();\n\n if (sessions.length === 0) {\n process.stdout.write('Keine Sessions gefunden\\n');\n db.close();\n return;\n }\n\n for (const session of sessions) {\n const stats = db.getStats(session.id);\n const status = session.completedAt ? '✓' : '●';\n process.stdout.write(\n `${status} ${session.id.substring(0, 8)} [${session.mode}] ` +\n `${session.startedAt.substring(0, 19)} ` +\n `nodes:${stats.nodes} edges:${stats.edges}\\n`\n );\n }\n\n db.close();\n });\n\n // ── DOCS ──────────────────────────────────────────────────────────────────\n\n program\n .command('docs')\n .description('Alle Features und Befehle auf einen Blick')\n .action(() => {\n const out = process.stdout.write.bind(process.stdout);\n const b = (s: string) => `\\x1b[1m${s}\\x1b[0m`;\n const dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\n const cyan = (s: string) => `\\x1b[36m${s}\\x1b[0m`;\n const green = (s: string) => `\\x1b[32m${s}\\x1b[0m`;\n const yellow = (s: string) => `\\x1b[33m${s}\\x1b[0m`;\n const line = () => out(dim('─'.repeat(60)) + '\\n');\n\n out('\\n');\n out(b(' CARTOGRAPHY') + ' ' + dim('v0.1.0') + '\\n');\n out(dim(' AI-powered Infrastructure Cartography & SOP Generation\\n'));\n out('\\n');\n line();\n\n // ── DISCOVERY\n out(b(cyan(' DISCOVERY\\n')));\n out('\\n');\n out(` ${green('cartography discover')}\\n`);\n out(` Scannt die lokale Infrastruktur (Claude Sonnet).\\n`);\n out(` Claude führt eigenständig ss, ps, curl, docker inspect, kubectl get\\n`);\n out(` aus und speichert alles in SQLite.\\n`);\n out('\\n');\n out(dim(' Optionen:\\n'));\n out(dim(' --entry <hosts...> Startpunkte (default: localhost)\\n'));\n out(dim(' --depth <n> Max Tiefe (default: 8)\\n'));\n out(dim(' --max-turns <n> Max Agent-Turns (default: 50)\\n'));\n out(dim(' --model <m> Model (default: claude-sonnet-4-5-...)\\n'));\n out(dim(' --org <name> Organisation für Backstage YAML\\n'));\n out(dim(' -o, --output <dir> Output-Verzeichnis (default: ./cartography-output)\\n'));\n out(dim(' -v, --verbose Agent-Reasoning anzeigen\\n'));\n out('\\n');\n out(dim(' Output:\\n'));\n out(dim(' cartography-output/\\n'));\n out(dim(' catalog.json Maschinenlesbarer Komplett-Dump\\n'));\n out(dim(' catalog-info.yaml Backstage Service-Katalog\\n'));\n out(dim(' topology.mermaid Infrastruktur-Topologie (graph TB)\\n'));\n out(dim(' dependencies.mermaid Service-Dependencies (graph LR)\\n'));\n out(dim(' topology.html Interaktiver D3.js Force-Graph\\n'));\n out(dim(' sops/ Generierte SOPs als Markdown\\n'));\n out(dim(' workflows/ Workflow-Flowcharts als Mermaid\\n'));\n out('\\n');\n line();\n\n // ── SHADOW\n out(b(cyan(' SHADOW DAEMON\\n')));\n out('\\n');\n out(` ${green('cartography shadow start')}\\n`);\n out(` Startet einen Background-Daemon, der alle 30s einen System-Snapshot\\n`);\n out(` nimmt (ss + ps). Nur bei Änderung ruft er Claude Haiku auf.\\n`);\n out('\\n');\n out(dim(' Optionen:\\n'));\n out(dim(' --interval <ms> Poll-Intervall (default: 30000, min: 15000)\\n'));\n out(dim(' --inactivity <ms> Task-Grenze (default: 300000 = 5 min)\\n'));\n out(dim(' --model <m> Analysis-Model (default: claude-haiku-4-5-...)\\n'));\n out(dim(' --track-windows Fenster-Focus tracken (benötigt xdotool)\\n'));\n out(dim(' --auto-save Nodes ohne Rückfrage speichern\\n'));\n out(dim(' --no-notifications Desktop-Notifications deaktivieren\\n'));\n out(dim(' --foreground Kein Daemon, im Terminal bleiben\\n'));\n out('\\n');\n out(` ${green('cartography shadow stop')} ${dim('Daemon per SIGTERM beenden')}\\n`);\n out(` ${green('cartography shadow status')} ${dim('PID + Socket-Pfad anzeigen')}\\n`);\n out(` ${green('cartography shadow attach')} ${dim('Live-Events im Terminal, Hotkeys: [T] [S] [D] [Q]')}\\n`);\n out('\\n');\n out(dim(' Hotkeys im Attach-Modus:\\n'));\n out(dim(' [T] Neuen Task starten (mit Beschreibung)\\n'));\n out(dim(' [S] Status-Dump anzeigen (Nodes, Events, Tasks, Cycles)\\n'));\n out(dim(' [D] Trennen — Daemon läuft weiter\\n'));\n out(dim(' [Q] Daemon stoppen und beenden\\n'));\n out('\\n');\n line();\n\n // ── ANALYSE & EXPORT\n out(b(cyan(' ANALYSE & EXPORT\\n')));\n out('\\n');\n out(` ${green('cartography sops [session-id]')}\\n`);\n out(` Clustert abgeschlossene Tasks und generiert SOPs via Claude Sonnet.\\n`);\n out(` Nutzt die Anthropic Messages API (kein Agent-Loop, ein Request pro Cluster).\\n`);\n out('\\n');\n out(` ${green('cartography export [session-id]')}\\n`);\n out(dim(' --format <fmt...> mermaid, json, yaml, html, sops (default: alle)\\n'));\n out(dim(' -o, --output <dir> Output-Verzeichnis\\n'));\n out('\\n');\n out(` ${green('cartography show [session-id]')} ${dim('Session-Details + Node-Liste')}\\n`);\n out(` ${green('cartography sessions')} ${dim('Alle Sessions tabellarisch auflisten')}\\n`);\n out('\\n');\n line();\n\n // ── KOSTEN\n out(b(cyan(' KOSTEN (Richtwerte)\\n')));\n out('\\n');\n out(yellow(' Modus Model Intervall pro Stunde pro 8h-Tag\\n'));\n out(dim(' ─────────────────────────────────────────────────────────────\\n'));\n out(` Discovery Sonnet einmalig $0.15–0.50 einmalig\\n`);\n out(` Shadow Haiku 30s $0.12–0.36 $0.96–2.88\\n`);\n out(` Shadow Haiku 60s $0.06–0.18 $0.48–1.44\\n`);\n out(` Shadow (ruhig) Haiku 30s ~$0.02 ~$0.16\\n`);\n out(` SOP-Gen Sonnet einmalig $0.01–0.03 einmalig\\n`);\n out('\\n');\n out(dim(' * \"ruhig\" = Diff-Check überspringt 90%+ Cycles, wenn System unverändert\\n'));\n out('\\n');\n line();\n\n // ── ARCHITEKTUR\n out(b(cyan(' ARCHITEKTUR\\n')));\n out('\\n');\n out(dim(' CLI (Commander)\\n'));\n out(dim(' └── Preflight: Claude CLI check + API key + Intervall-Validierung\\n'));\n out(dim(' └── Agent Orchestrator (agent.ts)\\n'));\n out(dim(' ├── runDiscovery() → Claude Sonnet + Bash + MCP Tools\\n'));\n out(dim(' ├── runShadowCycle() → Claude Haiku + nur MCP Tools (kein Bash!)\\n'));\n out(dim(' └── generateSOPs() → Anthropic Messages API (kein Agent-Loop)\\n'));\n out(dim(' └── Custom MCP Tools (tools.ts)\\n'));\n out(dim(' save_node, save_edge, save_event,\\n'));\n out(dim(' get_catalog, manage_task, save_sop\\n'));\n out(dim(' └── CartographyDB (SQLite WAL)\\n'));\n out(dim(' Shadow Daemon (daemon.ts)\\n'));\n out(dim(' ├── takeSnapshot() → ss + ps [kein Claude!]\\n'));\n out(dim(' ├── Diff-Check → nur bei Änderung: runShadowCycle()\\n'));\n out(dim(' ├── IPC Server (Unix Socket ~/.cartography/daemon.sock)\\n'));\n out(dim(' └── NotificationService (Desktop wenn kein Client attached)\\n'));\n out('\\n');\n line();\n\n // ── SETUP\n out(b(cyan(' SETUP\\n')));\n out('\\n');\n out(dim(' # 1. Claude CLI (Runtime-Dependency)\\n'));\n out(' npm install -g @anthropic-ai/claude-code\\n');\n out(' claude login\\n');\n out('\\n');\n out(dim(' # 2. API Key (falls nicht via claude login)\\n'));\n out(' export ANTHROPIC_API_KEY=sk-ant-...\\n');\n out('\\n');\n out(dim(' # 3. Los\\n'));\n out(' cartography discover\\n');\n out(' cartography shadow start\\n');\n out('\\n');\n out(dim(' Daten: ~/.cartography/cartography.db\\n'));\n out(dim(' Socket: ~/.cartography/daemon.sock\\n'));\n out(dim(' PID: ~/.cartography/daemon.pid\\n'));\n out('\\n');\n });\n\n // ── Parse ──────────────────────────────────────────────────────────────────\n\n program.exitOverride((err) => {\n if (err.code === 'commander.helpDisplayed') {\n process.exitCode = 0;\n } else {\n process.exitCode = 2;\n }\n });\n\n program.parse(process.argv);\n}\n","import { execSync } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { MIN_POLL_INTERVAL_MS } from './types.js';\n\nfunction isOAuthLoggedIn(): boolean {\n // Claude CLI speichert OAuth-Tokens in ~/.claude/.credentials.json\n const home = process.env.HOME ?? process.env.USERPROFILE ?? '/tmp';\n const credFile = join(home, '.claude', '.credentials.json');\n if (!existsSync(credFile)) return false;\n try {\n const creds = JSON.parse(readFileSync(credFile, 'utf8')) as Record<string, unknown>;\n const oauth = creds['claudeAiOauth'] as Record<string, unknown> | undefined;\n return typeof oauth?.['accessToken'] === 'string' && oauth['accessToken'].length > 0;\n } catch {\n return false;\n }\n}\n\nexport function checkPrerequisites(): void {\n // Claude CLI vorhanden?\n try {\n execSync('claude --version', { stdio: 'pipe' });\n } catch {\n process.stderr.write(\n '\\n❌ Claude CLI nicht gefunden.\\n' +\n ' Cartography braucht die Claude CLI als Runtime-Dependency.\\n\\n' +\n ' Installieren:\\n' +\n ' npm install -g @anthropic-ai/claude-code\\n' +\n ' # oder\\n' +\n ' curl -fsSL https://claude.ai/install.sh | bash\\n\\n' +\n ' Danach: claude login\\n\\n'\n );\n process.exitCode = 1;\n throw new Error('Claude CLI not found');\n }\n\n // Auth prüfen: API Key ODER OAuth-Login (claude.ai Subscription)\n const hasApiKey = Boolean(process.env.ANTHROPIC_API_KEY);\n const hasOAuth = isOAuthLoggedIn();\n\n if (!hasApiKey && !hasOAuth) {\n process.stderr.write(\n '⚠ Keine Authentifizierung gefunden. Bitte eine der folgenden Optionen:\\n\\n' +\n ' Option A — claude.ai Subscription (empfohlen):\\n' +\n ' claude login\\n\\n' +\n ' Option B — API Key:\\n' +\n ' export ANTHROPIC_API_KEY=sk-ant-...\\n\\n'\n );\n } else if (hasOAuth && !hasApiKey) {\n process.stderr.write('✓ Eingeloggt via claude login (Subscription)\\n');\n }\n}\n\nexport function checkPollInterval(intervalMs: number): number {\n if (intervalMs < MIN_POLL_INTERVAL_MS) {\n process.stderr.write(\n `⚠ Minimum Shadow-Intervall: ${MIN_POLL_INTERVAL_MS / 1000} Sekunden (Agent SDK Overhead)\\n`\n );\n return MIN_POLL_INTERVAL_MS;\n }\n return intervalMs;\n}\n","import { z } from 'zod';\n\n// ── Enums ────────────────────────────────\n\nexport const NODE_TYPES = [\n 'host', 'database_server', 'database', 'table',\n 'web_service', 'api_endpoint', 'cache_server',\n 'message_broker', 'queue', 'topic',\n 'container', 'pod', 'k8s_cluster',\n 'config_file', 'unknown',\n] as const;\nexport type NodeType = typeof NODE_TYPES[number];\n\nexport const EDGE_RELATIONSHIPS = [\n 'connects_to', 'reads_from', 'writes_to',\n 'calls', 'contains', 'depends_on',\n] as const;\nexport type EdgeRelationship = typeof EDGE_RELATIONSHIPS[number];\n\nexport const EVENT_TYPES = [\n 'process_start', 'process_end',\n 'connection_open', 'connection_close',\n 'window_focus', 'tool_switch',\n] as const;\nexport type EventType = typeof EVENT_TYPES[number];\n\n// ── Zod Schemas ──────────────────────────\n\nexport const NodeSchema = z.object({\n id: z.string().describe('Format: \"{type}:{host}:{port}\" oder \"{type}:{name}\"'),\n type: z.enum(NODE_TYPES),\n name: z.string(),\n discoveredVia: z.string(),\n confidence: z.number().min(0).max(1).default(0.5),\n metadata: z.record(z.unknown()).default({}),\n tags: z.array(z.string()).default([]),\n});\nexport type DiscoveryNode = z.infer<typeof NodeSchema>;\n\nexport const EdgeSchema = z.object({\n sourceId: z.string(),\n targetId: z.string(),\n relationship: z.enum(EDGE_RELATIONSHIPS),\n evidence: z.string(),\n confidence: z.number().min(0).max(1).default(0.5),\n});\nexport type DiscoveryEdge = z.infer<typeof EdgeSchema>;\n\nexport const EventSchema = z.object({\n eventType: z.enum(EVENT_TYPES),\n process: z.string(),\n pid: z.number(),\n target: z.string().optional(),\n targetType: z.enum(NODE_TYPES).optional(),\n protocol: z.string().optional(),\n port: z.number().optional(),\n});\nexport type ActivityEvent = z.infer<typeof EventSchema>;\n\nexport const SOPStepSchema = z.object({\n order: z.number(),\n instruction: z.string(),\n tool: z.string(),\n target: z.string().optional(),\n notes: z.string().optional(),\n});\nexport type SOPStep = z.infer<typeof SOPStepSchema>;\n\nexport const SOPSchema = z.object({\n title: z.string(),\n description: z.string(),\n steps: z.array(SOPStepSchema),\n involvedSystems: z.array(z.string()),\n estimatedDuration: z.string(),\n frequency: z.string(),\n confidence: z.number().min(0).max(1),\n});\nexport type SOP = z.infer<typeof SOPSchema>;\n\n// ── DB Row Types ─────────────────────────\n\nexport interface NodeRow extends DiscoveryNode {\n sessionId: string;\n discoveredAt: string;\n depth: number;\n pathId?: string;\n}\n\nexport interface EdgeRow extends DiscoveryEdge {\n id: string;\n sessionId: string;\n discoveredAt: string;\n pathId?: string;\n}\n\nexport interface EventRow {\n id: string;\n sessionId: string;\n taskId?: string;\n timestamp: string;\n eventType: EventType;\n process: string;\n pid: number;\n target?: string;\n targetType?: NodeType;\n port?: number;\n durationMs?: number;\n}\n\nexport interface TaskRow {\n id: string;\n sessionId: string;\n description?: string;\n startedAt: string;\n completedAt?: string;\n steps: string;\n involvedServices: string;\n status: 'active' | 'completed' | 'cancelled';\n isSOPCandidate: boolean;\n}\n\nexport interface WorkflowRow {\n id: string;\n sessionId: string;\n name?: string;\n pattern: string;\n taskIds: string;\n occurrences: number;\n firstSeen: string;\n lastSeen: string;\n avgDurationMs: number;\n involvedServices: string;\n}\n\nexport interface SessionRow {\n id: string;\n mode: 'discover' | 'shadow';\n startedAt: string;\n completedAt?: string;\n config: string;\n}\n\n// ── IPC Protokoll ────────────────────────\n\nexport type DaemonMessage =\n | { type: 'event'; data: EventRow }\n | { type: 'prompt'; id: string; prompt: PendingPrompt }\n | { type: 'status'; data: ShadowStatus }\n | { type: 'agent-output'; text: string }\n | { type: 'info'; message: string };\n\nexport type ClientMessage =\n | { type: 'prompt-response'; id: string; answer: string }\n | { type: 'command'; command: 'new-task' | 'end-task' | 'status' | 'stop' }\n | { type: 'task-description'; description: string };\n\nexport interface PendingPrompt {\n kind: 'node-approval' | 'task-boundary' | 'task-end';\n context: Record<string, unknown>;\n options: string[];\n defaultAnswer: string;\n timeoutMs: number;\n createdAt: string;\n}\n\nexport interface ShadowStatus {\n pid: number;\n uptime: number;\n nodeCount: number;\n eventCount: number;\n taskCount: number;\n pendingPrompts: number;\n autoSave: boolean;\n mode: 'foreground' | 'daemon';\n agentActive: boolean;\n cyclesRun: number;\n cyclesSkipped: number;\n}\n\n// ── Config ───────────────────────────────\n\nexport const MIN_POLL_INTERVAL_MS = 15_000; // 15s Minimum (Agent SDK Overhead)\n\nexport interface CartographyConfig {\n mode: 'discover' | 'shadow';\n maxDepth: number;\n maxTurns: number;\n entryPoints: string[];\n agentModel: string;\n shadowMode: 'foreground' | 'daemon';\n pollIntervalMs: number;\n inactivityTimeoutMs: number;\n promptTimeoutMs: number;\n trackWindowFocus: boolean;\n autoSaveNodes: boolean;\n enableNotifications: boolean;\n shadowModel: string;\n organization?: string;\n outputDir: string;\n dbPath: string;\n socketPath: string;\n pidFile: string;\n verbose: boolean;\n}\n\nexport function defaultConfig(overrides: Partial<CartographyConfig> = {}): CartographyConfig {\n const home = process.env.HOME ?? process.env.USERPROFILE ?? '/tmp';\n return {\n mode: 'discover',\n maxDepth: 8,\n maxTurns: 50,\n entryPoints: ['localhost'],\n agentModel: 'claude-sonnet-4-5-20250929',\n shadowMode: 'daemon',\n pollIntervalMs: 30_000,\n inactivityTimeoutMs: 300_000,\n promptTimeoutMs: 60_000,\n trackWindowFocus: false,\n autoSaveNodes: false,\n enableNotifications: true,\n shadowModel: 'claude-haiku-4-5-20251001',\n outputDir: './cartography-output',\n dbPath: `${home}/.cartography/cartography.db`,\n socketPath: `${home}/.cartography/daemon.sock`,\n pidFile: `${home}/.cartography/daemon.pid`,\n verbose: false,\n ...overrides,\n };\n}\n","import Database from 'better-sqlite3';\nimport { mkdirSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport type {\n CartographyConfig, DiscoveryNode, DiscoveryEdge, ActivityEvent,\n NodeRow, EdgeRow, EventRow, TaskRow, WorkflowRow, SessionRow, SOP,\n} from './types.js';\n\nconst SCHEMA = `\nPRAGMA journal_mode = WAL;\nPRAGMA foreign_keys = ON;\nPRAGMA busy_timeout = 5000;\n\nCREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n mode TEXT NOT NULL CHECK (mode IN ('discover','shadow')),\n started_at TEXT NOT NULL,\n completed_at TEXT,\n config TEXT NOT NULL DEFAULT '{}'\n);\n\nCREATE TABLE IF NOT EXISTS nodes (\n id TEXT NOT NULL,\n session_id TEXT NOT NULL REFERENCES sessions(id),\n type TEXT NOT NULL,\n name TEXT NOT NULL,\n discovered_via TEXT,\n discovered_at TEXT NOT NULL,\n path_id TEXT,\n depth INTEGER DEFAULT 0,\n confidence REAL DEFAULT 0.5,\n metadata TEXT NOT NULL DEFAULT '{}',\n tags TEXT NOT NULL DEFAULT '[]',\n PRIMARY KEY (id, session_id)\n);\n\nCREATE TABLE IF NOT EXISTS edges (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL REFERENCES sessions(id),\n source_id TEXT NOT NULL,\n target_id TEXT NOT NULL,\n relationship TEXT NOT NULL,\n evidence TEXT,\n confidence REAL DEFAULT 0.5,\n discovered_at TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS activity_events (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL REFERENCES sessions(id),\n task_id TEXT,\n timestamp TEXT NOT NULL,\n event_type TEXT NOT NULL,\n process TEXT NOT NULL,\n pid INTEGER NOT NULL,\n target TEXT,\n target_type TEXT,\n port INTEGER,\n duration_ms INTEGER\n);\n\nCREATE TABLE IF NOT EXISTS tasks (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL REFERENCES sessions(id),\n description TEXT,\n started_at TEXT NOT NULL,\n completed_at TEXT,\n steps TEXT NOT NULL DEFAULT '[]',\n involved_services TEXT NOT NULL DEFAULT '[]',\n status TEXT DEFAULT 'active' CHECK (status IN ('active','completed','cancelled')),\n is_sop_candidate INTEGER DEFAULT 0\n);\n\nCREATE TABLE IF NOT EXISTS workflows (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL REFERENCES sessions(id),\n name TEXT,\n pattern TEXT NOT NULL,\n task_ids TEXT NOT NULL DEFAULT '[]',\n occurrences INTEGER DEFAULT 1,\n first_seen TEXT NOT NULL,\n last_seen TEXT NOT NULL,\n avg_duration_ms INTEGER,\n involved_services TEXT NOT NULL DEFAULT '[]'\n);\n\nCREATE TABLE IF NOT EXISTS sops (\n id TEXT PRIMARY KEY,\n workflow_id TEXT NOT NULL,\n title TEXT NOT NULL,\n description TEXT NOT NULL,\n steps TEXT NOT NULL,\n involved_systems TEXT NOT NULL DEFAULT '[]',\n estimated_duration TEXT,\n frequency TEXT,\n generated_at TEXT NOT NULL,\n confidence REAL DEFAULT 0.5\n);\n\nCREATE TABLE IF NOT EXISTS node_approvals (\n pattern TEXT PRIMARY KEY,\n action TEXT NOT NULL CHECK (action IN ('save','ignore','auto')),\n created_at TEXT NOT NULL\n);\n\nCREATE INDEX IF NOT EXISTS idx_nodes_session ON nodes(session_id);\nCREATE INDEX IF NOT EXISTS idx_edges_session ON edges(session_id);\nCREATE INDEX IF NOT EXISTS idx_events_session ON activity_events(session_id);\nCREATE INDEX IF NOT EXISTS idx_events_task ON activity_events(task_id);\nCREATE INDEX IF NOT EXISTS idx_tasks_session ON tasks(session_id);\n`;\n\nexport class CartographyDB {\n private db: Database.Database;\n\n constructor(dbPath: string) {\n mkdirSync(dirname(dbPath), { recursive: true });\n this.db = new Database(dbPath);\n this.db.pragma('journal_mode = WAL');\n this.db.pragma('foreign_keys = ON');\n this.db.pragma('busy_timeout = 5000');\n this.migrate();\n }\n\n private migrate(): void {\n const version = (this.db.pragma('user_version', { simple: true }) as number);\n if (version === 0) {\n this.db.exec(SCHEMA);\n this.db.pragma('user_version = 1');\n }\n }\n\n close(): void {\n this.db.pragma('optimize');\n this.db.close();\n }\n\n // ── Sessions ────────────────────────────\n\n createSession(mode: 'discover' | 'shadow', config: CartographyConfig): string {\n const id = crypto.randomUUID();\n this.db.prepare(\n 'INSERT INTO sessions (id, mode, started_at, config) VALUES (?, ?, ?, ?)'\n ).run(id, mode, new Date().toISOString(), JSON.stringify(config));\n return id;\n }\n\n endSession(id: string): void {\n this.db.prepare('UPDATE sessions SET completed_at = ? WHERE id = ?')\n .run(new Date().toISOString(), id);\n }\n\n getSession(id: string): SessionRow | undefined {\n const row = this.db.prepare('SELECT * FROM sessions WHERE id = ?').get(id) as Record<string, unknown> | undefined;\n return row ? this.mapSession(row) : undefined;\n }\n\n getLatestSession(mode?: string): SessionRow | undefined {\n const row = mode\n ? this.db.prepare('SELECT * FROM sessions WHERE mode = ? ORDER BY rowid DESC LIMIT 1').get(mode) as Record<string, unknown> | undefined\n : this.db.prepare('SELECT * FROM sessions ORDER BY rowid DESC LIMIT 1').get() as Record<string, unknown> | undefined;\n return row ? this.mapSession(row) : undefined;\n }\n\n getSessions(): SessionRow[] {\n const rows = this.db.prepare('SELECT * FROM sessions ORDER BY rowid DESC').all() as Record<string, unknown>[];\n return rows.map(r => this.mapSession(r));\n }\n\n private mapSession(r: Record<string, unknown>): SessionRow {\n return {\n id: r['id'] as string,\n mode: r['mode'] as 'discover' | 'shadow',\n startedAt: r['started_at'] as string,\n completedAt: (r['completed_at'] as string | null) ?? undefined,\n config: r['config'] as string,\n };\n }\n\n // ── Nodes ───────────────────────────────\n\n upsertNode(sessionId: string, node: DiscoveryNode, depth = 0): void {\n this.db.prepare(`\n INSERT OR REPLACE INTO nodes\n (id, session_id, type, name, discovered_via, discovered_at, depth, confidence, metadata, tags)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).run(\n node.id, sessionId, node.type, node.name, node.discoveredVia,\n new Date().toISOString(), depth, node.confidence,\n JSON.stringify(node.metadata ?? {}),\n JSON.stringify(node.tags ?? []),\n );\n }\n\n getNodes(sessionId: string): NodeRow[] {\n const rows = this.db.prepare('SELECT * FROM nodes WHERE session_id = ?').all(sessionId) as Record<string, unknown>[];\n return rows.map(r => ({\n id: r['id'] as string,\n sessionId: r['session_id'] as string,\n type: r['type'] as NodeRow['type'],\n name: r['name'] as string,\n discoveredVia: r['discovered_via'] as string,\n discoveredAt: r['discovered_at'] as string,\n depth: r['depth'] as number,\n confidence: r['confidence'] as number,\n metadata: JSON.parse(r['metadata'] as string) as Record<string, unknown>,\n tags: JSON.parse(r['tags'] as string) as string[],\n pathId: r['path_id'] as string | undefined,\n }));\n }\n\n // ── Edges ───────────────────────────────\n\n insertEdge(sessionId: string, edge: DiscoveryEdge): void {\n const id = crypto.randomUUID();\n this.db.prepare(`\n INSERT OR IGNORE INTO edges\n (id, session_id, source_id, target_id, relationship, evidence, confidence, discovered_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n `).run(\n id, sessionId, edge.sourceId, edge.targetId,\n edge.relationship, edge.evidence, edge.confidence,\n new Date().toISOString(),\n );\n }\n\n getEdges(sessionId: string): EdgeRow[] {\n const rows = this.db.prepare('SELECT * FROM edges WHERE session_id = ?').all(sessionId) as Record<string, unknown>[];\n return rows.map(r => ({\n id: r['id'] as string,\n sessionId: r['session_id'] as string,\n sourceId: r['source_id'] as string,\n targetId: r['target_id'] as string,\n relationship: r['relationship'] as EdgeRow['relationship'],\n evidence: r['evidence'] as string,\n confidence: r['confidence'] as number,\n discoveredAt: r['discovered_at'] as string,\n }));\n }\n\n // ── Events ──────────────────────────────\n\n insertEvent(sessionId: string, event: ActivityEvent, taskId?: string): void {\n const id = crypto.randomUUID();\n this.db.prepare(`\n INSERT INTO activity_events\n (id, session_id, task_id, timestamp, event_type, process, pid, target, target_type, port)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).run(\n id, sessionId, taskId ?? null, new Date().toISOString(),\n event.eventType, event.process, event.pid,\n event.target ?? null, event.targetType ?? null, event.port ?? null,\n );\n }\n\n getEvents(sessionId: string, since?: string): EventRow[] {\n const rows = since\n ? this.db.prepare('SELECT * FROM activity_events WHERE session_id = ? AND timestamp > ? ORDER BY timestamp').all(sessionId, since) as Record<string, unknown>[]\n : this.db.prepare('SELECT * FROM activity_events WHERE session_id = ? ORDER BY timestamp').all(sessionId) as Record<string, unknown>[];\n return rows.map(r => ({\n id: r['id'] as string,\n sessionId: r['session_id'] as string,\n taskId: r['task_id'] as string | undefined,\n timestamp: r['timestamp'] as string,\n eventType: r['event_type'] as EventRow['eventType'],\n process: r['process'] as string,\n pid: r['pid'] as number,\n target: r['target'] as string | undefined,\n targetType: r['target_type'] as EventRow['targetType'],\n port: r['port'] as number | undefined,\n durationMs: r['duration_ms'] as number | undefined,\n }));\n }\n\n // ── Tasks ───────────────────────────────\n\n startTask(sessionId: string, description?: string): string {\n const id = crypto.randomUUID();\n this.db.prepare(`\n INSERT INTO tasks (id, session_id, description, started_at, steps, involved_services, status)\n VALUES (?, ?, ?, ?, '[]', '[]', 'active')\n `).run(id, sessionId, description ?? null, new Date().toISOString());\n return id;\n }\n\n endCurrentTask(sessionId: string): void {\n this.db.prepare(`\n UPDATE tasks SET status = 'completed', completed_at = ?\n WHERE session_id = ? AND status = 'active'\n `).run(new Date().toISOString(), sessionId);\n }\n\n updateTaskDescription(sessionId: string, description: string): void {\n this.db.prepare(`\n UPDATE tasks SET description = ?\n WHERE session_id = ? AND status = 'active'\n `).run(description, sessionId);\n }\n\n getActiveTask(sessionId: string): TaskRow | undefined {\n const row = this.db.prepare(\n \"SELECT * FROM tasks WHERE session_id = ? AND status = 'active' LIMIT 1\"\n ).get(sessionId) as Record<string, unknown> | undefined;\n return row ? this.mapTask(row) : undefined;\n }\n\n getTasks(sessionId: string): TaskRow[] {\n const rows = this.db.prepare('SELECT * FROM tasks WHERE session_id = ? ORDER BY started_at').all(sessionId) as Record<string, unknown>[];\n return rows.map(r => this.mapTask(r));\n }\n\n private mapTask(r: Record<string, unknown>): TaskRow {\n return {\n id: r['id'] as string,\n sessionId: r['session_id'] as string,\n description: r['description'] as string | undefined,\n startedAt: r['started_at'] as string,\n completedAt: r['completed_at'] as string | undefined,\n steps: r['steps'] as string,\n involvedServices: r['involved_services'] as string,\n status: r['status'] as TaskRow['status'],\n isSOPCandidate: Boolean(r['is_sop_candidate']),\n };\n }\n\n // ── Workflows ───────────────────────────\n\n insertWorkflow(sessionId: string, data: Omit<WorkflowRow, 'id'>): void {\n const id = crypto.randomUUID();\n this.db.prepare(`\n INSERT INTO workflows\n (id, session_id, name, pattern, task_ids, occurrences,\n first_seen, last_seen, avg_duration_ms, involved_services)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).run(\n id, sessionId, data.name ?? null, data.pattern,\n data.taskIds, data.occurrences,\n data.firstSeen, data.lastSeen, data.avgDurationMs,\n data.involvedServices,\n );\n }\n\n getWorkflows(sessionId: string): WorkflowRow[] {\n const rows = this.db.prepare('SELECT * FROM workflows WHERE session_id = ?').all(sessionId) as Record<string, unknown>[];\n return rows.map(r => ({\n id: r['id'] as string,\n sessionId: r['session_id'] as string,\n name: r['name'] as string | undefined,\n pattern: r['pattern'] as string,\n taskIds: r['task_ids'] as string,\n occurrences: r['occurrences'] as number,\n firstSeen: r['first_seen'] as string,\n lastSeen: r['last_seen'] as string,\n avgDurationMs: r['avg_duration_ms'] as number,\n involvedServices: r['involved_services'] as string,\n }));\n }\n\n // ── SOPs ────────────────────────────────\n\n insertSOP(sop: { workflowId: string } & SOP): void {\n const id = crypto.randomUUID();\n this.db.prepare(`\n INSERT INTO sops\n (id, workflow_id, title, description, steps, involved_systems,\n estimated_duration, frequency, generated_at, confidence)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).run(\n id, sop.workflowId, sop.title, sop.description,\n JSON.stringify(sop.steps),\n JSON.stringify(sop.involvedSystems),\n sop.estimatedDuration, sop.frequency,\n new Date().toISOString(), sop.confidence,\n );\n }\n\n getSOPs(sessionId: string): Array<SOP & { id: string; workflowId: string }> {\n const rows = this.db.prepare(`\n SELECT s.* FROM sops s\n JOIN workflows w ON s.workflow_id = w.id\n WHERE w.session_id = ?\n `).all(sessionId) as Record<string, unknown>[];\n return rows.map(r => ({\n id: r['id'] as string,\n workflowId: r['workflow_id'] as string,\n title: r['title'] as string,\n description: r['description'] as string,\n steps: JSON.parse(r['steps'] as string) as SOP['steps'],\n involvedSystems: JSON.parse(r['involved_systems'] as string) as string[],\n estimatedDuration: r['estimated_duration'] as string,\n frequency: r['frequency'] as string,\n confidence: r['confidence'] as number,\n }));\n }\n\n // ── Approvals ───────────────────────────\n\n setApproval(pattern: string, action: 'save' | 'ignore' | 'auto'): void {\n this.db.prepare(`\n INSERT OR REPLACE INTO node_approvals (pattern, action, created_at) VALUES (?, ?, ?)\n `).run(pattern, action, new Date().toISOString());\n }\n\n getApproval(pattern: string): string | undefined {\n const row = this.db.prepare('SELECT action FROM node_approvals WHERE pattern = ?').get(pattern) as { action: string } | undefined;\n return row?.action;\n }\n\n // ── Stats ───────────────────────────────\n\n getStats(sessionId: string): { nodes: number; edges: number; events: number; tasks: number } {\n const nodes = (this.db.prepare('SELECT COUNT(*) as c FROM nodes WHERE session_id = ?').get(sessionId) as { c: number }).c;\n const edges = (this.db.prepare('SELECT COUNT(*) as c FROM edges WHERE session_id = ?').get(sessionId) as { c: number }).c;\n const events = (this.db.prepare('SELECT COUNT(*) as c FROM activity_events WHERE session_id = ?').get(sessionId) as { c: number }).c;\n const tasks = (this.db.prepare('SELECT COUNT(*) as c FROM tasks WHERE session_id = ?').get(sessionId) as { c: number }).c;\n return { nodes, edges, events, tasks };\n }\n}\n","import { z } from 'zod';\nimport type { CartographyDB } from './db.js';\nimport { NODE_TYPES, EDGE_RELATIONSHIPS, EVENT_TYPES, SOPStepSchema } from './types.js';\n\n// Lazy import to avoid hard-wiring SDK at module parse time\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype McpServer = any;\n\nexport function stripSensitive(target: string): string {\n try {\n const url = new URL(target.startsWith('http') ? target : `tcp://${target}`);\n return `${url.hostname}${url.port ? ':' + url.port : ''}`;\n } catch {\n return target\n .replace(/\\/.*$/, '')\n .replace(/\\?.*$/, '')\n .replace(/@.*:/, ':');\n }\n}\n\nexport async function createCartographyTools(db: CartographyDB, sessionId: string): Promise<McpServer> {\n // Dynamically import the SDK so missing package doesn't crash at load time\n const sdk = await import('@anthropic-ai/claude-code');\n const { tool, createSdkMcpServer } = sdk as {\n tool: (name: string, description: string, schema: z.ZodRawShape, handler: (args: Record<string, unknown>) => Promise<{ content: Array<{ type: string; text: string }> }>) => unknown;\n createSdkMcpServer: (opts: { name: string; version: string; tools: unknown[] }) => McpServer;\n };\n\n const tools = [\n tool('save_node', 'Infrastructure-Node speichern', {\n id: z.string(),\n type: z.enum(NODE_TYPES),\n name: z.string(),\n discoveredVia: z.string(),\n confidence: z.number().min(0).max(1),\n metadata: z.record(z.unknown()).optional(),\n tags: z.array(z.string()).optional(),\n }, async (args) => {\n const node = {\n id: stripSensitive(args['id'] as string),\n type: args['type'] as typeof NODE_TYPES[number],\n name: args['name'] as string,\n discoveredVia: args['discoveredVia'] as string,\n confidence: args['confidence'] as number,\n metadata: (args['metadata'] as Record<string, unknown>) ?? {},\n tags: (args['tags'] as string[]) ?? [],\n };\n db.upsertNode(sessionId, node);\n return { content: [{ type: 'text', text: `✓ Node: ${node.id}` }] };\n }),\n\n tool('save_edge', 'Verbindung zwischen zwei Nodes speichern', {\n sourceId: z.string(),\n targetId: z.string(),\n relationship: z.enum(EDGE_RELATIONSHIPS),\n evidence: z.string(),\n confidence: z.number().min(0).max(1),\n }, async (args) => {\n db.insertEdge(sessionId, {\n sourceId: args['sourceId'] as string,\n targetId: args['targetId'] as string,\n relationship: args['relationship'] as typeof EDGE_RELATIONSHIPS[number],\n evidence: args['evidence'] as string,\n confidence: args['confidence'] as number,\n });\n return { content: [{ type: 'text', text: `✓ ${args['sourceId']}→${args['targetId']}` }] };\n }),\n\n tool('save_event', 'Activity-Event (Prozess/Verbindung) speichern', {\n eventType: z.enum(EVENT_TYPES),\n process: z.string(),\n pid: z.number(),\n target: z.string().optional(),\n targetType: z.enum(NODE_TYPES).optional(),\n port: z.number().optional(),\n }, async (args) => {\n db.insertEvent(sessionId, {\n eventType: args['eventType'] as typeof EVENT_TYPES[number],\n process: args['process'] as string,\n pid: args['pid'] as number,\n target: args['target'] ? stripSensitive(args['target'] as string) : undefined,\n targetType: args['targetType'] as typeof NODE_TYPES[number] | undefined,\n port: args['port'] as number | undefined,\n });\n return { content: [{ type: 'text', text: `✓ ${args['eventType']}` }] };\n }),\n\n tool('get_catalog', 'Aktuellen Katalog abrufen (Duplikat-Check)', {\n includeEdges: z.boolean().default(true),\n }, async (args) => {\n const nodes = db.getNodes(sessionId);\n const edges = (args['includeEdges'] as boolean) ? db.getEdges(sessionId) : [];\n return {\n content: [{\n type: 'text',\n text: JSON.stringify({\n count: { nodes: nodes.length, edges: edges.length },\n nodeIds: nodes.map(n => n.id),\n }),\n }],\n };\n }),\n\n tool('manage_task', 'Task starten, beenden oder beschreiben', {\n action: z.enum(['start', 'end', 'describe']),\n description: z.string().optional(),\n }, async (args) => {\n const action = args['action'] as string;\n if (action === 'start') {\n const id = db.startTask(sessionId, args['description'] as string | undefined);\n return { content: [{ type: 'text', text: `✓ Task gestartet: ${id}` }] };\n }\n if (action === 'end') {\n db.endCurrentTask(sessionId);\n return { content: [{ type: 'text', text: '✓ Task beendet' }] };\n }\n db.updateTaskDescription(sessionId, args['description'] as string);\n return { content: [{ type: 'text', text: '✓ Beschreibung aktualisiert' }] };\n }),\n\n tool('save_sop', 'Standard Operating Procedure speichern', {\n workflowId: z.string(),\n title: z.string(),\n description: z.string(),\n steps: z.array(SOPStepSchema),\n involvedSystems: z.array(z.string()),\n estimatedDuration: z.string(),\n frequency: z.string(),\n confidence: z.number().min(0).max(1),\n }, async (args) => {\n db.insertSOP({\n workflowId: args['workflowId'] as string,\n title: args['title'] as string,\n description: args['description'] as string,\n steps: args['steps'] as ReturnType<typeof SOPStepSchema.parse>[],\n involvedSystems: args['involvedSystems'] as string[],\n estimatedDuration: args['estimatedDuration'] as string,\n frequency: args['frequency'] as string,\n confidence: args['confidence'] as number,\n });\n return { content: [{ type: 'text', text: `✓ SOP: ${args['title']}` }] };\n }),\n ];\n\n return createSdkMcpServer({\n name: 'cartography',\n version: '0.1.0',\n tools,\n });\n}\n","// PreToolUse Safety Hook — enforces read-only policy on all Bash calls\n\nimport type { HookCallback } from '@anthropic-ai/claude-code';\n\n// Word-boundary matched dangerous commands\nconst BLOCKED_CMDS =\n /\\b(rm|mv|cp|dd|mkfs|chmod|chown|chgrp|kill|killall|pkill|reboot|shutdown|poweroff|halt|systemctl\\s+(start|stop|restart|enable|disable)|service\\s+(start|stop|restart)|docker\\s+(rm|rmi|stop|kill|exec|run|build|push)|kubectl\\s+(delete|apply|edit|exec|run|create|patch)|apt|yum|dnf|pacman|pip\\s+install|npm\\s+(install|uninstall)|curl\\s+.*-X\\s*(POST|PUT|DELETE|PATCH)|wget\\s+-O|tee\\s)\\b/i;\n// Redirect operators (no word boundary needed)\nconst BLOCKED_REDIRECTS = />>|>[^>]/;\n\nexport type { HookCallback };\n\nexport const safetyHook: HookCallback = async (input) => {\n // Only intercept PreToolUse events (other hook events don't have tool_name)\n if (!('tool_name' in input)) return {};\n if ((input as { tool_name: string }).tool_name !== 'Bash') return {};\n\n const cmd = ((input as { tool_input: { command?: string } }).tool_input)?.command ?? '';\n\n if (BLOCKED_CMDS.test(cmd) || BLOCKED_REDIRECTS.test(cmd)) {\n return {\n hookSpecificOutput: {\n hookEventName: 'PreToolUse',\n permissionDecision: 'deny',\n permissionDecisionReason: `BLOCKED: \"${cmd}\" — read-only policy`,\n },\n };\n }\n\n return {\n hookSpecificOutput: {\n hookEventName: 'PreToolUse',\n permissionDecision: 'allow',\n },\n };\n};\n","import type { CartographyDB } from './db.js';\nimport { createCartographyTools } from './tools.js';\nimport { safetyHook } from './safety.js';\nimport type { CartographyConfig, TaskRow } from './types.js';\n\n// ── runDiscovery ─────────────────────────────────────────────────────────────\n\nexport async function runDiscovery(\n config: CartographyConfig,\n db: CartographyDB,\n sessionId: string,\n onOutput?: (text: string) => void,\n): Promise<void> {\n const { query } = await import('@anthropic-ai/claude-code');\n const tools = await createCartographyTools(db, sessionId);\n\n const systemPrompt = `Du bist ein Infrastruktur-Discovery-Agent.\nKartographiere die gesamte Systemlandschaft.\n\nSTRATEGIE:\n1. ss -tlnp + ps aux → Überblick\n2. Jeden Service tiefer (Datenbanken→Tabellen, APIs→Endpoints, Queues→Topics)\n3. save_node + save_edge für alles. get_catalog → keine Duplikate.\n4. Config-Files folgen: .env (nur Host:Port!), docker-compose.yml, application.yml\n5. Backtrack wenn Spur erschöpft. Stop wenn alles explored.\n\nPORT-MAPPING: 5432=postgres, 3306=mysql, 27017=mongodb, 6379=redis,\n9092=kafka, 5672=rabbitmq, 80/443/8080/3000=web_service,\n9090=prometheus, 8500=consul, 8200=vault, 2379=etcd\n\nREGELN:\n- NUR read-only Commands (ss, ps, cat, head, curl -s, docker inspect, kubectl get)\n- Targets NUR Host:Port — KEINE URLs, Pfade, Credentials\n- Node IDs: \"{type}:{host}:{port}\" oder \"{type}:{name}\"\n- Confidence: 0.9 direkt beobachtet, 0.7 aus Config, 0.5 Vermutung\n- KEINE Credentials speichern\n\nEntrypoints: ${config.entryPoints.join(', ')}`;\n\n for await (const msg of query({\n prompt: systemPrompt,\n options: {\n model: config.agentModel,\n maxTurns: config.maxTurns,\n customSystemPrompt: systemPrompt,\n mcpServers: { cartography: tools },\n allowedTools: [\n 'Bash',\n 'mcp__cartograph__save_node',\n 'mcp__cartograph__save_edge',\n 'mcp__cartograph__get_catalog',\n ],\n hooks: {\n PreToolUse: [{ matcher: 'Bash', hooks: [safetyHook] }],\n },\n permissionMode: 'bypassPermissions',\n },\n })) {\n if (msg.type === 'assistant' && onOutput) {\n for (const block of msg.message.content) {\n if (block.type === 'text') {\n onOutput(block.text);\n }\n }\n }\n if (msg.type === 'result') return;\n }\n}\n\n// ── runShadowCycle ───────────────────────────────────────────────────────────\n\nexport async function runShadowCycle(\n config: CartographyConfig,\n db: CartographyDB,\n sessionId: string,\n prevSnapshot: string,\n currSnapshot: string,\n onOutput?: (msg: unknown) => void,\n): Promise<void> {\n const { query } = await import('@anthropic-ai/claude-code');\n const tools = await createCartographyTools(db, sessionId);\n\n const prompt = `Analysiere den Diff zwischen diesen beiden System-Snapshots.\nFinde:\n- Neue/geschlossene TCP-Verbindungen → save_event\n- Neue/beendete Prozesse → save_event\n- Bisher unbekannte Services → get_catalog prüfen, dann save_node\n- Task-Grenzen (Inaktivität, Tool-Wechsel) → manage_task\ntarget = NUR Host:Port. Kurz und effizient.\n\n=== VORHER ===\n${prevSnapshot}\n\n=== JETZT ===\n${currSnapshot}`;\n\n for await (const msg of query({\n prompt,\n options: {\n model: config.shadowModel,\n maxTurns: 5,\n mcpServers: { cartography: tools },\n allowedTools: [\n 'mcp__cartograph__save_event',\n 'mcp__cartograph__save_node',\n 'mcp__cartograph__save_edge',\n 'mcp__cartograph__get_catalog',\n 'mcp__cartograph__manage_task',\n ],\n permissionMode: 'bypassPermissions',\n },\n })) {\n if (onOutput) onOutput(msg);\n }\n}\n\n// ── generateSOPs ─────────────────────────────────────────────────────────────\n\nexport async function generateSOPs(db: CartographyDB, sessionId: string): Promise<number> {\n const Anthropic = (await import('@anthropic-ai/sdk')).default;\n const client = new Anthropic();\n\n const tasks = db.getTasks(sessionId).filter(t => t.status === 'completed');\n if (tasks.length === 0) return 0;\n\n // Cluster tasks by involved services\n const clusters = clusterTasks(tasks);\n let generated = 0;\n\n for (const cluster of clusters) {\n const workflowId = crypto.randomUUID();\n const involved = JSON.parse(cluster[0]?.involvedServices ?? '[]') as string[];\n\n const taskDescriptions = cluster\n .map((t, i) => `Task ${i + 1}: ${t.description ?? 'Unnamed'}\\nSteps: ${t.steps}`)\n .join('\\n\\n');\n\n const response = await client.messages.create({\n model: 'claude-sonnet-4-5-20250929',\n max_tokens: 2048,\n messages: [{\n role: 'user',\n content: `Generiere eine SOP (Standard Operating Procedure) für diesen wiederkehrenden Workflow.\nAntworte NUR mit validen JSON im Format:\n{\n \"title\": \"...\",\n \"description\": \"...\",\n \"steps\": [{\"order\": 1, \"instruction\": \"...\", \"tool\": \"...\", \"target\": \"...\", \"notes\": \"...\"}],\n \"involvedSystems\": [\"...\"],\n \"estimatedDuration\": \"~N Minuten\",\n \"frequency\": \"Xmal täglich\",\n \"confidence\": 0.8\n}\n\nTasks:\n${taskDescriptions}\n\nBeteiligte Services: ${involved.join(', ')}`,\n }],\n });\n\n const text = response.content[0]?.type === 'text' ? response.content[0].text : '';\n\n try {\n const jsonMatch = text.match(/\\{[\\s\\S]*\\}/);\n if (!jsonMatch) continue;\n const parsed = JSON.parse(jsonMatch[0]) as {\n title: string;\n description: string;\n steps: Array<{ order: number; instruction: string; tool: string; target?: string; notes?: string }>;\n involvedSystems: string[];\n estimatedDuration: string;\n frequency: string;\n confidence: number;\n };\n\n db.insertSOP({ workflowId, ...parsed });\n generated++;\n } catch {\n // Skip malformed responses\n }\n }\n\n return generated;\n}\n\nfunction clusterTasks(tasks: TaskRow[]): TaskRow[][] {\n // Simple clustering: group by overlapping involved services\n const clusters: TaskRow[][] = [];\n const assigned = new Set<string>();\n\n for (const task of tasks) {\n if (assigned.has(task.id)) continue;\n\n const cluster = [task];\n assigned.add(task.id);\n\n const taskServices = new Set(JSON.parse(task.involvedServices ?? '[]') as string[]);\n\n for (const other of tasks) {\n if (assigned.has(other.id)) continue;\n const otherServices = new Set(JSON.parse(other.involvedServices ?? '[]') as string[]);\n // Check overlap\n const overlap = [...taskServices].filter(s => otherServices.has(s));\n if (overlap.length > 0) {\n cluster.push(other);\n assigned.add(other.id);\n }\n }\n\n clusters.push(cluster);\n }\n\n return clusters;\n}\n","import { mkdirSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { CartographyDB } from './db.js';\nimport type { NodeRow, EdgeRow, SOP } from './types.js';\n\n// ── Icons & Labels ───────────────────────────────────────────────────────────\n\nconst MERMAID_ICONS: Record<string, string> = {\n host: '🖥️',\n database_server: '🗄️',\n database: '🗄️',\n table: '📋',\n web_service: '🌐',\n api_endpoint: '🔌',\n cache_server: '⚡',\n message_broker: '📨',\n queue: '📬',\n topic: '📢',\n container: '📦',\n pod: '☸️',\n k8s_cluster: '☸️',\n config_file: '📄',\n unknown: '❓',\n};\n\nconst EDGE_LABELS: Record<string, string> = {\n connects_to: '',\n reads_from: 'reads',\n writes_to: 'writes',\n calls: 'calls',\n contains: 'contains',\n depends_on: 'depends',\n};\n\n// ── Mermaid ──────────────────────────────────────────────────────────────────\n\nfunction sanitize(id: string): string {\n return id.replace(/[^a-zA-Z0-9_]/g, '_');\n}\n\nfunction groupByParent(nodes: NodeRow[]): Map<string, NodeRow[]> {\n const groups = new Map<string, NodeRow[]>();\n for (const node of nodes) {\n // Group by host portion of id or by type\n const group = node.id.split(':')[1] ?? node.type;\n if (!groups.has(group)) groups.set(group, []);\n groups.get(group)!.push(node);\n }\n return groups;\n}\n\nexport function generateTopologyMermaid(nodes: NodeRow[], edges: EdgeRow[]): string {\n const lines: string[] = ['graph TB'];\n const groups = groupByParent(nodes);\n\n for (const [group, groupNodes] of groups) {\n if (groups.size > 1) {\n lines.push(` subgraph ${sanitize(group)}`);\n }\n for (const node of groupNodes) {\n const icon = MERMAID_ICONS[node.type] ?? '❓';\n lines.push(` ${sanitize(node.id)}[\"${icon} ${node.name}\"]`);\n }\n if (groups.size > 1) {\n lines.push(' end');\n }\n }\n\n for (const edge of edges) {\n const label = EDGE_LABELS[edge.relationship] ?? '';\n const arrow = label ? `-->|\"${label}\"|` : '-->';\n lines.push(` ${sanitize(edge.sourceId)} ${arrow} ${sanitize(edge.targetId)}`);\n }\n\n return lines.join('\\n');\n}\n\nexport function generateDependencyMermaid(nodes: NodeRow[], edges: EdgeRow[]): string {\n const lines: string[] = ['graph LR'];\n\n const depEdges = edges.filter(e =>\n ['calls', 'reads_from', 'writes_to', 'depends_on'].includes(e.relationship)\n );\n\n const usedIds = new Set<string>();\n for (const edge of depEdges) {\n usedIds.add(edge.sourceId);\n usedIds.add(edge.targetId);\n }\n\n const usedNodes = nodes.filter(n => usedIds.has(n.id));\n for (const node of usedNodes) {\n const icon = MERMAID_ICONS[node.type] ?? '❓';\n lines.push(` ${sanitize(node.id)}[\"${icon} ${node.name}\"]`);\n }\n\n for (const edge of depEdges) {\n const label = EDGE_LABELS[edge.relationship] ?? '';\n const arrow = label ? `-->|\"${label}\"|` : '-->';\n lines.push(` ${sanitize(edge.sourceId)} ${arrow} ${sanitize(edge.targetId)}`);\n }\n\n return lines.join('\\n');\n}\n\nexport function generateWorkflowMermaid(sop: SOP): string {\n const lines: string[] = ['flowchart TD'];\n\n for (const step of sop.steps) {\n const nodeId = `S${step.order}`;\n const label = `${step.order}. ${step.instruction.substring(0, 60)}`;\n lines.push(` ${nodeId}[\"${label}\"]`);\n\n if (step.order > 1) {\n lines.push(` S${step.order - 1} --> ${nodeId}`);\n }\n }\n\n return lines.join('\\n');\n}\n\n// ── Backstage YAML ───────────────────────────────────────────────────────────\n\nexport function exportBackstageYAML(nodes: NodeRow[], edges: EdgeRow[], org?: string): string {\n const owner = org ?? 'unknown';\n const docs: string[] = [];\n\n for (const node of nodes) {\n const isComponent = ['web_service', 'container', 'pod'].includes(node.type);\n const isAPI = node.type === 'api_endpoint';\n const kind = isComponent ? 'Component' : isAPI ? 'API' : 'Resource';\n\n const deps = edges\n .filter(e => e.sourceId === node.id)\n .map(e => ` - resource:default/${sanitize(e.targetId)}`);\n\n const doc = [\n `apiVersion: backstage.io/v1alpha1`,\n `kind: ${kind}`,\n `metadata:`,\n ` name: ${sanitize(node.id)}`,\n ` annotations:`,\n ` cartography/discovered-at: \"${node.discoveredAt}\"`,\n ` cartography/confidence: \"${node.confidence}\"`,\n `spec:`,\n ` type: ${node.type}`,\n ` lifecycle: production`,\n ` owner: ${owner}`,\n ...(deps.length > 0 ? [' dependsOn:', ...deps] : []),\n ].join('\\n');\n\n docs.push(doc);\n }\n\n return docs.join('\\n---\\n');\n}\n\n// ── JSON ─────────────────────────────────────────────────────────────────────\n\nexport function exportJSON(db: CartographyDB, sessionId: string): string {\n const nodes = db.getNodes(sessionId);\n const edges = db.getEdges(sessionId);\n const events = db.getEvents(sessionId);\n const tasks = db.getTasks(sessionId);\n const sops = db.getSOPs(sessionId);\n const stats = db.getStats(sessionId);\n\n return JSON.stringify({\n sessionId,\n exportedAt: new Date().toISOString(),\n stats,\n nodes,\n edges,\n events,\n tasks,\n sops,\n }, null, 2);\n}\n\n// ── HTML (D3.js Force-Graph) ──────────────────────────────────────────────────\n\nexport function exportHTML(nodes: NodeRow[], edges: EdgeRow[]): string {\n const graphData = JSON.stringify({\n nodes: nodes.map(n => ({ id: n.id, name: n.name, type: n.type, confidence: n.confidence })),\n links: edges.map(e => ({ source: e.sourceId, target: e.targetId, relationship: e.relationship })),\n });\n\n return `<!DOCTYPE html>\n<html lang=\"de\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Cartography — Topology</title>\n <script src=\"https://d3js.org/d3.v7.min.js\"></script>\n <style>\n body { margin: 0; background: #1a1a2e; color: #eee; font-family: monospace; }\n svg { width: 100vw; height: 100vh; }\n .node circle { stroke: #fff; stroke-width: 1.5px; }\n .node text { font-size: 10px; fill: #eee; }\n .link { stroke: #666; stroke-opacity: 0.6; }\n #info { position: fixed; top: 10px; right: 10px; background: rgba(0,0,0,0.7);\n padding: 10px; border-radius: 4px; font-size: 12px; }\n </style>\n</head>\n<body>\n<div id=\"info\">\n <strong>Cartography</strong><br>\n Nodes: ${nodes.length} | Edges: ${edges.length}<br>\n <small>Drag to explore</small>\n</div>\n<svg></svg>\n<script>\nconst data = ${graphData};\n\nconst TYPE_COLORS = {\n host: '#4a9eff', database_server: '#ff6b6b', database: '#ff8c42',\n web_service: '#6bcb77', api_endpoint: '#4d96ff', cache_server: '#ffd93d',\n message_broker: '#c77dff', queue: '#e0aaff', topic: '#9d4edd',\n container: '#48cae4', pod: '#00b4d8', k8s_cluster: '#0077b6',\n config_file: '#adb5bd', unknown: '#6c757d',\n};\n\nconst svg = d3.select('svg');\nconst width = window.innerWidth, height = window.innerHeight;\nconst g = svg.append('g');\n\nsvg.call(d3.zoom().on('zoom', e => g.attr('transform', e.transform)));\n\nconst sim = d3.forceSimulation(data.nodes)\n .force('link', d3.forceLink(data.links).id(d => d.id).distance(100))\n .force('charge', d3.forceManyBody().strength(-200))\n .force('center', d3.forceCenter(width / 2, height / 2));\n\nconst link = g.append('g').selectAll('line')\n .data(data.links).join('line').attr('class', 'link');\n\nconst node = g.append('g').selectAll('g')\n .data(data.nodes).join('g').attr('class', 'node')\n .call(d3.drag()\n .on('start', (e, d) => { if (!e.active) sim.alphaTarget(0.3).restart(); d.fx = d.x; d.fy = d.y; })\n .on('drag', (e, d) => { d.fx = e.x; d.fy = e.y; })\n .on('end', (e, d) => { if (!e.active) sim.alphaTarget(0); d.fx = null; d.fy = null; })\n );\n\nnode.append('circle').attr('r', 8).attr('fill', d => TYPE_COLORS[d.type] || '#aaa');\nnode.append('text').attr('dx', 12).attr('dy', '.35em').text(d => d.name);\nnode.append('title').text(d => \\`\\${d.type}: \\${d.id}\\nConfidence: \\${d.confidence}\\`);\n\nsim.on('tick', () => {\n link.attr('x1', d => d.source.x).attr('y1', d => d.source.y)\n .attr('x2', d => d.target.x).attr('y2', d => d.target.y);\n node.attr('transform', d => \\`translate(\\${d.x},\\${d.y})\\`);\n});\n</script>\n</body>\n</html>`;\n}\n\n// ── SOP Markdown ─────────────────────────────────────────────────────────────\n\nexport function exportSOPMarkdown(sop: SOP): string {\n const lines: string[] = [\n `# ${sop.title}`,\n '',\n `**Beschreibung:** ${sop.description}`,\n `**Systeme:** ${sop.involvedSystems.join(', ')}`,\n `**Dauer:** ${sop.estimatedDuration}`,\n `**Häufigkeit:** ${sop.frequency}`,\n `**Confidence:** ${sop.confidence.toFixed(2)}`,\n '',\n '## Schritte',\n '',\n ];\n\n for (const step of sop.steps) {\n lines.push(`${step.order}. **${step.tool}**${step.target ? ` → \\`${step.target}\\`` : ''}`);\n lines.push(` ${step.instruction}`);\n if (step.notes) lines.push(` _${step.notes}_`);\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\n// ── exportAll ─────────────────────────────────────────────────────────────────\n\nexport function exportAll(\n db: CartographyDB,\n sessionId: string,\n outputDir: string,\n formats: string[] = ['mermaid', 'json', 'yaml', 'html', 'sops'],\n): void {\n mkdirSync(outputDir, { recursive: true });\n mkdirSync(join(outputDir, 'sops'), { recursive: true });\n mkdirSync(join(outputDir, 'workflows'), { recursive: true });\n\n const nodes = db.getNodes(sessionId);\n const edges = db.getEdges(sessionId);\n\n if (formats.includes('mermaid')) {\n writeFileSync(join(outputDir, 'topology.mermaid'), generateTopologyMermaid(nodes, edges));\n writeFileSync(join(outputDir, 'dependencies.mermaid'), generateDependencyMermaid(nodes, edges));\n process.stderr.write('✓ topology.mermaid, dependencies.mermaid\\n');\n }\n\n if (formats.includes('json')) {\n writeFileSync(join(outputDir, 'catalog.json'), exportJSON(db, sessionId));\n process.stderr.write('✓ catalog.json\\n');\n }\n\n if (formats.includes('yaml')) {\n writeFileSync(join(outputDir, 'catalog-info.yaml'), exportBackstageYAML(nodes, edges));\n process.stderr.write('✓ catalog-info.yaml\\n');\n }\n\n if (formats.includes('html')) {\n writeFileSync(join(outputDir, 'topology.html'), exportHTML(nodes, edges));\n process.stderr.write('✓ topology.html\\n');\n }\n\n if (formats.includes('sops')) {\n const sops = db.getSOPs(sessionId);\n for (const sop of sops) {\n const filename = sop.title.toLowerCase().replace(/[^a-z0-9]+/g, '-') + '.md';\n writeFileSync(join(outputDir, 'sops', filename), exportSOPMarkdown(sop));\n\n const wfFilename = `workflow-${sop.workflowId.substring(0, 8)}.mermaid`;\n writeFileSync(join(outputDir, 'workflows', wfFilename), generateWorkflowMermaid(sop));\n }\n if (sops.length > 0) {\n process.stderr.write(`✓ ${sops.length} SOPs + workflow diagrams\\n`);\n }\n }\n}\n","import { execSync, spawn } from 'node:child_process';\nimport { existsSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs';\nimport { CartographyDB } from './db.js';\nimport { IPCServer, cleanStaleSocket } from './ipc.js';\nimport { NotificationService } from './notify.js';\nimport { runShadowCycle } from './agent.js';\nimport type { CartographyConfig, ShadowStatus } from './types.js';\n\n// ── Snapshot ─────────────────────────────────────────────────────────────────\n\nexport function takeSnapshot(config: CartographyConfig): string {\n const run = (cmd: string): string => {\n try {\n return execSync(cmd, { stdio: ['pipe', 'pipe', 'pipe'], timeout: 5000 }).toString();\n } catch {\n return `(${cmd}: not available)`;\n }\n };\n\n const ss = run('ss -tnp 2>/dev/null || ss -tn 2>/dev/null || echo \"ss not available\"');\n const ps = run('ps aux --sort=-start_time 2>/dev/null | head -50');\n\n let win = '';\n if (config.trackWindowFocus) {\n try {\n win = execSync('xdotool getactivewindow getwindowname 2>/dev/null', {\n stdio: ['pipe', 'pipe', 'pipe'],\n timeout: 2000,\n }).toString().trim();\n } catch {\n win = '';\n }\n }\n\n return `=== TCP ===\\n${ss}\\n=== PS ===\\n${ps}\\n=== Window ===\\n${win}`;\n}\n\n// ── ShadowDaemon ─────────────────────────────────────────────────────────────\n\nexport class ShadowDaemon {\n private running = false;\n private prevSnapshot = '';\n private cyclesRun = 0;\n private cyclesSkipped = 0;\n\n constructor(\n private config: CartographyConfig,\n private db: CartographyDB,\n private ipc: IPCServer,\n private notify: NotificationService,\n ) {}\n\n async run(): Promise<void> {\n this.running = true;\n const sessionId = this.db.createSession('shadow', this.config);\n\n process.on('SIGTERM', () => this.stop());\n process.on('SIGINT', () => this.stop());\n\n while (this.running) {\n const snapshot = takeSnapshot(this.config);\n\n if (snapshot !== this.prevSnapshot) {\n try {\n await runShadowCycle(\n this.config,\n this.db,\n sessionId,\n this.prevSnapshot,\n snapshot,\n (msg) => {\n if (this.ipc.hasClients()) {\n this.ipc.broadcast({ type: 'agent-output', text: JSON.stringify(msg) });\n }\n },\n );\n this.cyclesRun++;\n } catch (err) {\n process.stderr.write(`⚠ Cycle error: ${err}\\n`);\n }\n this.prevSnapshot = snapshot;\n } else {\n this.cyclesSkipped++;\n }\n\n // Broadcast status\n const status = this.getStatus(sessionId);\n this.ipc.broadcast({ type: 'status', data: status });\n\n // Desktop notification if no clients attached\n if (!this.ipc.hasClients()) {\n const stats = this.db.getStats(sessionId);\n if (stats.events > 0 && this.cyclesRun % 10 === 0) {\n this.notify.workflowDetected(stats.tasks, `${stats.events} events so far`);\n }\n }\n\n await sleep(this.config.pollIntervalMs);\n }\n\n this.db.endSession(sessionId);\n this.ipc.stop();\n cleanup(this.config);\n }\n\n stop(): void {\n this.running = false;\n }\n\n private getStatus(sessionId: string): ShadowStatus {\n const stats = this.db.getStats(sessionId);\n return {\n pid: process.pid,\n uptime: process.uptime(),\n nodeCount: stats.nodes,\n eventCount: stats.events,\n taskCount: stats.tasks,\n pendingPrompts: 0,\n autoSave: this.config.autoSaveNodes,\n mode: this.config.shadowMode,\n agentActive: false,\n cyclesRun: this.cyclesRun,\n cyclesSkipped: this.cyclesSkipped,\n };\n }\n}\n\n// ── Daemon Lifecycle ──────────────────────────────────────────────────────────\n\nexport function forkDaemon(config: CartographyConfig): number {\n // The daemon entry is the same cli.ts but with --daemon flag via env\n const child = spawn(\n process.execPath,\n [process.argv[1] ?? 'cartography', 'shadow', 'start', '--foreground', '--daemon-child'],\n {\n detached: true,\n stdio: 'ignore',\n env: {\n ...process.env,\n CARTOGRAPHYY_DAEMON: '1',\n CARTOGRAPHYY_CONFIG: JSON.stringify(config),\n },\n }\n );\n child.unref();\n\n const pid = child.pid;\n if (!pid) throw new Error('Failed to fork daemon');\n\n writeFileSync(config.pidFile, String(pid), 'utf8');\n return pid;\n}\n\nexport function isDaemonRunning(pidFile: string): { running: boolean; pid?: number } {\n if (!existsSync(pidFile)) return { running: false };\n\n try {\n const pid = parseInt(readFileSync(pidFile, 'utf8').trim(), 10);\n if (isNaN(pid)) return { running: false };\n\n process.kill(pid, 0); // throws if process doesn't exist\n return { running: true, pid };\n } catch {\n // Stale PID file\n try { unlinkSync(pidFile); } catch { /* already gone */ }\n return { running: false };\n }\n}\n\nexport function stopDaemon(pidFile: string): boolean {\n const { running, pid } = isDaemonRunning(pidFile);\n if (!running || !pid) return false;\n\n try {\n process.kill(pid, 'SIGTERM');\n try { unlinkSync(pidFile); } catch { /* already gone */ }\n return true;\n } catch {\n return false;\n }\n}\n\nfunction cleanup(config: CartographyConfig): void {\n try { unlinkSync(config.socketPath); } catch { /* already gone */ }\n try { unlinkSync(config.pidFile); } catch { /* already gone */ }\n}\n\n// ── startDaemonProcess ───────────────────────────────────────────────────────\n\nexport async function startDaemonProcess(config: CartographyConfig): Promise<void> {\n cleanStaleSocket(config.socketPath);\n\n const db = new CartographyDB(config.dbPath);\n const ipc = new IPCServer();\n const notify = new NotificationService(config.enableNotifications);\n\n ipc.start(config.socketPath);\n\n const daemon = new ShadowDaemon(config, db, ipc, notify);\n await daemon.run();\n\n db.close();\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n","import net from 'node:net';\nimport { EventEmitter } from 'node:events';\nimport { chmodSync, existsSync, unlinkSync } from 'node:fs';\nimport type { DaemonMessage, ClientMessage } from './types.js';\n\n// ── IPCServer ────────────────────────────────────────────────────────────────\n\nexport class IPCServer extends EventEmitter {\n private server: net.Server | null = null;\n private clients: Set<net.Socket> = new Set();\n\n start(socketPath: string): void {\n this.server = net.createServer((socket) => {\n this.clients.add(socket);\n this.emit('client-connect', socket);\n\n let buf = '';\n socket.on('data', (chunk) => {\n buf += chunk.toString();\n const lines = buf.split('\\n');\n buf = lines.pop() ?? '';\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n const msg = JSON.parse(line) as ClientMessage;\n this.emit('message', msg, socket);\n } catch {\n // Ignore malformed JSON\n }\n }\n });\n\n socket.on('close', () => {\n this.clients.delete(socket);\n this.emit('client-disconnect', socket);\n });\n\n socket.on('error', () => {\n this.clients.delete(socket);\n });\n });\n\n this.server.listen(socketPath, () => {\n try {\n chmodSync(socketPath, 0o600);\n } catch {\n // chmod may fail in some environments — non-fatal\n }\n });\n }\n\n broadcast(msg: DaemonMessage): void {\n const line = JSON.stringify(msg) + '\\n';\n for (const socket of this.clients) {\n try {\n socket.write(line);\n } catch {\n this.clients.delete(socket);\n }\n }\n }\n\n hasClients(): boolean {\n return this.clients.size > 0;\n }\n\n stop(): void {\n for (const socket of this.clients) {\n socket.destroy();\n }\n this.clients.clear();\n this.server?.close();\n this.server = null;\n }\n}\n\n// ── IPCClient ────────────────────────────────────────────────────────────────\n\nexport class IPCClient extends EventEmitter {\n private socket: net.Socket | null = null;\n\n connect(socketPath: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const socket = net.createConnection(socketPath, () => {\n resolve();\n });\n\n socket.on('error', (err) => {\n reject(err);\n });\n\n let buf = '';\n socket.on('data', (chunk) => {\n buf += chunk.toString();\n const lines = buf.split('\\n');\n buf = lines.pop() ?? '';\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n const msg = JSON.parse(line) as DaemonMessage;\n this.emit('message', msg);\n } catch {\n // Ignore malformed JSON\n }\n }\n });\n\n socket.on('close', () => {\n this.emit('disconnect');\n });\n\n this.socket = socket;\n });\n }\n\n send(msg: ClientMessage): void {\n if (!this.socket) return;\n try {\n this.socket.write(JSON.stringify(msg) + '\\n');\n } catch {\n // Socket may have closed\n }\n }\n\n disconnect(): void {\n this.socket?.destroy();\n this.socket = null;\n }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\nexport function cleanStaleSocket(socketPath: string): void {\n if (existsSync(socketPath)) {\n try {\n unlinkSync(socketPath);\n } catch {\n // Already gone\n }\n }\n}\n","import notifier from 'node-notifier';\n\nexport class NotificationService {\n constructor(private enabled: boolean) {}\n\n nodeDiscovered(nodeId: string, via: string): void {\n this.send(`📍 Node entdeckt: ${nodeId}`, `Via: ${via}`);\n }\n\n workflowDetected(count: number, desc: string): void {\n this.send(`🔄 ${count} Workflow(s) erkannt`, desc);\n }\n\n taskBoundary(gapMinutes: number): void {\n this.send('⏸ Task-Grenze erkannt', `${gapMinutes} Minuten Inaktivität`);\n }\n\n private send(title: string, message: string): void {\n if (!this.enabled) return;\n\n try {\n notifier.notify({ title, message, sound: false });\n } catch {\n // Notifications not available — silently skip\n }\n }\n}\n","import { IPCClient } from './ipc.js';\nimport { startDaemonProcess } from './daemon.js';\nimport type { CartographyConfig, DaemonMessage, ShadowStatus } from './types.js';\n\n// ── ForegroundClient ─────────────────────────────────────────────────────────\n// Runs daemon + terminal UI in the same process (no fork)\n\nexport class ForegroundClient {\n async run(config: CartographyConfig): Promise<void> {\n process.stderr.write('👁 Cartography Shadow (foreground) gestartet\\n');\n process.stderr.write(` Intervall: ${config.pollIntervalMs / 1000}s | Modell: ${config.shadowModel}\\n`);\n process.stderr.write(' Ctrl+C zum Beenden\\n\\n');\n\n // Run daemon inline (blocks until SIGINT/SIGTERM)\n await startDaemonProcess({ ...config, shadowMode: 'foreground' });\n }\n}\n\n// ── AttachClient ─────────────────────────────────────────────────────────────\n// Connects to a running daemon via Unix socket and provides terminal UI\n\nexport class AttachClient {\n async attach(socketPath: string): Promise<void> {\n const client = new IPCClient();\n\n try {\n await client.connect(socketPath);\n } catch {\n process.stderr.write(`❌ Kann nicht an Daemon ankoppeln: ${socketPath}\\n`);\n process.stderr.write(' Ist der Daemon gestartet? cartography shadow status\\n');\n process.exitCode = 1;\n return;\n }\n\n process.stderr.write('📡 Verbunden mit Shadow-Daemon\\n');\n process.stderr.write(' [T] Neuer Task [S] Status [D] Trennen [Q] Daemon stoppen\\n\\n');\n\n // Set raw mode for hotkeys\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(true);\n }\n process.stdin.resume();\n process.stdin.setEncoding('utf8');\n\n process.stdin.on('data', (key: string) => {\n const k = key.toLowerCase();\n\n if (k === 't') {\n process.stdout.write('\\nTask-Beschreibung: ');\n // Simple readline for description\n process.stdin.once('data', (desc: string) => {\n client.send({ type: 'task-description', description: desc.trim() });\n client.send({ type: 'command', command: 'new-task' });\n process.stdout.write(`\\n✓ Neuer Task gestartet: ${desc.trim()}\\n`);\n });\n return;\n }\n\n if (k === 's') {\n client.send({ type: 'command', command: 'status' });\n return;\n }\n\n if (k === 'd' || k === '\\u0003') {\n // Detach (Ctrl+C also)\n process.stderr.write('\\n📡 Getrennt. Daemon läuft weiter.\\n');\n client.disconnect();\n if (process.stdin.isTTY) process.stdin.setRawMode(false);\n process.stdin.pause();\n return;\n }\n\n if (k === 'q') {\n client.send({ type: 'command', command: 'stop' });\n process.stderr.write('\\n🛑 Daemon wird gestoppt...\\n');\n setTimeout(() => {\n client.disconnect();\n if (process.stdin.isTTY) process.stdin.setRawMode(false);\n process.stdin.pause();\n }, 1000);\n return;\n }\n });\n\n client.on('message', (msg: DaemonMessage) => {\n switch (msg.type) {\n case 'status':\n renderStatus(msg.data);\n break;\n case 'event':\n process.stdout.write(\n ` [${new Date(msg.data.timestamp).toLocaleTimeString()}] ` +\n `${msg.data.eventType} ${msg.data.process}` +\n (msg.data.target ? ` → ${msg.data.target}` : '') + '\\n'\n );\n break;\n case 'agent-output':\n if (msg.text) process.stdout.write(` 🤖 ${msg.text}\\n`);\n break;\n case 'info':\n process.stdout.write(` ℹ ${msg.message}\\n`);\n break;\n case 'prompt':\n renderPrompt(msg.prompt.kind, msg.prompt.options, (answer) => {\n client.send({ type: 'prompt-response', id: msg.id, answer });\n });\n break;\n }\n });\n\n client.on('disconnect', () => {\n process.stderr.write('\\n⚠ Verbindung zum Daemon verloren\\n');\n if (process.stdin.isTTY) process.stdin.setRawMode(false);\n process.stdin.pause();\n });\n }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction renderStatus(status: ShadowStatus): void {\n process.stdout.write(\n `\\n── Shadow Status ───────────────────────────────\\n` +\n ` PID: ${status.pid} | Uptime: ${Math.round(status.uptime)}s\\n` +\n ` Nodes: ${status.nodeCount} | Events: ${status.eventCount} | Tasks: ${status.taskCount}\\n` +\n ` Cycles: ${status.cyclesRun} run, ${status.cyclesSkipped} skipped\\n` +\n `────────────────────────────────────────────────\\n`\n );\n}\n\nfunction renderPrompt(\n kind: string,\n options: string[],\n callback: (answer: string) => void,\n): void {\n process.stdout.write(`\\n❓ ${kind}\\n`);\n options.forEach((opt, i) => process.stdout.write(` [${i + 1}] ${opt}\\n`));\n process.stdout.write('Antwort: ');\n process.stdin.once('data', (data: string) => {\n const idx = parseInt(data.trim(), 10) - 1;\n callback(options[idx] ?? options[0] ?? '');\n });\n}\n"],"mappings":"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","names":["z","z","mkdirSync","join","execSync","existsSync","readFileSync","writeFileSync","unlinkSync","existsSync","execSync","writeFileSync","existsSync","readFileSync","unlinkSync"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/preflight.ts","../src/types.ts","../src/db.ts","../src/tools.ts","../src/safety.ts","../src/agent.ts","../src/exporter.ts","../src/daemon.ts","../src/ipc.ts","../src/notify.ts","../src/client.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { checkPrerequisites, checkPollInterval } from './preflight.js';\nimport { CartographyDB } from './db.js';\nimport { defaultConfig } from './types.js';\nimport { runDiscovery, generateSOPs } from './agent.js';\nimport { exportAll } from './exporter.js';\nimport {\n forkDaemon, isDaemonRunning, stopDaemon, startDaemonProcess,\n} from './daemon.js';\nimport { ForegroundClient, AttachClient } from './client.js';\n\n// ── Daemon child-process entry ────────────────────────────────────────────────\nif (process.env.CARTOGRAPHYY_DAEMON === '1') {\n const config = JSON.parse(process.env.CARTOGRAPHYY_CONFIG ?? '{}') as ReturnType<typeof defaultConfig>;\n startDaemonProcess(config).catch((err) => {\n process.stderr.write(`Daemon fatal: ${err}\\n`);\n process.exitCode = 1;\n });\n} else {\n main();\n}\n\nfunction main(): void {\n const program = new Command();\n\n program\n .name('cartography')\n .description('AI-powered Infrastructure Cartography & SOP Generation')\n .version('0.1.0');\n\n // ── DISCOVERY ──────────────────────────────────────────────────────────────\n\n program\n .command('discover')\n .description('Infrastruktur scannen und kartographieren')\n .option('--entry <hosts...>', 'Startpunkte', ['localhost'])\n .option('--depth <n>', 'Max Tiefe', '8')\n .option('--max-turns <n>', 'Max Agent-Turns', '50')\n .option('--model <m>', 'Agent-Model', 'claude-sonnet-4-5-20250929')\n .option('--org <name>', 'Organisation (für Backstage)')\n .option('-o, --output <dir>', 'Output-Dir', './cartography-output')\n .option('--db <path>', 'DB-Pfad')\n .option('-v, --verbose', 'Agent-Reasoning anzeigen', false)\n .action(async (opts) => {\n checkPrerequisites();\n\n const config = defaultConfig({\n mode: 'discover',\n entryPoints: opts.entry,\n maxDepth: parseInt(opts.depth, 10),\n maxTurns: parseInt(opts.maxTurns, 10),\n agentModel: opts.model,\n organization: opts.org,\n outputDir: opts.output,\n ...(opts.db ? { dbPath: opts.db } : {}),\n verbose: opts.verbose,\n });\n\n const db = new CartographyDB(config.dbPath);\n const sessionId = db.createSession('discover', config);\n\n process.stderr.write(`🔍 Scanning ${config.entryPoints.join(', ')}...\\n`);\n process.stderr.write(` Model: ${config.agentModel} | MaxTurns: ${config.maxTurns}\\n\\n`);\n\n try {\n await runDiscovery(config, db, sessionId, (text) => {\n if (config.verbose) process.stdout.write(text + '\\n');\n });\n } catch (err) {\n process.stderr.write(`❌ Discovery fehlgeschlagen: ${err}\\n`);\n db.close();\n process.exitCode = 1;\n return;\n }\n\n db.endSession(sessionId);\n const stats = db.getStats(sessionId);\n\n process.stderr.write(`\\n✓ ${stats.nodes} nodes, ${stats.edges} edges discovered\\n`);\n\n exportAll(db, sessionId, config.outputDir);\n process.stderr.write(`✓ Exported to: ${config.outputDir}\\n`);\n\n db.close();\n });\n\n // ── SHADOW ────────────────────────────────────────────────────────────────\n\n const shadow = program.command('shadow').description('Shadow-Daemon verwalten');\n\n shadow\n .command('start')\n .description('Shadow-Daemon starten')\n .option('--interval <ms>', 'Poll-Intervall in ms', '30000')\n .option('--inactivity <ms>', 'Task-Grenze in ms', '300000')\n .option('--track-windows', 'Fenster-Focus tracken', false)\n .option('--auto-save', 'Nodes ohne Rückfrage speichern', false)\n .option('--no-notifications', 'Desktop-Notifications deaktivieren')\n .option('--model <m>', 'Analysis-Model', 'claude-haiku-4-5-20251001')\n .option('--foreground', 'Kein Daemon, im Terminal bleiben', false)\n .option('--db <path>', 'DB-Pfad')\n .option('--daemon-child', 'Internal: marks this as a daemon child process') // internal flag\n .action(async (opts) => {\n checkPrerequisites();\n\n const intervalMs = checkPollInterval(parseInt(opts.interval, 10));\n\n const config = defaultConfig({\n mode: 'shadow',\n shadowMode: opts.foreground ? 'foreground' : 'daemon',\n pollIntervalMs: intervalMs,\n inactivityTimeoutMs: parseInt(opts.inactivity, 10),\n trackWindowFocus: opts.trackWindows,\n autoSaveNodes: opts.autoSave,\n enableNotifications: opts.notifications !== false,\n shadowModel: opts.model,\n ...(opts.db ? { dbPath: opts.db } : {}),\n });\n\n // Check if already running\n const { running } = isDaemonRunning(config.pidFile);\n if (running) {\n process.stderr.write('❌ Shadow-Daemon läuft bereits. cartography shadow status\\n');\n process.exitCode = 1;\n return;\n }\n\n if (opts.foreground) {\n const client = new ForegroundClient();\n await client.run(config);\n } else {\n const pid = forkDaemon(config);\n process.stderr.write(`👁 Shadow daemon started (PID ${pid})\\n`);\n process.stderr.write(` Intervall: ${intervalMs / 1000}s | Modell: ${config.shadowModel}\\n`);\n process.stderr.write(' cartography shadow attach — ankoppeln\\n');\n process.stderr.write(' cartography shadow stop — stoppen\\n\\n');\n }\n });\n\n shadow\n .command('stop')\n .description('Shadow-Daemon stoppen')\n .action(() => {\n const config = defaultConfig();\n const stopped = stopDaemon(config.pidFile);\n if (stopped) {\n process.stderr.write('✓ Shadow-Daemon gestoppt\\n');\n } else {\n process.stderr.write('⚠ Kein laufender Shadow-Daemon gefunden\\n');\n }\n });\n\n shadow\n .command('status')\n .description('Shadow-Daemon Status anzeigen')\n .action(() => {\n const config = defaultConfig();\n const { running, pid } = isDaemonRunning(config.pidFile);\n if (running) {\n process.stdout.write(`✓ Shadow-Daemon läuft (PID ${pid})\\n`);\n process.stdout.write(` Socket: ${config.socketPath}\\n`);\n } else {\n process.stdout.write('✗ Shadow-Daemon gestoppt\\n');\n }\n });\n\n shadow\n .command('attach')\n .description('An laufenden Shadow-Daemon ankoppeln')\n .action(async () => {\n const config = defaultConfig();\n const client = new AttachClient();\n await client.attach(config.socketPath);\n });\n\n // ── ANALYSE & EXPORT ──────────────────────────────────────────────────────\n\n program\n .command('sops [session-id]')\n .description('SOPs aus beobachteten Workflows generieren')\n .action(async (sessionId?: string) => {\n checkPrerequisites();\n\n const config = defaultConfig();\n const db = new CartographyDB(config.dbPath);\n\n const session = sessionId\n ? db.getSession(sessionId)\n : db.getLatestSession('shadow');\n\n if (!session) {\n process.stderr.write('❌ Keine Shadow-Session gefunden. cartography shadow start\\n');\n db.close();\n process.exitCode = 1;\n return;\n }\n\n process.stderr.write(`🔄 Generiere SOPs aus Session ${session.id}...\\n`);\n const count = await generateSOPs(db, session.id);\n process.stderr.write(`✓ ${count} SOPs generiert\\n`);\n\n db.close();\n });\n\n program\n .command('export [session-id]')\n .description('Alle Outputs generieren')\n .option('-o, --output <dir>', 'Output-Dir', './cartography-output')\n .option('--format <fmt...>', 'Formate: mermaid,json,yaml,html,sops')\n .action((sessionId: string | undefined, opts) => {\n const config = defaultConfig({ outputDir: opts.output });\n const db = new CartographyDB(config.dbPath);\n\n const session = sessionId\n ? db.getSession(sessionId)\n : db.getLatestSession();\n\n if (!session) {\n process.stderr.write('❌ Keine Session gefunden\\n');\n db.close();\n process.exitCode = 1;\n return;\n }\n\n const formats = opts.format ?? ['mermaid', 'json', 'yaml', 'html', 'sops'];\n exportAll(db, session.id, opts.output, formats);\n process.stderr.write(`✓ Exported to: ${opts.output}\\n`);\n\n db.close();\n });\n\n program\n .command('show [session-id]')\n .description('Session-Details anzeigen')\n .action((sessionId?: string) => {\n const config = defaultConfig();\n const db = new CartographyDB(config.dbPath);\n\n const session = sessionId\n ? db.getSession(sessionId)\n : db.getLatestSession();\n\n if (!session) {\n process.stderr.write('❌ Keine Session gefunden\\n');\n db.close();\n process.exitCode = 1;\n return;\n }\n\n const stats = db.getStats(session.id);\n const nodes = db.getNodes(session.id);\n\n process.stdout.write(`\\nSession: ${session.id}\\n`);\n process.stdout.write(` Mode: ${session.mode}\\n`);\n process.stdout.write(` Started: ${session.startedAt}\\n`);\n if (session.completedAt) process.stdout.write(` Ended: ${session.completedAt}\\n`);\n process.stdout.write(` Nodes: ${stats.nodes}\\n`);\n process.stdout.write(` Edges: ${stats.edges}\\n`);\n process.stdout.write(` Events: ${stats.events}\\n`);\n process.stdout.write(` Tasks: ${stats.tasks}\\n`);\n\n if (nodes.length > 0) {\n process.stdout.write('\\n Discovered nodes:\\n');\n for (const node of nodes.slice(0, 20)) {\n process.stdout.write(` ${node.id} (${node.type}, confidence: ${node.confidence})\\n`);\n }\n if (nodes.length > 20) {\n process.stdout.write(` ... and ${nodes.length - 20} more\\n`);\n }\n }\n\n process.stdout.write('\\n');\n db.close();\n });\n\n program\n .command('sessions')\n .description('Alle Sessions auflisten')\n .action(() => {\n const config = defaultConfig();\n const db = new CartographyDB(config.dbPath);\n const sessions = db.getSessions();\n\n if (sessions.length === 0) {\n process.stdout.write('Keine Sessions gefunden\\n');\n db.close();\n return;\n }\n\n for (const session of sessions) {\n const stats = db.getStats(session.id);\n const status = session.completedAt ? '✓' : '●';\n process.stdout.write(\n `${status} ${session.id.substring(0, 8)} [${session.mode}] ` +\n `${session.startedAt.substring(0, 19)} ` +\n `nodes:${stats.nodes} edges:${stats.edges}\\n`\n );\n }\n\n db.close();\n });\n\n // ── DOCS ──────────────────────────────────────────────────────────────────\n\n program\n .command('docs')\n .description('Alle Features und Befehle auf einen Blick')\n .action(() => {\n const out = process.stdout.write.bind(process.stdout);\n const b = (s: string) => `\\x1b[1m${s}\\x1b[0m`;\n const dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\n const cyan = (s: string) => `\\x1b[36m${s}\\x1b[0m`;\n const green = (s: string) => `\\x1b[32m${s}\\x1b[0m`;\n const yellow = (s: string) => `\\x1b[33m${s}\\x1b[0m`;\n const line = () => out(dim('─'.repeat(60)) + '\\n');\n\n out('\\n');\n out(b(' CARTOGRAPHY') + ' ' + dim('v0.1.2') + '\\n');\n out(dim(' AI-powered Infrastructure Cartography & SOP Generation\\n'));\n out('\\n');\n line();\n\n // ── DISCOVERY\n out(b(cyan(' DISCOVERY\\n')));\n out('\\n');\n out(` ${green('cartography discover')}\\n`);\n out(` Scannt die lokale Infrastruktur (Claude Sonnet).\\n`);\n out(` Claude führt eigenständig ss, ps, curl, docker inspect, kubectl get\\n`);\n out(` aus und speichert alles in SQLite.\\n`);\n out('\\n');\n out(dim(' Optionen:\\n'));\n out(dim(' --entry <hosts...> Startpunkte (default: localhost)\\n'));\n out(dim(' --depth <n> Max Tiefe (default: 8)\\n'));\n out(dim(' --max-turns <n> Max Agent-Turns (default: 50)\\n'));\n out(dim(' --model <m> Model (default: claude-sonnet-4-5-...)\\n'));\n out(dim(' --org <name> Organisation für Backstage YAML\\n'));\n out(dim(' -o, --output <dir> Output-Verzeichnis (default: ./cartography-output)\\n'));\n out(dim(' -v, --verbose Agent-Reasoning anzeigen\\n'));\n out('\\n');\n out(dim(' Output:\\n'));\n out(dim(' cartography-output/\\n'));\n out(dim(' catalog.json Maschinenlesbarer Komplett-Dump\\n'));\n out(dim(' catalog-info.yaml Backstage Service-Katalog\\n'));\n out(dim(' topology.mermaid Infrastruktur-Topologie (graph TB)\\n'));\n out(dim(' dependencies.mermaid Service-Dependencies (graph LR)\\n'));\n out(dim(' topology.html Interaktiver D3.js Force-Graph\\n'));\n out(dim(' sops/ Generierte SOPs als Markdown\\n'));\n out(dim(' workflows/ Workflow-Flowcharts als Mermaid\\n'));\n out('\\n');\n line();\n\n // ── SHADOW\n out(b(cyan(' SHADOW DAEMON\\n')));\n out('\\n');\n out(` ${green('cartography shadow start')}\\n`);\n out(` Startet einen Background-Daemon, der alle 30s einen System-Snapshot\\n`);\n out(` nimmt (ss + ps). Nur bei Änderung ruft er Claude Haiku auf.\\n`);\n out('\\n');\n out(dim(' Optionen:\\n'));\n out(dim(' --interval <ms> Poll-Intervall (default: 30000, min: 15000)\\n'));\n out(dim(' --inactivity <ms> Task-Grenze (default: 300000 = 5 min)\\n'));\n out(dim(' --model <m> Analysis-Model (default: claude-haiku-4-5-...)\\n'));\n out(dim(' --track-windows Fenster-Focus tracken (benötigt xdotool)\\n'));\n out(dim(' --auto-save Nodes ohne Rückfrage speichern\\n'));\n out(dim(' --no-notifications Desktop-Notifications deaktivieren\\n'));\n out(dim(' --foreground Kein Daemon, im Terminal bleiben\\n'));\n out('\\n');\n out(` ${green('cartography shadow stop')} ${dim('Daemon per SIGTERM beenden')}\\n`);\n out(` ${green('cartography shadow status')} ${dim('PID + Socket-Pfad anzeigen')}\\n`);\n out(` ${green('cartography shadow attach')} ${dim('Live-Events im Terminal, Hotkeys: [T] [S] [D] [Q]')}\\n`);\n out('\\n');\n out(dim(' Hotkeys im Attach-Modus:\\n'));\n out(dim(' [T] Neuen Task starten (mit Beschreibung)\\n'));\n out(dim(' [S] Status-Dump anzeigen (Nodes, Events, Tasks, Cycles)\\n'));\n out(dim(' [D] Trennen — Daemon läuft weiter\\n'));\n out(dim(' [Q] Daemon stoppen und beenden\\n'));\n out('\\n');\n line();\n\n // ── ANALYSE & EXPORT\n out(b(cyan(' ANALYSE & EXPORT\\n')));\n out('\\n');\n out(` ${green('cartography sops [session-id]')}\\n`);\n out(` Clustert abgeschlossene Tasks und generiert SOPs via Claude Sonnet.\\n`);\n out(` Nutzt die Anthropic Messages API (kein Agent-Loop, ein Request pro Cluster).\\n`);\n out('\\n');\n out(` ${green('cartography export [session-id]')}\\n`);\n out(dim(' --format <fmt...> mermaid, json, yaml, html, sops (default: alle)\\n'));\n out(dim(' -o, --output <dir> Output-Verzeichnis\\n'));\n out('\\n');\n out(` ${green('cartography show [session-id]')} ${dim('Session-Details + Node-Liste')}\\n`);\n out(` ${green('cartography sessions')} ${dim('Alle Sessions tabellarisch auflisten')}\\n`);\n out('\\n');\n line();\n\n // ── KOSTEN\n out(b(cyan(' KOSTEN (Richtwerte)\\n')));\n out('\\n');\n out(yellow(' Modus Model Intervall pro Stunde pro 8h-Tag\\n'));\n out(dim(' ─────────────────────────────────────────────────────────────\\n'));\n out(` Discovery Sonnet einmalig $0.15–0.50 einmalig\\n`);\n out(` Shadow Haiku 30s $0.12–0.36 $0.96–2.88\\n`);\n out(` Shadow Haiku 60s $0.06–0.18 $0.48–1.44\\n`);\n out(` Shadow (ruhig) Haiku 30s ~$0.02 ~$0.16\\n`);\n out(` SOP-Gen Sonnet einmalig $0.01–0.03 einmalig\\n`);\n out('\\n');\n out(dim(' * \"ruhig\" = Diff-Check überspringt 90%+ Cycles, wenn System unverändert\\n'));\n out('\\n');\n line();\n\n // ── ARCHITEKTUR\n out(b(cyan(' ARCHITEKTUR\\n')));\n out('\\n');\n out(dim(' CLI (Commander)\\n'));\n out(dim(' └── Preflight: Claude CLI check + API key + Intervall-Validierung\\n'));\n out(dim(' └── Agent Orchestrator (agent.ts)\\n'));\n out(dim(' ├── runDiscovery() → Claude Sonnet + Bash + MCP Tools\\n'));\n out(dim(' ├── runShadowCycle() → Claude Haiku + nur MCP Tools (kein Bash!)\\n'));\n out(dim(' └── generateSOPs() → Anthropic Messages API (kein Agent-Loop)\\n'));\n out(dim(' └── Custom MCP Tools (tools.ts)\\n'));\n out(dim(' save_node, save_edge, save_event,\\n'));\n out(dim(' get_catalog, manage_task, save_sop\\n'));\n out(dim(' └── CartographyDB (SQLite WAL)\\n'));\n out(dim(' Shadow Daemon (daemon.ts)\\n'));\n out(dim(' ├── takeSnapshot() → ss + ps [kein Claude!]\\n'));\n out(dim(' ├── Diff-Check → nur bei Änderung: runShadowCycle()\\n'));\n out(dim(' ├── IPC Server (Unix Socket ~/.cartography/daemon.sock)\\n'));\n out(dim(' └── NotificationService (Desktop wenn kein Client attached)\\n'));\n out('\\n');\n line();\n\n // ── SETUP\n out(b(cyan(' SETUP\\n')));\n out('\\n');\n out(dim(' # 1. Claude CLI (Runtime-Dependency)\\n'));\n out(' npm install -g @anthropic-ai/claude-code\\n');\n out(' claude login\\n');\n out('\\n');\n out(dim(' # 2. API Key (falls nicht via claude login)\\n'));\n out(' export ANTHROPIC_API_KEY=sk-ant-...\\n');\n out('\\n');\n out(dim(' # 3. Los\\n'));\n out(' cartography discover\\n');\n out(' cartography shadow start\\n');\n out('\\n');\n out(dim(' Daten: ~/.cartography/cartography.db\\n'));\n out(dim(' Socket: ~/.cartography/daemon.sock\\n'));\n out(dim(' PID: ~/.cartography/daemon.pid\\n'));\n out('\\n');\n });\n\n // ── Doctor ─────────────────────────────────────────────────────────────────\n\n program\n .command('doctor')\n .description('Prüft ob alle Voraussetzungen erfüllt sind')\n .action(async () => {\n const { execSync } = await import('node:child_process');\n const { existsSync, readFileSync } = await import('node:fs');\n const { join } = await import('node:path');\n const out = (s: string) => process.stdout.write(s);\n const ok = (msg: string) => out(` \\x1b[32m✓\\x1b[0m ${msg}\\n`);\n const err = (msg: string) => out(` \\x1b[31m✗\\x1b[0m ${msg}\\n`);\n const warn = (msg: string) => out(` \\x1b[33m⚠\\x1b[0m ${msg}\\n`);\n const dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\n let allGood = true;\n\n out('\\n \\x1b[1mCartography — Doctor\\x1b[0m\\n');\n out(dim(' ─────────────────────────────────\\n'));\n\n // 1. Node.js Version\n const nodeVer = process.versions.node;\n const [major] = nodeVer.split('.').map(Number);\n if ((major ?? 0) >= 18) {\n ok(`Node.js ${nodeVer}`);\n } else {\n err(`Node.js ${nodeVer} — benötigt >=18`);\n allGood = false;\n }\n\n // 2. Claude CLI\n try {\n const v = execSync('claude --version', { stdio: 'pipe' }).toString().trim();\n ok(`Claude CLI ${dim(v)}`);\n } catch {\n err('Claude CLI nicht gefunden — npm i -g @anthropic-ai/claude-code');\n allGood = false;\n }\n\n // 3. Auth\n const hasApiKey = Boolean(process.env.ANTHROPIC_API_KEY);\n const home = process.env.HOME ?? process.env.USERPROFILE ?? '/tmp';\n let hasOAuth = false;\n try {\n const creds = JSON.parse(readFileSync(join(home, '.claude', '.credentials.json'), 'utf8')) as Record<string, unknown>;\n const oauth = creds['claudeAiOauth'] as Record<string, unknown> | undefined;\n hasOAuth = typeof oauth?.['accessToken'] === 'string' && oauth['accessToken'].length > 0;\n } catch { /* no creds file */ }\n\n if (hasApiKey) {\n ok('ANTHROPIC_API_KEY gesetzt');\n } else if (hasOAuth) {\n ok('claude login (Subscription)');\n } else {\n err('Keine Authentifizierung — claude login oder export ANTHROPIC_API_KEY=sk-ant-...');\n allGood = false;\n }\n\n // 4. Optionale Tools\n const optional: Array<[string, string]> = [\n ['docker', 'docker --version'],\n ['kubectl', 'kubectl version --client --short'],\n ['ss', 'ss --version'],\n ];\n for (const [name, cmd] of optional) {\n try {\n execSync(cmd, { stdio: 'pipe' });\n ok(`${name} ${dim('(Discovery-Tool)')}`);\n } catch {\n warn(`${name} nicht gefunden ${dim('— Discovery ohne ' + name + ' eingeschränkt')}`);\n }\n }\n\n // 5. SQLite data dir\n const dbDir = join(home, '.cartography');\n if (existsSync(dbDir)) {\n ok(`~/.cartography ${dim('(Daten-Verzeichnis vorhanden)')}`);\n } else {\n warn('~/.cartography existiert noch nicht ' + dim('— wird beim ersten Start angelegt'));\n }\n\n out(dim(' ─────────────────────────────────\\n'));\n if (allGood) {\n out(' \\x1b[32m\\x1b[1mAlle Checks bestanden — cartography discover\\x1b[0m\\n\\n');\n } else {\n out(' \\x1b[31m\\x1b[1mEinige Checks fehlgeschlagen. Bitte oben beheben.\\x1b[0m\\n\\n');\n process.exitCode = 1;\n }\n });\n\n // ── Parse ──────────────────────────────────────────────────────────────────\n\n program.exitOverride((err) => {\n if (err.code === 'commander.helpDisplayed') {\n process.exitCode = 0;\n } else {\n process.exitCode = 2;\n }\n });\n\n program.parse(process.argv);\n}\n","import { execSync } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { MIN_POLL_INTERVAL_MS } from './types.js';\n\nfunction isOAuthLoggedIn(): boolean {\n // Claude CLI speichert OAuth-Tokens in ~/.claude/.credentials.json\n const home = process.env.HOME ?? process.env.USERPROFILE ?? '/tmp';\n const credFile = join(home, '.claude', '.credentials.json');\n if (!existsSync(credFile)) return false;\n try {\n const creds = JSON.parse(readFileSync(credFile, 'utf8')) as Record<string, unknown>;\n const oauth = creds['claudeAiOauth'] as Record<string, unknown> | undefined;\n return typeof oauth?.['accessToken'] === 'string' && oauth['accessToken'].length > 0;\n } catch {\n return false;\n }\n}\n\nexport function checkPrerequisites(): void {\n // Claude CLI vorhanden?\n try {\n execSync('claude --version', { stdio: 'pipe' });\n } catch {\n process.stderr.write(\n '\\n❌ Claude CLI nicht gefunden.\\n' +\n ' Cartography braucht die Claude CLI als Runtime-Dependency.\\n\\n' +\n ' Installieren:\\n' +\n ' npm install -g @anthropic-ai/claude-code\\n' +\n ' # oder\\n' +\n ' curl -fsSL https://claude.ai/install.sh | bash\\n\\n' +\n ' Danach: claude login\\n\\n'\n );\n process.exitCode = 1;\n throw new Error('Claude CLI not found');\n }\n\n // Auth prüfen: API Key ODER OAuth-Login (claude.ai Subscription)\n const hasApiKey = Boolean(process.env.ANTHROPIC_API_KEY);\n const hasOAuth = isOAuthLoggedIn();\n\n if (!hasApiKey && !hasOAuth) {\n process.stderr.write(\n '⚠ Keine Authentifizierung gefunden. Bitte eine der folgenden Optionen:\\n\\n' +\n ' Option A — claude.ai Subscription (empfohlen):\\n' +\n ' claude login\\n\\n' +\n ' Option B — API Key:\\n' +\n ' export ANTHROPIC_API_KEY=sk-ant-...\\n\\n'\n );\n } else if (hasOAuth && !hasApiKey) {\n process.stderr.write('✓ Eingeloggt via claude login (Subscription)\\n');\n }\n}\n\nexport function checkPollInterval(intervalMs: number): number {\n if (intervalMs < MIN_POLL_INTERVAL_MS) {\n process.stderr.write(\n `⚠ Minimum Shadow-Intervall: ${MIN_POLL_INTERVAL_MS / 1000} Sekunden (Agent SDK Overhead)\\n`\n );\n return MIN_POLL_INTERVAL_MS;\n }\n return intervalMs;\n}\n","import { z } from 'zod';\n\n// ── Enums ────────────────────────────────\n\nexport const NODE_TYPES = [\n 'host', 'database_server', 'database', 'table',\n 'web_service', 'api_endpoint', 'cache_server',\n 'message_broker', 'queue', 'topic',\n 'container', 'pod', 'k8s_cluster',\n 'config_file', 'unknown',\n] as const;\nexport type NodeType = typeof NODE_TYPES[number];\n\nexport const EDGE_RELATIONSHIPS = [\n 'connects_to', 'reads_from', 'writes_to',\n 'calls', 'contains', 'depends_on',\n] as const;\nexport type EdgeRelationship = typeof EDGE_RELATIONSHIPS[number];\n\nexport const EVENT_TYPES = [\n 'process_start', 'process_end',\n 'connection_open', 'connection_close',\n 'window_focus', 'tool_switch',\n] as const;\nexport type EventType = typeof EVENT_TYPES[number];\n\n// ── Zod Schemas ──────────────────────────\n\nexport const NodeSchema = z.object({\n id: z.string().describe('Format: \"{type}:{host}:{port}\" oder \"{type}:{name}\"'),\n type: z.enum(NODE_TYPES),\n name: z.string(),\n discoveredVia: z.string(),\n confidence: z.number().min(0).max(1).default(0.5),\n metadata: z.record(z.unknown()).default({}),\n tags: z.array(z.string()).default([]),\n});\nexport type DiscoveryNode = z.infer<typeof NodeSchema>;\n\nexport const EdgeSchema = z.object({\n sourceId: z.string(),\n targetId: z.string(),\n relationship: z.enum(EDGE_RELATIONSHIPS),\n evidence: z.string(),\n confidence: z.number().min(0).max(1).default(0.5),\n});\nexport type DiscoveryEdge = z.infer<typeof EdgeSchema>;\n\nexport const EventSchema = z.object({\n eventType: z.enum(EVENT_TYPES),\n process: z.string(),\n pid: z.number(),\n target: z.string().optional(),\n targetType: z.enum(NODE_TYPES).optional(),\n protocol: z.string().optional(),\n port: z.number().optional(),\n});\nexport type ActivityEvent = z.infer<typeof EventSchema>;\n\nexport const SOPStepSchema = z.object({\n order: z.number(),\n instruction: z.string(),\n tool: z.string(),\n target: z.string().optional(),\n notes: z.string().optional(),\n});\nexport type SOPStep = z.infer<typeof SOPStepSchema>;\n\nexport const SOPSchema = z.object({\n title: z.string(),\n description: z.string(),\n steps: z.array(SOPStepSchema),\n involvedSystems: z.array(z.string()),\n estimatedDuration: z.string(),\n frequency: z.string(),\n confidence: z.number().min(0).max(1),\n});\nexport type SOP = z.infer<typeof SOPSchema>;\n\n// ── DB Row Types ─────────────────────────\n\nexport interface NodeRow extends DiscoveryNode {\n sessionId: string;\n discoveredAt: string;\n depth: number;\n pathId?: string;\n}\n\nexport interface EdgeRow extends DiscoveryEdge {\n id: string;\n sessionId: string;\n discoveredAt: string;\n pathId?: string;\n}\n\nexport interface EventRow {\n id: string;\n sessionId: string;\n taskId?: string;\n timestamp: string;\n eventType: EventType;\n process: string;\n pid: number;\n target?: string;\n targetType?: NodeType;\n port?: number;\n durationMs?: number;\n}\n\nexport interface TaskRow {\n id: string;\n sessionId: string;\n description?: string;\n startedAt: string;\n completedAt?: string;\n steps: string;\n involvedServices: string;\n status: 'active' | 'completed' | 'cancelled';\n isSOPCandidate: boolean;\n}\n\nexport interface WorkflowRow {\n id: string;\n sessionId: string;\n name?: string;\n pattern: string;\n taskIds: string;\n occurrences: number;\n firstSeen: string;\n lastSeen: string;\n avgDurationMs: number;\n involvedServices: string;\n}\n\nexport interface SessionRow {\n id: string;\n mode: 'discover' | 'shadow';\n startedAt: string;\n completedAt?: string;\n config: string;\n}\n\n// ── IPC Protokoll ────────────────────────\n\nexport type DaemonMessage =\n | { type: 'event'; data: EventRow }\n | { type: 'prompt'; id: string; prompt: PendingPrompt }\n | { type: 'status'; data: ShadowStatus }\n | { type: 'agent-output'; text: string }\n | { type: 'info'; message: string };\n\nexport type ClientMessage =\n | { type: 'prompt-response'; id: string; answer: string }\n | { type: 'command'; command: 'new-task' | 'end-task' | 'status' | 'stop' }\n | { type: 'task-description'; description: string };\n\nexport interface PendingPrompt {\n kind: 'node-approval' | 'task-boundary' | 'task-end';\n context: Record<string, unknown>;\n options: string[];\n defaultAnswer: string;\n timeoutMs: number;\n createdAt: string;\n}\n\nexport interface ShadowStatus {\n pid: number;\n uptime: number;\n nodeCount: number;\n eventCount: number;\n taskCount: number;\n pendingPrompts: number;\n autoSave: boolean;\n mode: 'foreground' | 'daemon';\n agentActive: boolean;\n cyclesRun: number;\n cyclesSkipped: number;\n}\n\n// ── Config ───────────────────────────────\n\nexport const MIN_POLL_INTERVAL_MS = 15_000; // 15s Minimum (Agent SDK Overhead)\n\nexport interface CartographyConfig {\n mode: 'discover' | 'shadow';\n maxDepth: number;\n maxTurns: number;\n entryPoints: string[];\n agentModel: string;\n shadowMode: 'foreground' | 'daemon';\n pollIntervalMs: number;\n inactivityTimeoutMs: number;\n promptTimeoutMs: number;\n trackWindowFocus: boolean;\n autoSaveNodes: boolean;\n enableNotifications: boolean;\n shadowModel: string;\n organization?: string;\n outputDir: string;\n dbPath: string;\n socketPath: string;\n pidFile: string;\n verbose: boolean;\n}\n\nexport function defaultConfig(overrides: Partial<CartographyConfig> = {}): CartographyConfig {\n const home = process.env.HOME ?? process.env.USERPROFILE ?? '/tmp';\n return {\n mode: 'discover',\n maxDepth: 8,\n maxTurns: 50,\n entryPoints: ['localhost'],\n agentModel: 'claude-sonnet-4-5-20250929',\n shadowMode: 'daemon',\n pollIntervalMs: 30_000,\n inactivityTimeoutMs: 300_000,\n promptTimeoutMs: 60_000,\n trackWindowFocus: false,\n autoSaveNodes: false,\n enableNotifications: true,\n shadowModel: 'claude-haiku-4-5-20251001',\n outputDir: './cartography-output',\n dbPath: `${home}/.cartography/cartography.db`,\n socketPath: `${home}/.cartography/daemon.sock`,\n pidFile: `${home}/.cartography/daemon.pid`,\n verbose: false,\n ...overrides,\n };\n}\n","import Database from 'better-sqlite3';\nimport { mkdirSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport type {\n CartographyConfig, DiscoveryNode, DiscoveryEdge, ActivityEvent,\n NodeRow, EdgeRow, EventRow, TaskRow, WorkflowRow, SessionRow, SOP,\n} from './types.js';\n\nconst SCHEMA = `\nPRAGMA journal_mode = WAL;\nPRAGMA foreign_keys = ON;\nPRAGMA busy_timeout = 5000;\n\nCREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n mode TEXT NOT NULL CHECK (mode IN ('discover','shadow')),\n started_at TEXT NOT NULL,\n completed_at TEXT,\n config TEXT NOT NULL DEFAULT '{}'\n);\n\nCREATE TABLE IF NOT EXISTS nodes (\n id TEXT NOT NULL,\n session_id TEXT NOT NULL REFERENCES sessions(id),\n type TEXT NOT NULL,\n name TEXT NOT NULL,\n discovered_via TEXT,\n discovered_at TEXT NOT NULL,\n path_id TEXT,\n depth INTEGER DEFAULT 0,\n confidence REAL DEFAULT 0.5,\n metadata TEXT NOT NULL DEFAULT '{}',\n tags TEXT NOT NULL DEFAULT '[]',\n PRIMARY KEY (id, session_id)\n);\n\nCREATE TABLE IF NOT EXISTS edges (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL REFERENCES sessions(id),\n source_id TEXT NOT NULL,\n target_id TEXT NOT NULL,\n relationship TEXT NOT NULL,\n evidence TEXT,\n confidence REAL DEFAULT 0.5,\n discovered_at TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS activity_events (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL REFERENCES sessions(id),\n task_id TEXT,\n timestamp TEXT NOT NULL,\n event_type TEXT NOT NULL,\n process TEXT NOT NULL,\n pid INTEGER NOT NULL,\n target TEXT,\n target_type TEXT,\n port INTEGER,\n duration_ms INTEGER\n);\n\nCREATE TABLE IF NOT EXISTS tasks (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL REFERENCES sessions(id),\n description TEXT,\n started_at TEXT NOT NULL,\n completed_at TEXT,\n steps TEXT NOT NULL DEFAULT '[]',\n involved_services TEXT NOT NULL DEFAULT '[]',\n status TEXT DEFAULT 'active' CHECK (status IN ('active','completed','cancelled')),\n is_sop_candidate INTEGER DEFAULT 0\n);\n\nCREATE TABLE IF NOT EXISTS workflows (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL REFERENCES sessions(id),\n name TEXT,\n pattern TEXT NOT NULL,\n task_ids TEXT NOT NULL DEFAULT '[]',\n occurrences INTEGER DEFAULT 1,\n first_seen TEXT NOT NULL,\n last_seen TEXT NOT NULL,\n avg_duration_ms INTEGER,\n involved_services TEXT NOT NULL DEFAULT '[]'\n);\n\nCREATE TABLE IF NOT EXISTS sops (\n id TEXT PRIMARY KEY,\n workflow_id TEXT NOT NULL,\n title TEXT NOT NULL,\n description TEXT NOT NULL,\n steps TEXT NOT NULL,\n involved_systems TEXT NOT NULL DEFAULT '[]',\n estimated_duration TEXT,\n frequency TEXT,\n generated_at TEXT NOT NULL,\n confidence REAL DEFAULT 0.5\n);\n\nCREATE TABLE IF NOT EXISTS node_approvals (\n pattern TEXT PRIMARY KEY,\n action TEXT NOT NULL CHECK (action IN ('save','ignore','auto')),\n created_at TEXT NOT NULL\n);\n\nCREATE INDEX IF NOT EXISTS idx_nodes_session ON nodes(session_id);\nCREATE INDEX IF NOT EXISTS idx_edges_session ON edges(session_id);\nCREATE INDEX IF NOT EXISTS idx_events_session ON activity_events(session_id);\nCREATE INDEX IF NOT EXISTS idx_events_task ON activity_events(task_id);\nCREATE INDEX IF NOT EXISTS idx_tasks_session ON tasks(session_id);\n`;\n\nexport class CartographyDB {\n private db: Database.Database;\n\n constructor(dbPath: string) {\n mkdirSync(dirname(dbPath), { recursive: true });\n this.db = new Database(dbPath);\n this.db.pragma('journal_mode = WAL');\n this.db.pragma('foreign_keys = ON');\n this.db.pragma('busy_timeout = 5000');\n this.migrate();\n }\n\n private migrate(): void {\n const version = (this.db.pragma('user_version', { simple: true }) as number);\n if (version === 0) {\n this.db.exec(SCHEMA);\n this.db.pragma('user_version = 1');\n }\n }\n\n close(): void {\n this.db.pragma('optimize');\n this.db.close();\n }\n\n // ── Sessions ────────────────────────────\n\n createSession(mode: 'discover' | 'shadow', config: CartographyConfig): string {\n const id = crypto.randomUUID();\n this.db.prepare(\n 'INSERT INTO sessions (id, mode, started_at, config) VALUES (?, ?, ?, ?)'\n ).run(id, mode, new Date().toISOString(), JSON.stringify(config));\n return id;\n }\n\n endSession(id: string): void {\n this.db.prepare('UPDATE sessions SET completed_at = ? WHERE id = ?')\n .run(new Date().toISOString(), id);\n }\n\n getSession(id: string): SessionRow | undefined {\n const row = this.db.prepare('SELECT * FROM sessions WHERE id = ?').get(id) as Record<string, unknown> | undefined;\n return row ? this.mapSession(row) : undefined;\n }\n\n getLatestSession(mode?: string): SessionRow | undefined {\n const row = mode\n ? this.db.prepare('SELECT * FROM sessions WHERE mode = ? ORDER BY rowid DESC LIMIT 1').get(mode) as Record<string, unknown> | undefined\n : this.db.prepare('SELECT * FROM sessions ORDER BY rowid DESC LIMIT 1').get() as Record<string, unknown> | undefined;\n return row ? this.mapSession(row) : undefined;\n }\n\n getSessions(): SessionRow[] {\n const rows = this.db.prepare('SELECT * FROM sessions ORDER BY rowid DESC').all() as Record<string, unknown>[];\n return rows.map(r => this.mapSession(r));\n }\n\n private mapSession(r: Record<string, unknown>): SessionRow {\n return {\n id: r['id'] as string,\n mode: r['mode'] as 'discover' | 'shadow',\n startedAt: r['started_at'] as string,\n completedAt: (r['completed_at'] as string | null) ?? undefined,\n config: r['config'] as string,\n };\n }\n\n // ── Nodes ───────────────────────────────\n\n upsertNode(sessionId: string, node: DiscoveryNode, depth = 0): void {\n this.db.prepare(`\n INSERT OR REPLACE INTO nodes\n (id, session_id, type, name, discovered_via, discovered_at, depth, confidence, metadata, tags)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).run(\n node.id, sessionId, node.type, node.name, node.discoveredVia,\n new Date().toISOString(), depth, node.confidence,\n JSON.stringify(node.metadata ?? {}),\n JSON.stringify(node.tags ?? []),\n );\n }\n\n getNodes(sessionId: string): NodeRow[] {\n const rows = this.db.prepare('SELECT * FROM nodes WHERE session_id = ?').all(sessionId) as Record<string, unknown>[];\n return rows.map(r => ({\n id: r['id'] as string,\n sessionId: r['session_id'] as string,\n type: r['type'] as NodeRow['type'],\n name: r['name'] as string,\n discoveredVia: r['discovered_via'] as string,\n discoveredAt: r['discovered_at'] as string,\n depth: r['depth'] as number,\n confidence: r['confidence'] as number,\n metadata: JSON.parse(r['metadata'] as string) as Record<string, unknown>,\n tags: JSON.parse(r['tags'] as string) as string[],\n pathId: r['path_id'] as string | undefined,\n }));\n }\n\n // ── Edges ───────────────────────────────\n\n insertEdge(sessionId: string, edge: DiscoveryEdge): void {\n const id = crypto.randomUUID();\n this.db.prepare(`\n INSERT OR IGNORE INTO edges\n (id, session_id, source_id, target_id, relationship, evidence, confidence, discovered_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n `).run(\n id, sessionId, edge.sourceId, edge.targetId,\n edge.relationship, edge.evidence, edge.confidence,\n new Date().toISOString(),\n );\n }\n\n getEdges(sessionId: string): EdgeRow[] {\n const rows = this.db.prepare('SELECT * FROM edges WHERE session_id = ?').all(sessionId) as Record<string, unknown>[];\n return rows.map(r => ({\n id: r['id'] as string,\n sessionId: r['session_id'] as string,\n sourceId: r['source_id'] as string,\n targetId: r['target_id'] as string,\n relationship: r['relationship'] as EdgeRow['relationship'],\n evidence: r['evidence'] as string,\n confidence: r['confidence'] as number,\n discoveredAt: r['discovered_at'] as string,\n }));\n }\n\n // ── Events ──────────────────────────────\n\n insertEvent(sessionId: string, event: ActivityEvent, taskId?: string): void {\n const id = crypto.randomUUID();\n this.db.prepare(`\n INSERT INTO activity_events\n (id, session_id, task_id, timestamp, event_type, process, pid, target, target_type, port)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).run(\n id, sessionId, taskId ?? null, new Date().toISOString(),\n event.eventType, event.process, event.pid,\n event.target ?? null, event.targetType ?? null, event.port ?? null,\n );\n }\n\n getEvents(sessionId: string, since?: string): EventRow[] {\n const rows = since\n ? this.db.prepare('SELECT * FROM activity_events WHERE session_id = ? AND timestamp > ? ORDER BY timestamp').all(sessionId, since) as Record<string, unknown>[]\n : this.db.prepare('SELECT * FROM activity_events WHERE session_id = ? ORDER BY timestamp').all(sessionId) as Record<string, unknown>[];\n return rows.map(r => ({\n id: r['id'] as string,\n sessionId: r['session_id'] as string,\n taskId: r['task_id'] as string | undefined,\n timestamp: r['timestamp'] as string,\n eventType: r['event_type'] as EventRow['eventType'],\n process: r['process'] as string,\n pid: r['pid'] as number,\n target: r['target'] as string | undefined,\n targetType: r['target_type'] as EventRow['targetType'],\n port: r['port'] as number | undefined,\n durationMs: r['duration_ms'] as number | undefined,\n }));\n }\n\n // ── Tasks ───────────────────────────────\n\n startTask(sessionId: string, description?: string): string {\n const id = crypto.randomUUID();\n this.db.prepare(`\n INSERT INTO tasks (id, session_id, description, started_at, steps, involved_services, status)\n VALUES (?, ?, ?, ?, '[]', '[]', 'active')\n `).run(id, sessionId, description ?? null, new Date().toISOString());\n return id;\n }\n\n endCurrentTask(sessionId: string): void {\n this.db.prepare(`\n UPDATE tasks SET status = 'completed', completed_at = ?\n WHERE session_id = ? AND status = 'active'\n `).run(new Date().toISOString(), sessionId);\n }\n\n updateTaskDescription(sessionId: string, description: string): void {\n this.db.prepare(`\n UPDATE tasks SET description = ?\n WHERE session_id = ? AND status = 'active'\n `).run(description, sessionId);\n }\n\n getActiveTask(sessionId: string): TaskRow | undefined {\n const row = this.db.prepare(\n \"SELECT * FROM tasks WHERE session_id = ? AND status = 'active' LIMIT 1\"\n ).get(sessionId) as Record<string, unknown> | undefined;\n return row ? this.mapTask(row) : undefined;\n }\n\n getTasks(sessionId: string): TaskRow[] {\n const rows = this.db.prepare('SELECT * FROM tasks WHERE session_id = ? ORDER BY started_at').all(sessionId) as Record<string, unknown>[];\n return rows.map(r => this.mapTask(r));\n }\n\n private mapTask(r: Record<string, unknown>): TaskRow {\n return {\n id: r['id'] as string,\n sessionId: r['session_id'] as string,\n description: r['description'] as string | undefined,\n startedAt: r['started_at'] as string,\n completedAt: r['completed_at'] as string | undefined,\n steps: r['steps'] as string,\n involvedServices: r['involved_services'] as string,\n status: r['status'] as TaskRow['status'],\n isSOPCandidate: Boolean(r['is_sop_candidate']),\n };\n }\n\n // ── Workflows ───────────────────────────\n\n insertWorkflow(sessionId: string, data: Omit<WorkflowRow, 'id'>): void {\n const id = crypto.randomUUID();\n this.db.prepare(`\n INSERT INTO workflows\n (id, session_id, name, pattern, task_ids, occurrences,\n first_seen, last_seen, avg_duration_ms, involved_services)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).run(\n id, sessionId, data.name ?? null, data.pattern,\n data.taskIds, data.occurrences,\n data.firstSeen, data.lastSeen, data.avgDurationMs,\n data.involvedServices,\n );\n }\n\n getWorkflows(sessionId: string): WorkflowRow[] {\n const rows = this.db.prepare('SELECT * FROM workflows WHERE session_id = ?').all(sessionId) as Record<string, unknown>[];\n return rows.map(r => ({\n id: r['id'] as string,\n sessionId: r['session_id'] as string,\n name: r['name'] as string | undefined,\n pattern: r['pattern'] as string,\n taskIds: r['task_ids'] as string,\n occurrences: r['occurrences'] as number,\n firstSeen: r['first_seen'] as string,\n lastSeen: r['last_seen'] as string,\n avgDurationMs: r['avg_duration_ms'] as number,\n involvedServices: r['involved_services'] as string,\n }));\n }\n\n // ── SOPs ────────────────────────────────\n\n insertSOP(sop: { workflowId: string } & SOP): void {\n const id = crypto.randomUUID();\n this.db.prepare(`\n INSERT INTO sops\n (id, workflow_id, title, description, steps, involved_systems,\n estimated_duration, frequency, generated_at, confidence)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).run(\n id, sop.workflowId, sop.title, sop.description,\n JSON.stringify(sop.steps),\n JSON.stringify(sop.involvedSystems),\n sop.estimatedDuration, sop.frequency,\n new Date().toISOString(), sop.confidence,\n );\n }\n\n getSOPs(sessionId: string): Array<SOP & { id: string; workflowId: string }> {\n const rows = this.db.prepare(`\n SELECT s.* FROM sops s\n JOIN workflows w ON s.workflow_id = w.id\n WHERE w.session_id = ?\n `).all(sessionId) as Record<string, unknown>[];\n return rows.map(r => ({\n id: r['id'] as string,\n workflowId: r['workflow_id'] as string,\n title: r['title'] as string,\n description: r['description'] as string,\n steps: JSON.parse(r['steps'] as string) as SOP['steps'],\n involvedSystems: JSON.parse(r['involved_systems'] as string) as string[],\n estimatedDuration: r['estimated_duration'] as string,\n frequency: r['frequency'] as string,\n confidence: r['confidence'] as number,\n }));\n }\n\n // ── Approvals ───────────────────────────\n\n setApproval(pattern: string, action: 'save' | 'ignore' | 'auto'): void {\n this.db.prepare(`\n INSERT OR REPLACE INTO node_approvals (pattern, action, created_at) VALUES (?, ?, ?)\n `).run(pattern, action, new Date().toISOString());\n }\n\n getApproval(pattern: string): string | undefined {\n const row = this.db.prepare('SELECT action FROM node_approvals WHERE pattern = ?').get(pattern) as { action: string } | undefined;\n return row?.action;\n }\n\n // ── Stats ───────────────────────────────\n\n getStats(sessionId: string): { nodes: number; edges: number; events: number; tasks: number } {\n const nodes = (this.db.prepare('SELECT COUNT(*) as c FROM nodes WHERE session_id = ?').get(sessionId) as { c: number }).c;\n const edges = (this.db.prepare('SELECT COUNT(*) as c FROM edges WHERE session_id = ?').get(sessionId) as { c: number }).c;\n const events = (this.db.prepare('SELECT COUNT(*) as c FROM activity_events WHERE session_id = ?').get(sessionId) as { c: number }).c;\n const tasks = (this.db.prepare('SELECT COUNT(*) as c FROM tasks WHERE session_id = ?').get(sessionId) as { c: number }).c;\n return { nodes, edges, events, tasks };\n }\n}\n","import { z } from 'zod';\nimport type { CartographyDB } from './db.js';\nimport { NODE_TYPES, EDGE_RELATIONSHIPS, EVENT_TYPES, SOPStepSchema } from './types.js';\n\n// Lazy import to avoid hard-wiring SDK at module parse time\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype McpServer = any;\n\nexport function stripSensitive(target: string): string {\n try {\n const url = new URL(target.startsWith('http') ? target : `tcp://${target}`);\n return `${url.hostname}${url.port ? ':' + url.port : ''}`;\n } catch {\n return target\n .replace(/\\/.*$/, '')\n .replace(/\\?.*$/, '')\n .replace(/@.*:/, ':');\n }\n}\n\nexport async function createCartographyTools(db: CartographyDB, sessionId: string): Promise<McpServer> {\n // Dynamically import the SDK so missing package doesn't crash at load time\n const sdk = await import('@anthropic-ai/claude-code');\n const { tool, createSdkMcpServer } = sdk as {\n tool: (name: string, description: string, schema: z.ZodRawShape, handler: (args: Record<string, unknown>) => Promise<{ content: Array<{ type: string; text: string }> }>) => unknown;\n createSdkMcpServer: (opts: { name: string; version: string; tools: unknown[] }) => McpServer;\n };\n\n const tools = [\n tool('save_node', 'Infrastructure-Node speichern', {\n id: z.string(),\n type: z.enum(NODE_TYPES),\n name: z.string(),\n discoveredVia: z.string(),\n confidence: z.number().min(0).max(1),\n metadata: z.record(z.unknown()).optional(),\n tags: z.array(z.string()).optional(),\n }, async (args) => {\n const node = {\n id: stripSensitive(args['id'] as string),\n type: args['type'] as typeof NODE_TYPES[number],\n name: args['name'] as string,\n discoveredVia: args['discoveredVia'] as string,\n confidence: args['confidence'] as number,\n metadata: (args['metadata'] as Record<string, unknown>) ?? {},\n tags: (args['tags'] as string[]) ?? [],\n };\n db.upsertNode(sessionId, node);\n return { content: [{ type: 'text', text: `✓ Node: ${node.id}` }] };\n }),\n\n tool('save_edge', 'Verbindung zwischen zwei Nodes speichern', {\n sourceId: z.string(),\n targetId: z.string(),\n relationship: z.enum(EDGE_RELATIONSHIPS),\n evidence: z.string(),\n confidence: z.number().min(0).max(1),\n }, async (args) => {\n db.insertEdge(sessionId, {\n sourceId: args['sourceId'] as string,\n targetId: args['targetId'] as string,\n relationship: args['relationship'] as typeof EDGE_RELATIONSHIPS[number],\n evidence: args['evidence'] as string,\n confidence: args['confidence'] as number,\n });\n return { content: [{ type: 'text', text: `✓ ${args['sourceId']}→${args['targetId']}` }] };\n }),\n\n tool('save_event', 'Activity-Event (Prozess/Verbindung) speichern', {\n eventType: z.enum(EVENT_TYPES),\n process: z.string(),\n pid: z.number(),\n target: z.string().optional(),\n targetType: z.enum(NODE_TYPES).optional(),\n port: z.number().optional(),\n }, async (args) => {\n db.insertEvent(sessionId, {\n eventType: args['eventType'] as typeof EVENT_TYPES[number],\n process: args['process'] as string,\n pid: args['pid'] as number,\n target: args['target'] ? stripSensitive(args['target'] as string) : undefined,\n targetType: args['targetType'] as typeof NODE_TYPES[number] | undefined,\n port: args['port'] as number | undefined,\n });\n return { content: [{ type: 'text', text: `✓ ${args['eventType']}` }] };\n }),\n\n tool('get_catalog', 'Aktuellen Katalog abrufen (Duplikat-Check)', {\n includeEdges: z.boolean().default(true),\n }, async (args) => {\n const nodes = db.getNodes(sessionId);\n const edges = (args['includeEdges'] as boolean) ? db.getEdges(sessionId) : [];\n return {\n content: [{\n type: 'text',\n text: JSON.stringify({\n count: { nodes: nodes.length, edges: edges.length },\n nodeIds: nodes.map(n => n.id),\n }),\n }],\n };\n }),\n\n tool('manage_task', 'Task starten, beenden oder beschreiben', {\n action: z.enum(['start', 'end', 'describe']),\n description: z.string().optional(),\n }, async (args) => {\n const action = args['action'] as string;\n if (action === 'start') {\n const id = db.startTask(sessionId, args['description'] as string | undefined);\n return { content: [{ type: 'text', text: `✓ Task gestartet: ${id}` }] };\n }\n if (action === 'end') {\n db.endCurrentTask(sessionId);\n return { content: [{ type: 'text', text: '✓ Task beendet' }] };\n }\n db.updateTaskDescription(sessionId, args['description'] as string);\n return { content: [{ type: 'text', text: '✓ Beschreibung aktualisiert' }] };\n }),\n\n tool('save_sop', 'Standard Operating Procedure speichern', {\n workflowId: z.string(),\n title: z.string(),\n description: z.string(),\n steps: z.array(SOPStepSchema),\n involvedSystems: z.array(z.string()),\n estimatedDuration: z.string(),\n frequency: z.string(),\n confidence: z.number().min(0).max(1),\n }, async (args) => {\n db.insertSOP({\n workflowId: args['workflowId'] as string,\n title: args['title'] as string,\n description: args['description'] as string,\n steps: args['steps'] as ReturnType<typeof SOPStepSchema.parse>[],\n involvedSystems: args['involvedSystems'] as string[],\n estimatedDuration: args['estimatedDuration'] as string,\n frequency: args['frequency'] as string,\n confidence: args['confidence'] as number,\n });\n return { content: [{ type: 'text', text: `✓ SOP: ${args['title']}` }] };\n }),\n ];\n\n return createSdkMcpServer({\n name: 'cartography',\n version: '0.1.0',\n tools,\n });\n}\n","// PreToolUse Safety Hook — enforces read-only policy on all Bash calls\n\nimport type { HookCallback } from '@anthropic-ai/claude-code';\n\n// Word-boundary matched dangerous commands\nconst BLOCKED_CMDS =\n /\\b(rm|mv|cp|dd|mkfs|chmod|chown|chgrp|kill|killall|pkill|reboot|shutdown|poweroff|halt|systemctl\\s+(start|stop|restart|enable|disable)|service\\s+(start|stop|restart)|docker\\s+(rm|rmi|stop|kill|exec|run|build|push)|kubectl\\s+(delete|apply|edit|exec|run|create|patch)|apt|yum|dnf|pacman|pip\\s+install|npm\\s+(install|uninstall)|curl\\s+.*-X\\s*(POST|PUT|DELETE|PATCH)|wget\\s+-O|tee\\s)\\b/i;\n// Redirect operators (no word boundary needed)\nconst BLOCKED_REDIRECTS = />>|>[^>]/;\n\nexport type { HookCallback };\n\nexport const safetyHook: HookCallback = async (input) => {\n // Only intercept PreToolUse events (other hook events don't have tool_name)\n if (!('tool_name' in input)) return {};\n if ((input as { tool_name: string }).tool_name !== 'Bash') return {};\n\n const cmd = ((input as { tool_input: { command?: string } }).tool_input)?.command ?? '';\n\n if (BLOCKED_CMDS.test(cmd) || BLOCKED_REDIRECTS.test(cmd)) {\n return {\n hookSpecificOutput: {\n hookEventName: 'PreToolUse',\n permissionDecision: 'deny',\n permissionDecisionReason: `BLOCKED: \"${cmd}\" — read-only policy`,\n },\n };\n }\n\n return {\n hookSpecificOutput: {\n hookEventName: 'PreToolUse',\n permissionDecision: 'allow',\n },\n };\n};\n","import type { CartographyDB } from './db.js';\nimport { createCartographyTools } from './tools.js';\nimport { safetyHook } from './safety.js';\nimport type { CartographyConfig, TaskRow } from './types.js';\n\n// ── runDiscovery ─────────────────────────────────────────────────────────────\n\nexport async function runDiscovery(\n config: CartographyConfig,\n db: CartographyDB,\n sessionId: string,\n onOutput?: (text: string) => void,\n): Promise<void> {\n const { query } = await import('@anthropic-ai/claude-code');\n const tools = await createCartographyTools(db, sessionId);\n\n const systemPrompt = `Du bist ein Infrastruktur-Discovery-Agent.\nKartographiere die gesamte Systemlandschaft.\n\nSTRATEGIE:\n1. ss -tlnp + ps aux → Überblick\n2. Jeden Service tiefer (Datenbanken→Tabellen, APIs→Endpoints, Queues→Topics)\n3. save_node + save_edge für alles. get_catalog → keine Duplikate.\n4. Config-Files folgen: .env (nur Host:Port!), docker-compose.yml, application.yml\n5. Backtrack wenn Spur erschöpft. Stop wenn alles explored.\n\nPORT-MAPPING: 5432=postgres, 3306=mysql, 27017=mongodb, 6379=redis,\n9092=kafka, 5672=rabbitmq, 80/443/8080/3000=web_service,\n9090=prometheus, 8500=consul, 8200=vault, 2379=etcd\n\nREGELN:\n- NUR read-only Commands (ss, ps, cat, head, curl -s, docker inspect, kubectl get)\n- Targets NUR Host:Port — KEINE URLs, Pfade, Credentials\n- Node IDs: \"{type}:{host}:{port}\" oder \"{type}:{name}\"\n- Confidence: 0.9 direkt beobachtet, 0.7 aus Config, 0.5 Vermutung\n- KEINE Credentials speichern\n\nEntrypoints: ${config.entryPoints.join(', ')}`;\n\n for await (const msg of query({\n prompt: systemPrompt,\n options: {\n model: config.agentModel,\n maxTurns: config.maxTurns,\n customSystemPrompt: systemPrompt,\n mcpServers: { cartography: tools },\n allowedTools: [\n 'Bash',\n 'mcp__cartograph__save_node',\n 'mcp__cartograph__save_edge',\n 'mcp__cartograph__get_catalog',\n ],\n hooks: {\n PreToolUse: [{ matcher: 'Bash', hooks: [safetyHook] }],\n },\n permissionMode: 'bypassPermissions',\n },\n })) {\n if (msg.type === 'assistant' && onOutput) {\n for (const block of msg.message.content) {\n if (block.type === 'text') {\n onOutput(block.text);\n }\n }\n }\n if (msg.type === 'result') return;\n }\n}\n\n// ── runShadowCycle ───────────────────────────────────────────────────────────\n\nexport async function runShadowCycle(\n config: CartographyConfig,\n db: CartographyDB,\n sessionId: string,\n prevSnapshot: string,\n currSnapshot: string,\n onOutput?: (msg: unknown) => void,\n): Promise<void> {\n const { query } = await import('@anthropic-ai/claude-code');\n const tools = await createCartographyTools(db, sessionId);\n\n const prompt = `Analysiere den Diff zwischen diesen beiden System-Snapshots.\nFinde:\n- Neue/geschlossene TCP-Verbindungen → save_event\n- Neue/beendete Prozesse → save_event\n- Bisher unbekannte Services → get_catalog prüfen, dann save_node\n- Task-Grenzen (Inaktivität, Tool-Wechsel) → manage_task\ntarget = NUR Host:Port. Kurz und effizient.\n\n=== VORHER ===\n${prevSnapshot}\n\n=== JETZT ===\n${currSnapshot}`;\n\n for await (const msg of query({\n prompt,\n options: {\n model: config.shadowModel,\n maxTurns: 5,\n mcpServers: { cartography: tools },\n allowedTools: [\n 'mcp__cartograph__save_event',\n 'mcp__cartograph__save_node',\n 'mcp__cartograph__save_edge',\n 'mcp__cartograph__get_catalog',\n 'mcp__cartograph__manage_task',\n ],\n permissionMode: 'bypassPermissions',\n },\n })) {\n if (onOutput) onOutput(msg);\n }\n}\n\n// ── generateSOPs ─────────────────────────────────────────────────────────────\n\nexport async function generateSOPs(db: CartographyDB, sessionId: string): Promise<number> {\n const Anthropic = (await import('@anthropic-ai/sdk')).default;\n const client = new Anthropic();\n\n const tasks = db.getTasks(sessionId).filter(t => t.status === 'completed');\n if (tasks.length === 0) return 0;\n\n // Cluster tasks by involved services\n const clusters = clusterTasks(tasks);\n let generated = 0;\n\n for (const cluster of clusters) {\n const workflowId = crypto.randomUUID();\n const involved = JSON.parse(cluster[0]?.involvedServices ?? '[]') as string[];\n\n const taskDescriptions = cluster\n .map((t, i) => `Task ${i + 1}: ${t.description ?? 'Unnamed'}\\nSteps: ${t.steps}`)\n .join('\\n\\n');\n\n const response = await client.messages.create({\n model: 'claude-sonnet-4-5-20250929',\n max_tokens: 2048,\n messages: [{\n role: 'user',\n content: `Generiere eine SOP (Standard Operating Procedure) für diesen wiederkehrenden Workflow.\nAntworte NUR mit validen JSON im Format:\n{\n \"title\": \"...\",\n \"description\": \"...\",\n \"steps\": [{\"order\": 1, \"instruction\": \"...\", \"tool\": \"...\", \"target\": \"...\", \"notes\": \"...\"}],\n \"involvedSystems\": [\"...\"],\n \"estimatedDuration\": \"~N Minuten\",\n \"frequency\": \"Xmal täglich\",\n \"confidence\": 0.8\n}\n\nTasks:\n${taskDescriptions}\n\nBeteiligte Services: ${involved.join(', ')}`,\n }],\n });\n\n const text = response.content[0]?.type === 'text' ? response.content[0].text : '';\n\n try {\n const jsonMatch = text.match(/\\{[\\s\\S]*\\}/);\n if (!jsonMatch) continue;\n const parsed = JSON.parse(jsonMatch[0]) as {\n title: string;\n description: string;\n steps: Array<{ order: number; instruction: string; tool: string; target?: string; notes?: string }>;\n involvedSystems: string[];\n estimatedDuration: string;\n frequency: string;\n confidence: number;\n };\n\n db.insertSOP({ workflowId, ...parsed });\n generated++;\n } catch {\n // Skip malformed responses\n }\n }\n\n return generated;\n}\n\nfunction clusterTasks(tasks: TaskRow[]): TaskRow[][] {\n // Simple clustering: group by overlapping involved services\n const clusters: TaskRow[][] = [];\n const assigned = new Set<string>();\n\n for (const task of tasks) {\n if (assigned.has(task.id)) continue;\n\n const cluster = [task];\n assigned.add(task.id);\n\n const taskServices = new Set(JSON.parse(task.involvedServices ?? '[]') as string[]);\n\n for (const other of tasks) {\n if (assigned.has(other.id)) continue;\n const otherServices = new Set(JSON.parse(other.involvedServices ?? '[]') as string[]);\n // Check overlap\n const overlap = [...taskServices].filter(s => otherServices.has(s));\n if (overlap.length > 0) {\n cluster.push(other);\n assigned.add(other.id);\n }\n }\n\n clusters.push(cluster);\n }\n\n return clusters;\n}\n","import { mkdirSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { CartographyDB } from './db.js';\nimport type { NodeRow, EdgeRow, SOP } from './types.js';\n\n// ── Icons & Labels ───────────────────────────────────────────────────────────\n\nconst MERMAID_ICONS: Record<string, string> = {\n host: '🖥️',\n database_server: '🗄️',\n database: '🗄️',\n table: '📋',\n web_service: '🌐',\n api_endpoint: '🔌',\n cache_server: '⚡',\n message_broker: '📨',\n queue: '📬',\n topic: '📢',\n container: '📦',\n pod: '☸️',\n k8s_cluster: '☸️',\n config_file: '📄',\n unknown: '❓',\n};\n\nconst EDGE_LABELS: Record<string, string> = {\n connects_to: '',\n reads_from: 'reads',\n writes_to: 'writes',\n calls: 'calls',\n contains: 'contains',\n depends_on: 'depends',\n};\n\n// ── Mermaid ──────────────────────────────────────────────────────────────────\n\nfunction sanitize(id: string): string {\n return id.replace(/[^a-zA-Z0-9_]/g, '_');\n}\n\nfunction groupByParent(nodes: NodeRow[]): Map<string, NodeRow[]> {\n const groups = new Map<string, NodeRow[]>();\n for (const node of nodes) {\n // Group by host portion of id or by type\n const group = node.id.split(':')[1] ?? node.type;\n if (!groups.has(group)) groups.set(group, []);\n groups.get(group)!.push(node);\n }\n return groups;\n}\n\nexport function generateTopologyMermaid(nodes: NodeRow[], edges: EdgeRow[]): string {\n const lines: string[] = ['graph TB'];\n const groups = groupByParent(nodes);\n\n for (const [group, groupNodes] of groups) {\n if (groups.size > 1) {\n lines.push(` subgraph ${sanitize(group)}`);\n }\n for (const node of groupNodes) {\n const icon = MERMAID_ICONS[node.type] ?? '❓';\n lines.push(` ${sanitize(node.id)}[\"${icon} ${node.name}\"]`);\n }\n if (groups.size > 1) {\n lines.push(' end');\n }\n }\n\n for (const edge of edges) {\n const label = EDGE_LABELS[edge.relationship] ?? '';\n const arrow = label ? `-->|\"${label}\"|` : '-->';\n lines.push(` ${sanitize(edge.sourceId)} ${arrow} ${sanitize(edge.targetId)}`);\n }\n\n return lines.join('\\n');\n}\n\nexport function generateDependencyMermaid(nodes: NodeRow[], edges: EdgeRow[]): string {\n const lines: string[] = ['graph LR'];\n\n const depEdges = edges.filter(e =>\n ['calls', 'reads_from', 'writes_to', 'depends_on'].includes(e.relationship)\n );\n\n const usedIds = new Set<string>();\n for (const edge of depEdges) {\n usedIds.add(edge.sourceId);\n usedIds.add(edge.targetId);\n }\n\n const usedNodes = nodes.filter(n => usedIds.has(n.id));\n for (const node of usedNodes) {\n const icon = MERMAID_ICONS[node.type] ?? '❓';\n lines.push(` ${sanitize(node.id)}[\"${icon} ${node.name}\"]`);\n }\n\n for (const edge of depEdges) {\n const label = EDGE_LABELS[edge.relationship] ?? '';\n const arrow = label ? `-->|\"${label}\"|` : '-->';\n lines.push(` ${sanitize(edge.sourceId)} ${arrow} ${sanitize(edge.targetId)}`);\n }\n\n return lines.join('\\n');\n}\n\nexport function generateWorkflowMermaid(sop: SOP): string {\n const lines: string[] = ['flowchart TD'];\n\n for (const step of sop.steps) {\n const nodeId = `S${step.order}`;\n const label = `${step.order}. ${step.instruction.substring(0, 60)}`;\n lines.push(` ${nodeId}[\"${label}\"]`);\n\n if (step.order > 1) {\n lines.push(` S${step.order - 1} --> ${nodeId}`);\n }\n }\n\n return lines.join('\\n');\n}\n\n// ── Backstage YAML ───────────────────────────────────────────────────────────\n\nexport function exportBackstageYAML(nodes: NodeRow[], edges: EdgeRow[], org?: string): string {\n const owner = org ?? 'unknown';\n const docs: string[] = [];\n\n for (const node of nodes) {\n const isComponent = ['web_service', 'container', 'pod'].includes(node.type);\n const isAPI = node.type === 'api_endpoint';\n const kind = isComponent ? 'Component' : isAPI ? 'API' : 'Resource';\n\n const deps = edges\n .filter(e => e.sourceId === node.id)\n .map(e => ` - resource:default/${sanitize(e.targetId)}`);\n\n const doc = [\n `apiVersion: backstage.io/v1alpha1`,\n `kind: ${kind}`,\n `metadata:`,\n ` name: ${sanitize(node.id)}`,\n ` annotations:`,\n ` cartography/discovered-at: \"${node.discoveredAt}\"`,\n ` cartography/confidence: \"${node.confidence}\"`,\n `spec:`,\n ` type: ${node.type}`,\n ` lifecycle: production`,\n ` owner: ${owner}`,\n ...(deps.length > 0 ? [' dependsOn:', ...deps] : []),\n ].join('\\n');\n\n docs.push(doc);\n }\n\n return docs.join('\\n---\\n');\n}\n\n// ── JSON ─────────────────────────────────────────────────────────────────────\n\nexport function exportJSON(db: CartographyDB, sessionId: string): string {\n const nodes = db.getNodes(sessionId);\n const edges = db.getEdges(sessionId);\n const events = db.getEvents(sessionId);\n const tasks = db.getTasks(sessionId);\n const sops = db.getSOPs(sessionId);\n const stats = db.getStats(sessionId);\n\n return JSON.stringify({\n sessionId,\n exportedAt: new Date().toISOString(),\n stats,\n nodes,\n edges,\n events,\n tasks,\n sops,\n }, null, 2);\n}\n\n// ── HTML (D3.js Force-Graph) ──────────────────────────────────────────────────\n\nexport function exportHTML(nodes: NodeRow[], edges: EdgeRow[]): string {\n const graphData = JSON.stringify({\n nodes: nodes.map(n => ({ id: n.id, name: n.name, type: n.type, confidence: n.confidence })),\n links: edges.map(e => ({ source: e.sourceId, target: e.targetId, relationship: e.relationship })),\n });\n\n return `<!DOCTYPE html>\n<html lang=\"de\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Cartography — Topology</title>\n <script src=\"https://d3js.org/d3.v7.min.js\"></script>\n <style>\n body { margin: 0; background: #1a1a2e; color: #eee; font-family: monospace; }\n svg { width: 100vw; height: 100vh; }\n .node circle { stroke: #fff; stroke-width: 1.5px; }\n .node text { font-size: 10px; fill: #eee; }\n .link { stroke: #666; stroke-opacity: 0.6; }\n #info { position: fixed; top: 10px; right: 10px; background: rgba(0,0,0,0.7);\n padding: 10px; border-radius: 4px; font-size: 12px; }\n </style>\n</head>\n<body>\n<div id=\"info\">\n <strong>Cartography</strong><br>\n Nodes: ${nodes.length} | Edges: ${edges.length}<br>\n <small>Drag to explore</small>\n</div>\n<svg></svg>\n<script>\nconst data = ${graphData};\n\nconst TYPE_COLORS = {\n host: '#4a9eff', database_server: '#ff6b6b', database: '#ff8c42',\n web_service: '#6bcb77', api_endpoint: '#4d96ff', cache_server: '#ffd93d',\n message_broker: '#c77dff', queue: '#e0aaff', topic: '#9d4edd',\n container: '#48cae4', pod: '#00b4d8', k8s_cluster: '#0077b6',\n config_file: '#adb5bd', unknown: '#6c757d',\n};\n\nconst svg = d3.select('svg');\nconst width = window.innerWidth, height = window.innerHeight;\nconst g = svg.append('g');\n\nsvg.call(d3.zoom().on('zoom', e => g.attr('transform', e.transform)));\n\nconst sim = d3.forceSimulation(data.nodes)\n .force('link', d3.forceLink(data.links).id(d => d.id).distance(100))\n .force('charge', d3.forceManyBody().strength(-200))\n .force('center', d3.forceCenter(width / 2, height / 2));\n\nconst link = g.append('g').selectAll('line')\n .data(data.links).join('line').attr('class', 'link');\n\nconst node = g.append('g').selectAll('g')\n .data(data.nodes).join('g').attr('class', 'node')\n .call(d3.drag()\n .on('start', (e, d) => { if (!e.active) sim.alphaTarget(0.3).restart(); d.fx = d.x; d.fy = d.y; })\n .on('drag', (e, d) => { d.fx = e.x; d.fy = e.y; })\n .on('end', (e, d) => { if (!e.active) sim.alphaTarget(0); d.fx = null; d.fy = null; })\n );\n\nnode.append('circle').attr('r', 8).attr('fill', d => TYPE_COLORS[d.type] || '#aaa');\nnode.append('text').attr('dx', 12).attr('dy', '.35em').text(d => d.name);\nnode.append('title').text(d => \\`\\${d.type}: \\${d.id}\\nConfidence: \\${d.confidence}\\`);\n\nsim.on('tick', () => {\n link.attr('x1', d => d.source.x).attr('y1', d => d.source.y)\n .attr('x2', d => d.target.x).attr('y2', d => d.target.y);\n node.attr('transform', d => \\`translate(\\${d.x},\\${d.y})\\`);\n});\n</script>\n</body>\n</html>`;\n}\n\n// ── SOP Markdown ─────────────────────────────────────────────────────────────\n\nexport function exportSOPMarkdown(sop: SOP): string {\n const lines: string[] = [\n `# ${sop.title}`,\n '',\n `**Beschreibung:** ${sop.description}`,\n `**Systeme:** ${sop.involvedSystems.join(', ')}`,\n `**Dauer:** ${sop.estimatedDuration}`,\n `**Häufigkeit:** ${sop.frequency}`,\n `**Confidence:** ${sop.confidence.toFixed(2)}`,\n '',\n '## Schritte',\n '',\n ];\n\n for (const step of sop.steps) {\n lines.push(`${step.order}. **${step.tool}**${step.target ? ` → \\`${step.target}\\`` : ''}`);\n lines.push(` ${step.instruction}`);\n if (step.notes) lines.push(` _${step.notes}_`);\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\n// ── exportAll ─────────────────────────────────────────────────────────────────\n\nexport function exportAll(\n db: CartographyDB,\n sessionId: string,\n outputDir: string,\n formats: string[] = ['mermaid', 'json', 'yaml', 'html', 'sops'],\n): void {\n mkdirSync(outputDir, { recursive: true });\n mkdirSync(join(outputDir, 'sops'), { recursive: true });\n mkdirSync(join(outputDir, 'workflows'), { recursive: true });\n\n const nodes = db.getNodes(sessionId);\n const edges = db.getEdges(sessionId);\n\n if (formats.includes('mermaid')) {\n writeFileSync(join(outputDir, 'topology.mermaid'), generateTopologyMermaid(nodes, edges));\n writeFileSync(join(outputDir, 'dependencies.mermaid'), generateDependencyMermaid(nodes, edges));\n process.stderr.write('✓ topology.mermaid, dependencies.mermaid\\n');\n }\n\n if (formats.includes('json')) {\n writeFileSync(join(outputDir, 'catalog.json'), exportJSON(db, sessionId));\n process.stderr.write('✓ catalog.json\\n');\n }\n\n if (formats.includes('yaml')) {\n writeFileSync(join(outputDir, 'catalog-info.yaml'), exportBackstageYAML(nodes, edges));\n process.stderr.write('✓ catalog-info.yaml\\n');\n }\n\n if (formats.includes('html')) {\n writeFileSync(join(outputDir, 'topology.html'), exportHTML(nodes, edges));\n process.stderr.write('✓ topology.html\\n');\n }\n\n if (formats.includes('sops')) {\n const sops = db.getSOPs(sessionId);\n for (const sop of sops) {\n const filename = sop.title.toLowerCase().replace(/[^a-z0-9]+/g, '-') + '.md';\n writeFileSync(join(outputDir, 'sops', filename), exportSOPMarkdown(sop));\n\n const wfFilename = `workflow-${sop.workflowId.substring(0, 8)}.mermaid`;\n writeFileSync(join(outputDir, 'workflows', wfFilename), generateWorkflowMermaid(sop));\n }\n if (sops.length > 0) {\n process.stderr.write(`✓ ${sops.length} SOPs + workflow diagrams\\n`);\n }\n }\n}\n","import { execSync, spawn } from 'node:child_process';\nimport { existsSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs';\nimport { CartographyDB } from './db.js';\nimport { IPCServer, cleanStaleSocket } from './ipc.js';\nimport { NotificationService } from './notify.js';\nimport { runShadowCycle } from './agent.js';\nimport type { CartographyConfig, ShadowStatus } from './types.js';\n\n// ── Snapshot ─────────────────────────────────────────────────────────────────\n\nexport function takeSnapshot(config: CartographyConfig): string {\n const run = (cmd: string): string => {\n try {\n return execSync(cmd, { stdio: ['pipe', 'pipe', 'pipe'], timeout: 5000 }).toString();\n } catch {\n return `(${cmd}: not available)`;\n }\n };\n\n const ss = run('ss -tnp 2>/dev/null || ss -tn 2>/dev/null || echo \"ss not available\"');\n const ps = run('ps aux --sort=-start_time 2>/dev/null | head -50');\n\n let win = '';\n if (config.trackWindowFocus) {\n try {\n win = execSync('xdotool getactivewindow getwindowname 2>/dev/null', {\n stdio: ['pipe', 'pipe', 'pipe'],\n timeout: 2000,\n }).toString().trim();\n } catch {\n win = '';\n }\n }\n\n return `=== TCP ===\\n${ss}\\n=== PS ===\\n${ps}\\n=== Window ===\\n${win}`;\n}\n\n// ── ShadowDaemon ─────────────────────────────────────────────────────────────\n\nexport class ShadowDaemon {\n private running = false;\n private prevSnapshot = '';\n private cyclesRun = 0;\n private cyclesSkipped = 0;\n\n constructor(\n private config: CartographyConfig,\n private db: CartographyDB,\n private ipc: IPCServer,\n private notify: NotificationService,\n ) {}\n\n async run(): Promise<void> {\n this.running = true;\n const sessionId = this.db.createSession('shadow', this.config);\n\n process.on('SIGTERM', () => this.stop());\n process.on('SIGINT', () => this.stop());\n\n while (this.running) {\n const snapshot = takeSnapshot(this.config);\n\n if (snapshot !== this.prevSnapshot) {\n try {\n await runShadowCycle(\n this.config,\n this.db,\n sessionId,\n this.prevSnapshot,\n snapshot,\n (msg) => {\n if (this.ipc.hasClients()) {\n this.ipc.broadcast({ type: 'agent-output', text: JSON.stringify(msg) });\n }\n },\n );\n this.cyclesRun++;\n } catch (err) {\n process.stderr.write(`⚠ Cycle error: ${err}\\n`);\n }\n this.prevSnapshot = snapshot;\n } else {\n this.cyclesSkipped++;\n }\n\n // Broadcast status\n const status = this.getStatus(sessionId);\n this.ipc.broadcast({ type: 'status', data: status });\n\n // Desktop notification if no clients attached\n if (!this.ipc.hasClients()) {\n const stats = this.db.getStats(sessionId);\n if (stats.events > 0 && this.cyclesRun % 10 === 0) {\n this.notify.workflowDetected(stats.tasks, `${stats.events} events so far`);\n }\n }\n\n await sleep(this.config.pollIntervalMs);\n }\n\n this.db.endSession(sessionId);\n this.ipc.stop();\n cleanup(this.config);\n }\n\n stop(): void {\n this.running = false;\n }\n\n private getStatus(sessionId: string): ShadowStatus {\n const stats = this.db.getStats(sessionId);\n return {\n pid: process.pid,\n uptime: process.uptime(),\n nodeCount: stats.nodes,\n eventCount: stats.events,\n taskCount: stats.tasks,\n pendingPrompts: 0,\n autoSave: this.config.autoSaveNodes,\n mode: this.config.shadowMode,\n agentActive: false,\n cyclesRun: this.cyclesRun,\n cyclesSkipped: this.cyclesSkipped,\n };\n }\n}\n\n// ── Daemon Lifecycle ──────────────────────────────────────────────────────────\n\nexport function forkDaemon(config: CartographyConfig): number {\n // The daemon entry is the same cli.ts but with --daemon flag via env\n const child = spawn(\n process.execPath,\n [process.argv[1] ?? 'cartography', 'shadow', 'start', '--foreground', '--daemon-child'],\n {\n detached: true,\n stdio: 'ignore',\n env: {\n ...process.env,\n CARTOGRAPHYY_DAEMON: '1',\n CARTOGRAPHYY_CONFIG: JSON.stringify(config),\n },\n }\n );\n child.unref();\n\n const pid = child.pid;\n if (!pid) throw new Error('Failed to fork daemon');\n\n writeFileSync(config.pidFile, String(pid), 'utf8');\n return pid;\n}\n\nexport function isDaemonRunning(pidFile: string): { running: boolean; pid?: number } {\n if (!existsSync(pidFile)) return { running: false };\n\n try {\n const pid = parseInt(readFileSync(pidFile, 'utf8').trim(), 10);\n if (isNaN(pid)) return { running: false };\n\n process.kill(pid, 0); // throws if process doesn't exist\n return { running: true, pid };\n } catch {\n // Stale PID file\n try { unlinkSync(pidFile); } catch { /* already gone */ }\n return { running: false };\n }\n}\n\nexport function stopDaemon(pidFile: string): boolean {\n const { running, pid } = isDaemonRunning(pidFile);\n if (!running || !pid) return false;\n\n try {\n process.kill(pid, 'SIGTERM');\n try { unlinkSync(pidFile); } catch { /* already gone */ }\n return true;\n } catch {\n return false;\n }\n}\n\nfunction cleanup(config: CartographyConfig): void {\n try { unlinkSync(config.socketPath); } catch { /* already gone */ }\n try { unlinkSync(config.pidFile); } catch { /* already gone */ }\n}\n\n// ── startDaemonProcess ───────────────────────────────────────────────────────\n\nexport async function startDaemonProcess(config: CartographyConfig): Promise<void> {\n cleanStaleSocket(config.socketPath);\n\n const db = new CartographyDB(config.dbPath);\n const ipc = new IPCServer();\n const notify = new NotificationService(config.enableNotifications);\n\n ipc.start(config.socketPath);\n\n const daemon = new ShadowDaemon(config, db, ipc, notify);\n await daemon.run();\n\n db.close();\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n","import net from 'node:net';\nimport { EventEmitter } from 'node:events';\nimport { chmodSync, existsSync, unlinkSync } from 'node:fs';\nimport type { DaemonMessage, ClientMessage } from './types.js';\n\n// ── IPCServer ────────────────────────────────────────────────────────────────\n\nexport class IPCServer extends EventEmitter {\n private server: net.Server | null = null;\n private clients: Set<net.Socket> = new Set();\n\n start(socketPath: string): void {\n this.server = net.createServer((socket) => {\n this.clients.add(socket);\n this.emit('client-connect', socket);\n\n let buf = '';\n socket.on('data', (chunk) => {\n buf += chunk.toString();\n const lines = buf.split('\\n');\n buf = lines.pop() ?? '';\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n const msg = JSON.parse(line) as ClientMessage;\n this.emit('message', msg, socket);\n } catch {\n // Ignore malformed JSON\n }\n }\n });\n\n socket.on('close', () => {\n this.clients.delete(socket);\n this.emit('client-disconnect', socket);\n });\n\n socket.on('error', () => {\n this.clients.delete(socket);\n });\n });\n\n this.server.listen(socketPath, () => {\n try {\n chmodSync(socketPath, 0o600);\n } catch {\n // chmod may fail in some environments — non-fatal\n }\n });\n }\n\n broadcast(msg: DaemonMessage): void {\n const line = JSON.stringify(msg) + '\\n';\n for (const socket of this.clients) {\n try {\n socket.write(line);\n } catch {\n this.clients.delete(socket);\n }\n }\n }\n\n hasClients(): boolean {\n return this.clients.size > 0;\n }\n\n stop(): void {\n for (const socket of this.clients) {\n socket.destroy();\n }\n this.clients.clear();\n this.server?.close();\n this.server = null;\n }\n}\n\n// ── IPCClient ────────────────────────────────────────────────────────────────\n\nexport class IPCClient extends EventEmitter {\n private socket: net.Socket | null = null;\n\n connect(socketPath: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const socket = net.createConnection(socketPath, () => {\n resolve();\n });\n\n socket.on('error', (err) => {\n reject(err);\n });\n\n let buf = '';\n socket.on('data', (chunk) => {\n buf += chunk.toString();\n const lines = buf.split('\\n');\n buf = lines.pop() ?? '';\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n const msg = JSON.parse(line) as DaemonMessage;\n this.emit('message', msg);\n } catch {\n // Ignore malformed JSON\n }\n }\n });\n\n socket.on('close', () => {\n this.emit('disconnect');\n });\n\n this.socket = socket;\n });\n }\n\n send(msg: ClientMessage): void {\n if (!this.socket) return;\n try {\n this.socket.write(JSON.stringify(msg) + '\\n');\n } catch {\n // Socket may have closed\n }\n }\n\n disconnect(): void {\n this.socket?.destroy();\n this.socket = null;\n }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\nexport function cleanStaleSocket(socketPath: string): void {\n if (existsSync(socketPath)) {\n try {\n unlinkSync(socketPath);\n } catch {\n // Already gone\n }\n }\n}\n","import notifier from 'node-notifier';\n\nexport class NotificationService {\n constructor(private enabled: boolean) {}\n\n nodeDiscovered(nodeId: string, via: string): void {\n this.send(`📍 Node entdeckt: ${nodeId}`, `Via: ${via}`);\n }\n\n workflowDetected(count: number, desc: string): void {\n this.send(`🔄 ${count} Workflow(s) erkannt`, desc);\n }\n\n taskBoundary(gapMinutes: number): void {\n this.send('⏸ Task-Grenze erkannt', `${gapMinutes} Minuten Inaktivität`);\n }\n\n private send(title: string, message: string): void {\n if (!this.enabled) return;\n\n try {\n notifier.notify({ title, message, sound: false });\n } catch {\n // Notifications not available — silently skip\n }\n }\n}\n","import { IPCClient } from './ipc.js';\nimport { startDaemonProcess } from './daemon.js';\nimport type { CartographyConfig, DaemonMessage, ShadowStatus } from './types.js';\n\n// ── ForegroundClient ─────────────────────────────────────────────────────────\n// Runs daemon + terminal UI in the same process (no fork)\n\nexport class ForegroundClient {\n async run(config: CartographyConfig): Promise<void> {\n process.stderr.write('👁 Cartography Shadow (foreground) gestartet\\n');\n process.stderr.write(` Intervall: ${config.pollIntervalMs / 1000}s | Modell: ${config.shadowModel}\\n`);\n process.stderr.write(' Ctrl+C zum Beenden\\n\\n');\n\n // Run daemon inline (blocks until SIGINT/SIGTERM)\n await startDaemonProcess({ ...config, shadowMode: 'foreground' });\n }\n}\n\n// ── AttachClient ─────────────────────────────────────────────────────────────\n// Connects to a running daemon via Unix socket and provides terminal UI\n\nexport class AttachClient {\n async attach(socketPath: string): Promise<void> {\n const client = new IPCClient();\n\n try {\n await client.connect(socketPath);\n } catch {\n process.stderr.write(`❌ Kann nicht an Daemon ankoppeln: ${socketPath}\\n`);\n process.stderr.write(' Ist der Daemon gestartet? cartography shadow status\\n');\n process.exitCode = 1;\n return;\n }\n\n process.stderr.write('📡 Verbunden mit Shadow-Daemon\\n');\n process.stderr.write(' [T] Neuer Task [S] Status [D] Trennen [Q] Daemon stoppen\\n\\n');\n\n // Set raw mode for hotkeys\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(true);\n }\n process.stdin.resume();\n process.stdin.setEncoding('utf8');\n\n process.stdin.on('data', (key: string) => {\n const k = key.toLowerCase();\n\n if (k === 't') {\n process.stdout.write('\\nTask-Beschreibung: ');\n // Simple readline for description\n process.stdin.once('data', (desc: string) => {\n client.send({ type: 'task-description', description: desc.trim() });\n client.send({ type: 'command', command: 'new-task' });\n process.stdout.write(`\\n✓ Neuer Task gestartet: ${desc.trim()}\\n`);\n });\n return;\n }\n\n if (k === 's') {\n client.send({ type: 'command', command: 'status' });\n return;\n }\n\n if (k === 'd' || k === '\\u0003') {\n // Detach (Ctrl+C also)\n process.stderr.write('\\n📡 Getrennt. Daemon läuft weiter.\\n');\n client.disconnect();\n if (process.stdin.isTTY) process.stdin.setRawMode(false);\n process.stdin.pause();\n return;\n }\n\n if (k === 'q') {\n client.send({ type: 'command', command: 'stop' });\n process.stderr.write('\\n🛑 Daemon wird gestoppt...\\n');\n setTimeout(() => {\n client.disconnect();\n if (process.stdin.isTTY) process.stdin.setRawMode(false);\n process.stdin.pause();\n }, 1000);\n return;\n }\n });\n\n client.on('message', (msg: DaemonMessage) => {\n switch (msg.type) {\n case 'status':\n renderStatus(msg.data);\n break;\n case 'event':\n process.stdout.write(\n ` [${new Date(msg.data.timestamp).toLocaleTimeString()}] ` +\n `${msg.data.eventType} ${msg.data.process}` +\n (msg.data.target ? ` → ${msg.data.target}` : '') + '\\n'\n );\n break;\n case 'agent-output':\n if (msg.text) process.stdout.write(` 🤖 ${msg.text}\\n`);\n break;\n case 'info':\n process.stdout.write(` ℹ ${msg.message}\\n`);\n break;\n case 'prompt':\n renderPrompt(msg.prompt.kind, msg.prompt.options, (answer) => {\n client.send({ type: 'prompt-response', id: msg.id, answer });\n });\n break;\n }\n });\n\n client.on('disconnect', () => {\n process.stderr.write('\\n⚠ Verbindung zum Daemon verloren\\n');\n if (process.stdin.isTTY) process.stdin.setRawMode(false);\n process.stdin.pause();\n });\n }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction renderStatus(status: ShadowStatus): void {\n process.stdout.write(\n `\\n── Shadow Status ───────────────────────────────\\n` +\n ` PID: ${status.pid} | Uptime: ${Math.round(status.uptime)}s\\n` +\n ` Nodes: ${status.nodeCount} | Events: ${status.eventCount} | Tasks: ${status.taskCount}\\n` +\n ` Cycles: ${status.cyclesRun} run, ${status.cyclesSkipped} skipped\\n` +\n `────────────────────────────────────────────────\\n`\n );\n}\n\nfunction renderPrompt(\n kind: string,\n options: string[],\n callback: (answer: string) => void,\n): void {\n process.stdout.write(`\\n❓ ${kind}\\n`);\n options.forEach((opt, i) => process.stdout.write(` [${i + 1}] ${opt}\\n`));\n process.stdout.write('Antwort: ');\n process.stdin.once('data', (data: string) => {\n const idx = parseInt(data.trim(), 10) - 1;\n callback(options[idx] ?? options[0] ?? '');\n });\n}\n"],"mappings":"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","names":["z","z","mkdirSync","join","execSync","existsSync","readFileSync","writeFileSync","unlinkSync","existsSync","execSync","writeFileSync","existsSync","readFileSync","unlinkSync","execSync","existsSync","readFileSync","join"]}
package/package.json CHANGED
@@ -1,11 +1,22 @@
1
1
  {
2
2
  "name": "@datasynx/agentic-ai-cartography",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "AI-powered infrastructure cartography & SOP generation CLI — built on Claude Agent SDK",
5
5
  "type": "module",
6
- "bin": { "cartography": "./dist/cli.js" },
7
- "exports": { ".": { "import": "./dist/index.js", "types": "./dist/index.d.ts" } },
8
- "files": ["dist", "README.md", "LICENSE"],
6
+ "bin": {
7
+ "cartography": "./dist/cli.js"
8
+ },
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "LICENSE"
19
+ ],
9
20
  "scripts": {
10
21
  "build": "tsup",
11
22
  "dev": "tsx src/cli.ts",
@@ -15,11 +26,21 @@
15
26
  "prepublishOnly": "npm run lint && npm run test && npm run build",
16
27
  "postinstall": "node -e \"try{require('child_process').execSync('claude --version',{stdio:'pipe'})}catch{console.warn('\\n⚠ cartography requires Claude CLI: npm i -g @anthropic-ai/claude-code\\n')}\""
17
28
  },
18
- "engines": { "node": ">=18.0.0" },
29
+ "engines": {
30
+ "node": ">=18.0.0"
31
+ },
19
32
  "keywords": [
20
- "infrastructure", "cartography", "discovery", "sop",
21
- "claude", "ai-agent", "devops", "mermaid", "backstage",
22
- "network-topology", "observability"
33
+ "infrastructure",
34
+ "cartography",
35
+ "discovery",
36
+ "sop",
37
+ "claude",
38
+ "ai-agent",
39
+ "devops",
40
+ "mermaid",
41
+ "backstage",
42
+ "network-topology",
43
+ "observability"
23
44
  ],
24
45
  "author": {
25
46
  "name": "Datasynx AI",
@@ -34,8 +55,15 @@
34
55
  "url": "https://github.com/datasynx-ai/agentic-ai-discovery/issues"
35
56
  },
36
57
  "license": "MIT",
58
+ "peerDependencies": {
59
+ "@anthropic-ai/claude-code": ">=1.0.0 <2.0.0"
60
+ },
61
+ "peerDependenciesMeta": {
62
+ "@anthropic-ai/claude-code": {
63
+ "optional": true
64
+ }
65
+ },
37
66
  "dependencies": {
38
- "@anthropic-ai/claude-code": "^1.0.0",
39
67
  "@anthropic-ai/sdk": "^0.74.0",
40
68
  "better-sqlite3": "^12.6.0",
41
69
  "commander": "^12.1.0",
@@ -45,6 +73,7 @@
45
73
  "zod": "^3.24.0"
46
74
  },
47
75
  "devDependencies": {
76
+ "@anthropic-ai/claude-code": "^1.0.128",
48
77
  "@types/better-sqlite3": "^7.6.12",
49
78
  "@types/node": "^22.10.0",
50
79
  "tsup": "^8.3.0",