@datasynx/agentic-ai-cartography 2.11.0 → 2.12.1

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/index.d.cts CHANGED
@@ -1984,6 +1984,18 @@ type FragmentKind = 'host' | 'user' | 'path' | 'ip';
1984
1984
  * left intact (so topology against public infra still reads).
1985
1985
  */
1986
1986
  declare const PRIVATE_IP: RegExp;
1987
+ /**
1988
+ * A bare single-label internal hostname — the known 2.10 residual that {@link HOSTNAME}
1989
+ * (multi-label only) never tokenizes. We only treat a single label as an internal host
1990
+ * when it *looks* like one: it contains a hyphen or a digit run (e.g. `db-01`, `web2`,
1991
+ * `prod-db`) so we do not false-positive ordinary English words used as a `name`
1992
+ * (`Postgres`, `Marketing`) or the literal `localhost`. Single-sourced here so the
1993
+ * client (this module) and the server (`src/central/anonymization.ts`, which re-imports
1994
+ * this constant) agree on what counts as a bare internal host.
1995
+ */
1996
+ declare const BARE_INTERNAL_HOST: RegExp;
1997
+ /** A pseudonym token produced by this module (`anon:host:abc…`) — already anonymized. */
1998
+ declare const ANON_TOKEN: RegExp;
1987
1999
  /**
1988
2000
  * Deterministic token for one identifying fragment. When `db` is supplied, the
1989
2001
  * plaintext is AES-256-GCM-encrypted under `reversalKey(orgKey)` and persisted so
@@ -1998,6 +2010,17 @@ declare function pseudonymizeFragment(plaintext: string, kind: FragmentKind, org
1998
2010
  * or a path segment is never mis-tokenized as a host.
1999
2011
  */
2000
2012
  declare function pseudonymizeString(s: string, orgKey: Buffer, db?: CartographyDB): string;
2013
+ /**
2014
+ * Pseudonymize the host material of a structured node id (`{type}:{host}[:{port}]` or
2015
+ * `{type}:{provider}:{name}`). The leading `{type}` segment is a non-identifying schema
2016
+ * prefix and is left verbatim; every later colon-delimited segment is run through
2017
+ * {@link pseudonymizeString} (so an FQDN, a private IP, an absolute path, or a bare
2018
+ * internal host inside a segment all tokenize, while a numeric port — matching no rule —
2019
+ * is preserved). Re-join with `:`. This is the structural id transform used for node ids
2020
+ * and for edge endpoints, so both stay consistent. A token already inside a segment is
2021
+ * not re-tokenized (the bare-host pass is whole-string and `anon:` tokens are excluded).
2022
+ */
2023
+ declare function pseudonymizeId(id: string, orgKey: Buffer, db?: CartographyDB): string;
2001
2024
  /**
2002
2025
  * Recursive, structure-preserving walker — same shape as `redactValue`
2003
2026
  * (`src/tools.ts`): strings → {@link pseudonymizeString}, arrays → map,
@@ -2042,8 +2065,16 @@ declare function resolveEffectiveLevel(node: DiscoveryNode, policy: SharingPolic
2042
2065
  * (structure-preserving); identifying fragments tokenized.
2043
2066
  * - `full` → a structural clone, verbatim.
2044
2067
  *
2045
- * The same deterministic `pseudonymizeString` is applied to the id here and by
2046
- * {@link previewShare} when remapping edges, so endpoints always resolve.
2068
+ * The same deterministic `pseudonymizeId` is applied to the id here and by
2069
+ * {@link previewShare} when remapping edges (via the shared idMap), so endpoints
2070
+ * always resolve. `pseudonymizeId` is id-aware: it tokenizes the host segment(s) —
2071
+ * including a bare single-label internal host — while sparing the `{type}` prefix.
2072
+ *
2073
+ * At the `anonymized` level the derived identity fields `globalId`
2074
+ * (`{tenant}:{normalizeId(id)}`, which embeds the raw id) and `contentHash` are
2075
+ * dropped from the outgoing payload — they would otherwise carry the raw id past
2076
+ * anonymization, and the central collector recomputes both from the (anonymized)
2077
+ * node on ingest (`computeIdentity`), so omitting them is both leak-free and lossless.
2047
2078
  */
2048
2079
  declare function applySharingLevel(node: DiscoveryNode, level: SharingLevel, orgKey: Buffer, db?: CartographyDB): DiscoveryNode | null;
2049
2080
  interface SharePreviewEntry {
@@ -3550,6 +3581,66 @@ declare function executeNlQuery(db: CartographyDB, sessionId: string, search: Se
3550
3581
  /** Convenience: parse + execute in one call. */
3551
3582
  declare function resolveNlQuery(db: CartographyDB, sessionId: string, search: SearchFn, raw: string, opts?: NlQueryOptions): Promise<NlQueryResult>;
3552
3583
 
3584
+ /**
3585
+ * Kubernetes operator (5.2) — a thin, deterministic, LLM-free reconcile loop.
3586
+ *
3587
+ * Runs Cartograph's discovery continuously **inside** a cluster and reports drift between
3588
+ * cycles — the "continuous CMDB for Kubernetes" outcome. It is a thin orchestration over
3589
+ * two engine halves that already exist and are DB-agnostic: the deterministic discovery
3590
+ * driver `runLocalDiscovery` (with a **k8s-only** scanner registry — it maps in-cluster
3591
+ * resources, never the host) and the drift engine `runDrift` (which classifies the delta
3592
+ * vs the previous cycle and dispatches it to the configured sinks, 3.1/4.4). No agent loop,
3593
+ * no Anthropic coupling, read-only (only `kubectl` reads via the allowlist).
3594
+ *
3595
+ * It is a periodic-reconcile operator, not a CRD controller — no custom resource or
3596
+ * controller-runtime dependency; the loop is a plain interval (or a single `--once` pass
3597
+ * for a CronJob driver). All side effects are injectable, so a cycle is unit-testable
3598
+ * without a cluster.
3599
+ */
3600
+
3601
+ /** A k8s-only scanner registry — the operator discovers cluster resources, not the host. */
3602
+ declare function k8sRegistry(): ScannerRegistry;
3603
+ /** True when running inside a Kubernetes pod (the service-account API env is injected). */
3604
+ declare function isInCluster(env?: NodeJS.ProcessEnv): boolean;
3605
+ interface OperatorCycleResult {
3606
+ sessionId: string;
3607
+ nodes: number;
3608
+ edges: number;
3609
+ /** The classified drift vs the previous cycle, or null (first cycle / no change). */
3610
+ drift: DriftAlert | null;
3611
+ }
3612
+ interface OperatorOptions {
3613
+ /** Reconcile interval (ms). Default 5 minutes. */
3614
+ intervalMs?: number;
3615
+ /** Run a single reconcile and return — CronJob-driver friendly. */
3616
+ once?: boolean;
3617
+ /** Injected discovery (tests). Default: `runLocalDiscovery` over the k8s registry. */
3618
+ discover?: (db: CartographyDB, sessionId: string) => Promise<{
3619
+ nodes: number;
3620
+ edges: number;
3621
+ }>;
3622
+ /** Injected drift dispatch (tests). Default: `runDrift` (dispatches to `config.drift` sinks). */
3623
+ drift?: (db: CartographyDB, config: CartographyConfig) => Promise<DriftAlert | null>;
3624
+ /** Stop the reconcile loop (SIGINT/SIGTERM → abort). */
3625
+ signal?: AbortSignal;
3626
+ /** Sleep between cycles (tests inject a controlled/no-wait sleep). */
3627
+ sleep?: (ms: number) => Promise<void>;
3628
+ /**
3629
+ * Keep only the most recent N discovery sessions (default 10) — a continuous operator
3630
+ * creates one session per cycle, so older snapshots are pruned each cycle to bound the
3631
+ * catalog. Drift only needs the latest two; the rest are retained history.
3632
+ */
3633
+ retain?: number;
3634
+ log?: (msg: string) => void;
3635
+ }
3636
+ /**
3637
+ * One reconcile cycle: discover in-cluster → record the session → classify + dispatch drift
3638
+ * vs the previous cycle. Returns the cycle outcome.
3639
+ */
3640
+ declare function runOperatorCycle(db: CartographyDB, config: CartographyConfig, opts?: OperatorOptions): Promise<OperatorCycleResult>;
3641
+ /** Run the operator: a single cycle if `once`, else a reconcile loop until the signal aborts. */
3642
+ declare function runOperator(db: CartographyDB, config: CartographyConfig, opts?: OperatorOptions): Promise<void>;
3643
+
3553
3644
  /**
3554
3645
  * Multi-cloud correlation engine (5.1).
3555
3646
  *
@@ -4411,4 +4502,4 @@ declare function logInfo(message: string, context?: Record<string, unknown>): vo
4411
4502
  declare function logWarn(message: string, context?: Record<string, unknown>): void;
4412
4503
  declare function logError(message: string, context?: Record<string, unknown>): void;
4413
4504
 
4414
- export { ACTIONS, ANOMALY_KINDS, ANOMALY_SEVERITIES, type Action, ActionSchema, type AgentProvider, type AgentRunContext, type AgentTool, type Anomaly, type AnomalyConfig, type AnomalyKind, type AnomalySeverity, type AnomalyThresholds, type AnonViolation, type AnonymizationLevel, type ApiServerOptions, type AskUserFn, type AuthConfig, AuthConfigSchema, AuthorizationError, type Awaitable, type BackstageEntity, type BackstageMapOptions, type BindGuardOptions, type BoltDriver, type BoltRecord, type BoltResult, type BoltSession, CLIENTS, CONFIDENCE, CORRELATION_CONFIDENCE, COST_PERIODS, type CanonicalNode, type CartographyConfig, CartographyDB, type CartographyMapData, type CentralDbConfig, CentralDbConfigSchema, type ClassifiedItem, type ClassifyInput, type ClassifyResult, type ClientSpec, type Cluster, ClusterSchema, type ComplianceInput, type ComplianceReport, ComplianceReportSchema, type ComplianceRule, ComplianceRuleSchema, type Condition, ConditionSchema, ConfigError, type ConfigFile, ConfigFileSchema, type ConfigFormat, type Connection, ConnectionSchema, type Contributor, type ControlResult, ControlResultSchema, type CorrelatedTopology, type CorrelationEdge, type CorrelationSignal, type CostEntry, CostEntrySchema, type CostPeriod, type CostRecord, type CostSource, type CreateMcpServerOptions, type CredentialConfig, CredentialConfigSchema, type CredentialDb, type CredentialRecord, type CredentialStore, type CronFields, CsvCostSource, type CsvCostSourceOptions, DEFAULT_ANOMALY_THRESHOLDS, DEFAULT_FAST_MODEL, DEFAULT_INGEST_QUOTA, DEFAULT_LEAD_MODEL, DEFAULT_SERVER_NAME, DEFAULT_TENANT, DOMAIN_COLORS, DOMAIN_PALETTE, DRIFT_FIELDS, type DashboardOptions, type DataAsset, DataAssetSchema, type DependencyQuery, type DiscoveryEdge, type DiscoveryEvent, type DiscoveryFn, type DiscoveryNode, type DriftAlert, type DriftAlertItem, type DriftConfig, DriftConfigSchema, type DriftField, type DriftItemKind, type DriftRunRow, type DriftSink, type DriftSinkConfig, EDGE_RELATIONSHIPS, type EdgeRelationship, type EdgeRow, EdgeSchema, type EmbeddingProvider, type EnrichResult, type EntryOptions, type EstablishedConn, type EvidenceKind, type FetchLike, type FragmentKind, GraphStoreBackend, type GraphSummary, type HealthResult, type HttpOptions, INGEST_SCHEMA_VERSION, type IngestEnvelope, IngestEnvelopeSchema, type IngestHandler, type IngestHandlerOptions, type IngestOptions, type IngestResponse, type IngestResult, type InstallPlan, InvalidTenantError, type JiraIssue, type JiraOptions, JiraSink, type JiraSinkOptions, LOOPBACK_HOSTS, type LocalDiscoveryOptions, type LocalDiscoveryResult, type LogEntry, type LogLevel, MCP_BIN, type MatchStrategy, NODE_TYPES, NODE_TYPE_GROUPS, type NlIntent, type NlQueryOptions, type NlQueryResult, type NlRelation, type NodeAttribution, type NodeChange, type NodeIdentity, type NodeQuery, type NodeRow, NodeSchema, type NodeSignals, type NodeType, type NodesResult, NotFoundError, OUTPUT_FORMATS, type OrgKeyOptions, type OrgSummary, type OsKind, type OutputFormat, PACKAGE_NAME, PAGERDUTY_ENQUEUE_URL, PENDING_STATUSES, PERSONAL, PORT_MAP, PRIVATE_IP, PUSH_SCHEMA_VERSION, type PagerDutyEvent, PagerDutySink, type PagerDutySinkOptions, type ParsedApiArgs, type PendingShareRow, type PendingStatus, type PlanOptions, type PolicyResult, type PostJsonOptions, type Principal, PrincipalSchema, type ProviderFactory, type ProviderName, ProviderRegistry, type PushItem, type PushOptions, type PushResult, type QueryBackend, type QuotaConfig, type QuotaDecision, RELATION_TO_DIRECTION, ROLES, RateLimiter, type ResolveContext, type ResolveOptions, type Role, RoleSchema, type RuleCheck, RuleCheckSchema, type RuleScope, type Ruleset, RulesetSchema, type RunDriftOptions, SCAN_ARG_PATTERNS, SCHEMA_VERSION, SDL, SECURITY_METADATA_KEYS, SEVERITIES, SEVERITY_WEIGHT, SHARING_LEVELS, type ScanArgKind, type ScanContext, type ScanHintParams, type ScanResult, type Scanner, type ScannerPlugin, type ScannerPluginApi, ScannerRegistry, ScannerShape, type ScheduleConfig, ScheduleConfigSchema, type ScheduledRunResult, type Scope, type SearchFn, type SemanticSearchOptions, type ServerEntry, type SessionRow, type Severity, type SharePreview, type SharePreviewEntry, type SharingLevel, SharingLevelSchema, type SharingPolicy, type ShellKind, type SlackMessage, SlackSink, SqliteCredentialStore, SqliteQueryBackend, SqliteStoreBackend, type StartApiOptions, StdoutSink, type StoreBackend, type StoreBackendOptions, type SyncClassifyOptions, type SyncClassifyResult, TENANT_HEADER, type TenantContext, TenantMismatchError, type TenantOptions, type ToolResult, type TopologyDelta, type TopologyDiff, type TopologyInput, type TraversalResult, VectorStore, WebhookSink, type WebhookSinkOptions, applyInstall, applySharingLevel, assertReadOnly, assertSafeBind, assertSafeScanArg, assertSameTenant, assignColors, authorize, bearerToken, bookmarksScanner, buildCartographyToolHandlers, buildMapData, buildOpenApiDocument, buildReport, buildSinks, can, centralDbFromEnv, checkBearer, checkPrerequisites, checkReadOnly, clampText, classify, classifyDrift, cleanupTempFiles, cloudAwsScanner, cloudAzureScanner, cloudGcpScanner, codeAddMcpCommand, computeCentroid, computeClusterBounds, computeIdentity, connectionsScanner, contentHash, correlateTopology, createBashTool, createCartographyTools, createClaudeProvider, createDefaultRegistry, createHashEmbedder, createIngestHandler, createLocalEmbedder, createMcpServer, createOllamaProvider, createOpenAIProvider, createScanRunner, createSemanticSearch, createSqliteQueryBackend, currentOs, cursorDeeplink, dashboardHtml, databasesScanner, deepMerge, defaultAllowedHosts, defaultConfig, defaultContext, defaultProviderRegistry, defaultRegistry, defaultServerEntry, definePlugin, deriveSessionName, detectAnomalies, detectOrphans, detectShadowIt, diffTopology, edgesToConnections, enrichCosts, entitiesToYaml, evaluateCheck, evaluateRule, evidenceLine, executeGraphql, executeNlQuery, exportAll, exportBackstageYAML, exportComplianceReport, exportCostCSV, exportCostSummary, exportDiscoveryApp, exportJGF, exportJSON, extractListeningPorts, extractSignals, filterBySeverity, findAnonViolations, formatComplianceText, formatJira, formatPagerDuty, formatSlack, generateDependencyMermaid, generateDiffMermaid, generateTopologyMermaid, getClient, getRuleset, globalId, groupByDomain, handleGraphqlGet, hashToken, hexCorners, hexDistance, hexNeighbors, hexRing, hexSpiral, hexToPixel, hmacKey, hostname, ingestEnvelope, installedAppsScanner, isLoopbackHost, isPersonalHost, isReadOnlyCommand, isRemembered, isSecureWebhookUrl, k8sScanner, keyMetaOf, layoutClusters, listClients, listRulesets, loadConfig, loadOrgKey, loadPlugins, loadRuleset, localDiscoveryFn, log, logDebug, logError, logInfo, logWarn, machineId, maxSeverity, mcpServerObject, newAnomalies, nextRun, nodesToAssets, normalizeId, normalizeTenant, openStoreBackend, orgKeyPath, osUser, parseApiArgs, parseComposeDeps, parseConfig, parseConnectionString, parseCostCsv, parseCron, parseEstablished, parseNginxUpstreams, parseNlQuery, parseScanHint, parseTerraformState, pixelToHex, planInstall, portsScanner, postJson, previewShare, pseudonymize, pseudonymizeFragment, pseudonymizeString, pushDeltas, readConfigFile, redactConnectionString, redactSecrets, redactValue, renderDiff, resolveEffectiveLevel, resolveNlQuery, resolvePrincipal, resolveSharingLevel, resolveTenant, revalidateAnonymized, reversalKey, reversePseudonym, rotateOrgKey, runApi, runDiscovery, runDrift, runHttp, runLocalDiscovery, runOnce, runStdio, runSyncClassify, safeEnv, safeJson, safetyHook, sanitizeUntrusted, sanitizeValue, scopeReads, scoreTopology, securityRelevantChange, serializeConfig, serviceConfigScanner, setVerbose, shadeVariant, shapeToJsonSchema, shareHash, splitSegments, stableStringify, startApi, stripSensitive, terraformScanner, terraformTypeToNode, timingSafeEqual, toBackstageEntities, validateScanner, vscodeDeeplink, zodToJsonSchema };
4505
+ export { ACTIONS, ANOMALY_KINDS, ANOMALY_SEVERITIES, ANON_TOKEN, type Action, ActionSchema, type AgentProvider, type AgentRunContext, type AgentTool, type Anomaly, type AnomalyConfig, type AnomalyKind, type AnomalySeverity, type AnomalyThresholds, type AnonViolation, type AnonymizationLevel, type ApiServerOptions, type AskUserFn, type AuthConfig, AuthConfigSchema, AuthorizationError, type Awaitable, BARE_INTERNAL_HOST, type BackstageEntity, type BackstageMapOptions, type BindGuardOptions, type BoltDriver, type BoltRecord, type BoltResult, type BoltSession, CLIENTS, CONFIDENCE, CORRELATION_CONFIDENCE, COST_PERIODS, type CanonicalNode, type CartographyConfig, CartographyDB, type CartographyMapData, type CentralDbConfig, CentralDbConfigSchema, type ClassifiedItem, type ClassifyInput, type ClassifyResult, type ClientSpec, type Cluster, ClusterSchema, type ComplianceInput, type ComplianceReport, ComplianceReportSchema, type ComplianceRule, ComplianceRuleSchema, type Condition, ConditionSchema, ConfigError, type ConfigFile, ConfigFileSchema, type ConfigFormat, type Connection, ConnectionSchema, type Contributor, type ControlResult, ControlResultSchema, type CorrelatedTopology, type CorrelationEdge, type CorrelationSignal, type CostEntry, CostEntrySchema, type CostPeriod, type CostRecord, type CostSource, type CreateMcpServerOptions, type CredentialConfig, CredentialConfigSchema, type CredentialDb, type CredentialRecord, type CredentialStore, type CronFields, CsvCostSource, type CsvCostSourceOptions, DEFAULT_ANOMALY_THRESHOLDS, DEFAULT_FAST_MODEL, DEFAULT_INGEST_QUOTA, DEFAULT_LEAD_MODEL, DEFAULT_SERVER_NAME, DEFAULT_TENANT, DOMAIN_COLORS, DOMAIN_PALETTE, DRIFT_FIELDS, type DashboardOptions, type DataAsset, DataAssetSchema, type DependencyQuery, type DiscoveryEdge, type DiscoveryEvent, type DiscoveryFn, type DiscoveryNode, type DriftAlert, type DriftAlertItem, type DriftConfig, DriftConfigSchema, type DriftField, type DriftItemKind, type DriftRunRow, type DriftSink, type DriftSinkConfig, EDGE_RELATIONSHIPS, type EdgeRelationship, type EdgeRow, EdgeSchema, type EmbeddingProvider, type EnrichResult, type EntryOptions, type EstablishedConn, type EvidenceKind, type FetchLike, type FragmentKind, GraphStoreBackend, type GraphSummary, type HealthResult, type HttpOptions, INGEST_SCHEMA_VERSION, type IngestEnvelope, IngestEnvelopeSchema, type IngestHandler, type IngestHandlerOptions, type IngestOptions, type IngestResponse, type IngestResult, type InstallPlan, InvalidTenantError, type JiraIssue, type JiraOptions, JiraSink, type JiraSinkOptions, LOOPBACK_HOSTS, type LocalDiscoveryOptions, type LocalDiscoveryResult, type LogEntry, type LogLevel, MCP_BIN, type MatchStrategy, NODE_TYPES, NODE_TYPE_GROUPS, type NlIntent, type NlQueryOptions, type NlQueryResult, type NlRelation, type NodeAttribution, type NodeChange, type NodeIdentity, type NodeQuery, type NodeRow, NodeSchema, type NodeSignals, type NodeType, type NodesResult, NotFoundError, OUTPUT_FORMATS, type OperatorCycleResult, type OperatorOptions, type OrgKeyOptions, type OrgSummary, type OsKind, type OutputFormat, PACKAGE_NAME, PAGERDUTY_ENQUEUE_URL, PENDING_STATUSES, PERSONAL, PORT_MAP, PRIVATE_IP, PUSH_SCHEMA_VERSION, type PagerDutyEvent, PagerDutySink, type PagerDutySinkOptions, type ParsedApiArgs, type PendingShareRow, type PendingStatus, type PlanOptions, type PolicyResult, type PostJsonOptions, type Principal, PrincipalSchema, type ProviderFactory, type ProviderName, ProviderRegistry, type PushItem, type PushOptions, type PushResult, type QueryBackend, type QuotaConfig, type QuotaDecision, RELATION_TO_DIRECTION, ROLES, RateLimiter, type ResolveContext, type ResolveOptions, type Role, RoleSchema, type RuleCheck, RuleCheckSchema, type RuleScope, type Ruleset, RulesetSchema, type RunDriftOptions, SCAN_ARG_PATTERNS, SCHEMA_VERSION, SDL, SECURITY_METADATA_KEYS, SEVERITIES, SEVERITY_WEIGHT, SHARING_LEVELS, type ScanArgKind, type ScanContext, type ScanHintParams, type ScanResult, type Scanner, type ScannerPlugin, type ScannerPluginApi, ScannerRegistry, ScannerShape, type ScheduleConfig, ScheduleConfigSchema, type ScheduledRunResult, type Scope, type SearchFn, type SemanticSearchOptions, type ServerEntry, type SessionRow, type Severity, type SharePreview, type SharePreviewEntry, type SharingLevel, SharingLevelSchema, type SharingPolicy, type ShellKind, type SlackMessage, SlackSink, SqliteCredentialStore, SqliteQueryBackend, SqliteStoreBackend, type StartApiOptions, StdoutSink, type StoreBackend, type StoreBackendOptions, type SyncClassifyOptions, type SyncClassifyResult, TENANT_HEADER, type TenantContext, TenantMismatchError, type TenantOptions, type ToolResult, type TopologyDelta, type TopologyDiff, type TopologyInput, type TraversalResult, VectorStore, WebhookSink, type WebhookSinkOptions, applyInstall, applySharingLevel, assertReadOnly, assertSafeBind, assertSafeScanArg, assertSameTenant, assignColors, authorize, bearerToken, bookmarksScanner, buildCartographyToolHandlers, buildMapData, buildOpenApiDocument, buildReport, buildSinks, can, centralDbFromEnv, checkBearer, checkPrerequisites, checkReadOnly, clampText, classify, classifyDrift, cleanupTempFiles, cloudAwsScanner, cloudAzureScanner, cloudGcpScanner, codeAddMcpCommand, computeCentroid, computeClusterBounds, computeIdentity, connectionsScanner, contentHash, correlateTopology, createBashTool, createCartographyTools, createClaudeProvider, createDefaultRegistry, createHashEmbedder, createIngestHandler, createLocalEmbedder, createMcpServer, createOllamaProvider, createOpenAIProvider, createScanRunner, createSemanticSearch, createSqliteQueryBackend, currentOs, cursorDeeplink, dashboardHtml, databasesScanner, deepMerge, defaultAllowedHosts, defaultConfig, defaultContext, defaultProviderRegistry, defaultRegistry, defaultServerEntry, definePlugin, deriveSessionName, detectAnomalies, detectOrphans, detectShadowIt, diffTopology, edgesToConnections, enrichCosts, entitiesToYaml, evaluateCheck, evaluateRule, evidenceLine, executeGraphql, executeNlQuery, exportAll, exportBackstageYAML, exportComplianceReport, exportCostCSV, exportCostSummary, exportDiscoveryApp, exportJGF, exportJSON, extractListeningPorts, extractSignals, filterBySeverity, findAnonViolations, formatComplianceText, formatJira, formatPagerDuty, formatSlack, generateDependencyMermaid, generateDiffMermaid, generateTopologyMermaid, getClient, getRuleset, globalId, groupByDomain, handleGraphqlGet, hashToken, hexCorners, hexDistance, hexNeighbors, hexRing, hexSpiral, hexToPixel, hmacKey, hostname, ingestEnvelope, installedAppsScanner, isInCluster, isLoopbackHost, isPersonalHost, isReadOnlyCommand, isRemembered, isSecureWebhookUrl, k8sRegistry, k8sScanner, keyMetaOf, layoutClusters, listClients, listRulesets, loadConfig, loadOrgKey, loadPlugins, loadRuleset, localDiscoveryFn, log, logDebug, logError, logInfo, logWarn, machineId, maxSeverity, mcpServerObject, newAnomalies, nextRun, nodesToAssets, normalizeId, normalizeTenant, openStoreBackend, orgKeyPath, osUser, parseApiArgs, parseComposeDeps, parseConfig, parseConnectionString, parseCostCsv, parseCron, parseEstablished, parseNginxUpstreams, parseNlQuery, parseScanHint, parseTerraformState, pixelToHex, planInstall, portsScanner, postJson, previewShare, pseudonymize, pseudonymizeFragment, pseudonymizeId, pseudonymizeString, pushDeltas, readConfigFile, redactConnectionString, redactSecrets, redactValue, renderDiff, resolveEffectiveLevel, resolveNlQuery, resolvePrincipal, resolveSharingLevel, resolveTenant, revalidateAnonymized, reversalKey, reversePseudonym, rotateOrgKey, runApi, runDiscovery, runDrift, runHttp, runLocalDiscovery, runOnce, runOperator, runOperatorCycle, runStdio, runSyncClassify, safeEnv, safeJson, safetyHook, sanitizeUntrusted, sanitizeValue, scopeReads, scoreTopology, securityRelevantChange, serializeConfig, serviceConfigScanner, setVerbose, shadeVariant, shapeToJsonSchema, shareHash, splitSegments, stableStringify, startApi, stripSensitive, terraformScanner, terraformTypeToNode, timingSafeEqual, toBackstageEntities, validateScanner, vscodeDeeplink, zodToJsonSchema };
package/dist/index.d.ts CHANGED
@@ -1984,6 +1984,18 @@ type FragmentKind = 'host' | 'user' | 'path' | 'ip';
1984
1984
  * left intact (so topology against public infra still reads).
1985
1985
  */
1986
1986
  declare const PRIVATE_IP: RegExp;
1987
+ /**
1988
+ * A bare single-label internal hostname — the known 2.10 residual that {@link HOSTNAME}
1989
+ * (multi-label only) never tokenizes. We only treat a single label as an internal host
1990
+ * when it *looks* like one: it contains a hyphen or a digit run (e.g. `db-01`, `web2`,
1991
+ * `prod-db`) so we do not false-positive ordinary English words used as a `name`
1992
+ * (`Postgres`, `Marketing`) or the literal `localhost`. Single-sourced here so the
1993
+ * client (this module) and the server (`src/central/anonymization.ts`, which re-imports
1994
+ * this constant) agree on what counts as a bare internal host.
1995
+ */
1996
+ declare const BARE_INTERNAL_HOST: RegExp;
1997
+ /** A pseudonym token produced by this module (`anon:host:abc…`) — already anonymized. */
1998
+ declare const ANON_TOKEN: RegExp;
1987
1999
  /**
1988
2000
  * Deterministic token for one identifying fragment. When `db` is supplied, the
1989
2001
  * plaintext is AES-256-GCM-encrypted under `reversalKey(orgKey)` and persisted so
@@ -1998,6 +2010,17 @@ declare function pseudonymizeFragment(plaintext: string, kind: FragmentKind, org
1998
2010
  * or a path segment is never mis-tokenized as a host.
1999
2011
  */
2000
2012
  declare function pseudonymizeString(s: string, orgKey: Buffer, db?: CartographyDB): string;
2013
+ /**
2014
+ * Pseudonymize the host material of a structured node id (`{type}:{host}[:{port}]` or
2015
+ * `{type}:{provider}:{name}`). The leading `{type}` segment is a non-identifying schema
2016
+ * prefix and is left verbatim; every later colon-delimited segment is run through
2017
+ * {@link pseudonymizeString} (so an FQDN, a private IP, an absolute path, or a bare
2018
+ * internal host inside a segment all tokenize, while a numeric port — matching no rule —
2019
+ * is preserved). Re-join with `:`. This is the structural id transform used for node ids
2020
+ * and for edge endpoints, so both stay consistent. A token already inside a segment is
2021
+ * not re-tokenized (the bare-host pass is whole-string and `anon:` tokens are excluded).
2022
+ */
2023
+ declare function pseudonymizeId(id: string, orgKey: Buffer, db?: CartographyDB): string;
2001
2024
  /**
2002
2025
  * Recursive, structure-preserving walker — same shape as `redactValue`
2003
2026
  * (`src/tools.ts`): strings → {@link pseudonymizeString}, arrays → map,
@@ -2042,8 +2065,16 @@ declare function resolveEffectiveLevel(node: DiscoveryNode, policy: SharingPolic
2042
2065
  * (structure-preserving); identifying fragments tokenized.
2043
2066
  * - `full` → a structural clone, verbatim.
2044
2067
  *
2045
- * The same deterministic `pseudonymizeString` is applied to the id here and by
2046
- * {@link previewShare} when remapping edges, so endpoints always resolve.
2068
+ * The same deterministic `pseudonymizeId` is applied to the id here and by
2069
+ * {@link previewShare} when remapping edges (via the shared idMap), so endpoints
2070
+ * always resolve. `pseudonymizeId` is id-aware: it tokenizes the host segment(s) —
2071
+ * including a bare single-label internal host — while sparing the `{type}` prefix.
2072
+ *
2073
+ * At the `anonymized` level the derived identity fields `globalId`
2074
+ * (`{tenant}:{normalizeId(id)}`, which embeds the raw id) and `contentHash` are
2075
+ * dropped from the outgoing payload — they would otherwise carry the raw id past
2076
+ * anonymization, and the central collector recomputes both from the (anonymized)
2077
+ * node on ingest (`computeIdentity`), so omitting them is both leak-free and lossless.
2047
2078
  */
2048
2079
  declare function applySharingLevel(node: DiscoveryNode, level: SharingLevel, orgKey: Buffer, db?: CartographyDB): DiscoveryNode | null;
2049
2080
  interface SharePreviewEntry {
@@ -3550,6 +3581,66 @@ declare function executeNlQuery(db: CartographyDB, sessionId: string, search: Se
3550
3581
  /** Convenience: parse + execute in one call. */
3551
3582
  declare function resolveNlQuery(db: CartographyDB, sessionId: string, search: SearchFn, raw: string, opts?: NlQueryOptions): Promise<NlQueryResult>;
3552
3583
 
3584
+ /**
3585
+ * Kubernetes operator (5.2) — a thin, deterministic, LLM-free reconcile loop.
3586
+ *
3587
+ * Runs Cartograph's discovery continuously **inside** a cluster and reports drift between
3588
+ * cycles — the "continuous CMDB for Kubernetes" outcome. It is a thin orchestration over
3589
+ * two engine halves that already exist and are DB-agnostic: the deterministic discovery
3590
+ * driver `runLocalDiscovery` (with a **k8s-only** scanner registry — it maps in-cluster
3591
+ * resources, never the host) and the drift engine `runDrift` (which classifies the delta
3592
+ * vs the previous cycle and dispatches it to the configured sinks, 3.1/4.4). No agent loop,
3593
+ * no Anthropic coupling, read-only (only `kubectl` reads via the allowlist).
3594
+ *
3595
+ * It is a periodic-reconcile operator, not a CRD controller — no custom resource or
3596
+ * controller-runtime dependency; the loop is a plain interval (or a single `--once` pass
3597
+ * for a CronJob driver). All side effects are injectable, so a cycle is unit-testable
3598
+ * without a cluster.
3599
+ */
3600
+
3601
+ /** A k8s-only scanner registry — the operator discovers cluster resources, not the host. */
3602
+ declare function k8sRegistry(): ScannerRegistry;
3603
+ /** True when running inside a Kubernetes pod (the service-account API env is injected). */
3604
+ declare function isInCluster(env?: NodeJS.ProcessEnv): boolean;
3605
+ interface OperatorCycleResult {
3606
+ sessionId: string;
3607
+ nodes: number;
3608
+ edges: number;
3609
+ /** The classified drift vs the previous cycle, or null (first cycle / no change). */
3610
+ drift: DriftAlert | null;
3611
+ }
3612
+ interface OperatorOptions {
3613
+ /** Reconcile interval (ms). Default 5 minutes. */
3614
+ intervalMs?: number;
3615
+ /** Run a single reconcile and return — CronJob-driver friendly. */
3616
+ once?: boolean;
3617
+ /** Injected discovery (tests). Default: `runLocalDiscovery` over the k8s registry. */
3618
+ discover?: (db: CartographyDB, sessionId: string) => Promise<{
3619
+ nodes: number;
3620
+ edges: number;
3621
+ }>;
3622
+ /** Injected drift dispatch (tests). Default: `runDrift` (dispatches to `config.drift` sinks). */
3623
+ drift?: (db: CartographyDB, config: CartographyConfig) => Promise<DriftAlert | null>;
3624
+ /** Stop the reconcile loop (SIGINT/SIGTERM → abort). */
3625
+ signal?: AbortSignal;
3626
+ /** Sleep between cycles (tests inject a controlled/no-wait sleep). */
3627
+ sleep?: (ms: number) => Promise<void>;
3628
+ /**
3629
+ * Keep only the most recent N discovery sessions (default 10) — a continuous operator
3630
+ * creates one session per cycle, so older snapshots are pruned each cycle to bound the
3631
+ * catalog. Drift only needs the latest two; the rest are retained history.
3632
+ */
3633
+ retain?: number;
3634
+ log?: (msg: string) => void;
3635
+ }
3636
+ /**
3637
+ * One reconcile cycle: discover in-cluster → record the session → classify + dispatch drift
3638
+ * vs the previous cycle. Returns the cycle outcome.
3639
+ */
3640
+ declare function runOperatorCycle(db: CartographyDB, config: CartographyConfig, opts?: OperatorOptions): Promise<OperatorCycleResult>;
3641
+ /** Run the operator: a single cycle if `once`, else a reconcile loop until the signal aborts. */
3642
+ declare function runOperator(db: CartographyDB, config: CartographyConfig, opts?: OperatorOptions): Promise<void>;
3643
+
3553
3644
  /**
3554
3645
  * Multi-cloud correlation engine (5.1).
3555
3646
  *
@@ -4411,4 +4502,4 @@ declare function logInfo(message: string, context?: Record<string, unknown>): vo
4411
4502
  declare function logWarn(message: string, context?: Record<string, unknown>): void;
4412
4503
  declare function logError(message: string, context?: Record<string, unknown>): void;
4413
4504
 
4414
- export { ACTIONS, ANOMALY_KINDS, ANOMALY_SEVERITIES, type Action, ActionSchema, type AgentProvider, type AgentRunContext, type AgentTool, type Anomaly, type AnomalyConfig, type AnomalyKind, type AnomalySeverity, type AnomalyThresholds, type AnonViolation, type AnonymizationLevel, type ApiServerOptions, type AskUserFn, type AuthConfig, AuthConfigSchema, AuthorizationError, type Awaitable, type BackstageEntity, type BackstageMapOptions, type BindGuardOptions, type BoltDriver, type BoltRecord, type BoltResult, type BoltSession, CLIENTS, CONFIDENCE, CORRELATION_CONFIDENCE, COST_PERIODS, type CanonicalNode, type CartographyConfig, CartographyDB, type CartographyMapData, type CentralDbConfig, CentralDbConfigSchema, type ClassifiedItem, type ClassifyInput, type ClassifyResult, type ClientSpec, type Cluster, ClusterSchema, type ComplianceInput, type ComplianceReport, ComplianceReportSchema, type ComplianceRule, ComplianceRuleSchema, type Condition, ConditionSchema, ConfigError, type ConfigFile, ConfigFileSchema, type ConfigFormat, type Connection, ConnectionSchema, type Contributor, type ControlResult, ControlResultSchema, type CorrelatedTopology, type CorrelationEdge, type CorrelationSignal, type CostEntry, CostEntrySchema, type CostPeriod, type CostRecord, type CostSource, type CreateMcpServerOptions, type CredentialConfig, CredentialConfigSchema, type CredentialDb, type CredentialRecord, type CredentialStore, type CronFields, CsvCostSource, type CsvCostSourceOptions, DEFAULT_ANOMALY_THRESHOLDS, DEFAULT_FAST_MODEL, DEFAULT_INGEST_QUOTA, DEFAULT_LEAD_MODEL, DEFAULT_SERVER_NAME, DEFAULT_TENANT, DOMAIN_COLORS, DOMAIN_PALETTE, DRIFT_FIELDS, type DashboardOptions, type DataAsset, DataAssetSchema, type DependencyQuery, type DiscoveryEdge, type DiscoveryEvent, type DiscoveryFn, type DiscoveryNode, type DriftAlert, type DriftAlertItem, type DriftConfig, DriftConfigSchema, type DriftField, type DriftItemKind, type DriftRunRow, type DriftSink, type DriftSinkConfig, EDGE_RELATIONSHIPS, type EdgeRelationship, type EdgeRow, EdgeSchema, type EmbeddingProvider, type EnrichResult, type EntryOptions, type EstablishedConn, type EvidenceKind, type FetchLike, type FragmentKind, GraphStoreBackend, type GraphSummary, type HealthResult, type HttpOptions, INGEST_SCHEMA_VERSION, type IngestEnvelope, IngestEnvelopeSchema, type IngestHandler, type IngestHandlerOptions, type IngestOptions, type IngestResponse, type IngestResult, type InstallPlan, InvalidTenantError, type JiraIssue, type JiraOptions, JiraSink, type JiraSinkOptions, LOOPBACK_HOSTS, type LocalDiscoveryOptions, type LocalDiscoveryResult, type LogEntry, type LogLevel, MCP_BIN, type MatchStrategy, NODE_TYPES, NODE_TYPE_GROUPS, type NlIntent, type NlQueryOptions, type NlQueryResult, type NlRelation, type NodeAttribution, type NodeChange, type NodeIdentity, type NodeQuery, type NodeRow, NodeSchema, type NodeSignals, type NodeType, type NodesResult, NotFoundError, OUTPUT_FORMATS, type OrgKeyOptions, type OrgSummary, type OsKind, type OutputFormat, PACKAGE_NAME, PAGERDUTY_ENQUEUE_URL, PENDING_STATUSES, PERSONAL, PORT_MAP, PRIVATE_IP, PUSH_SCHEMA_VERSION, type PagerDutyEvent, PagerDutySink, type PagerDutySinkOptions, type ParsedApiArgs, type PendingShareRow, type PendingStatus, type PlanOptions, type PolicyResult, type PostJsonOptions, type Principal, PrincipalSchema, type ProviderFactory, type ProviderName, ProviderRegistry, type PushItem, type PushOptions, type PushResult, type QueryBackend, type QuotaConfig, type QuotaDecision, RELATION_TO_DIRECTION, ROLES, RateLimiter, type ResolveContext, type ResolveOptions, type Role, RoleSchema, type RuleCheck, RuleCheckSchema, type RuleScope, type Ruleset, RulesetSchema, type RunDriftOptions, SCAN_ARG_PATTERNS, SCHEMA_VERSION, SDL, SECURITY_METADATA_KEYS, SEVERITIES, SEVERITY_WEIGHT, SHARING_LEVELS, type ScanArgKind, type ScanContext, type ScanHintParams, type ScanResult, type Scanner, type ScannerPlugin, type ScannerPluginApi, ScannerRegistry, ScannerShape, type ScheduleConfig, ScheduleConfigSchema, type ScheduledRunResult, type Scope, type SearchFn, type SemanticSearchOptions, type ServerEntry, type SessionRow, type Severity, type SharePreview, type SharePreviewEntry, type SharingLevel, SharingLevelSchema, type SharingPolicy, type ShellKind, type SlackMessage, SlackSink, SqliteCredentialStore, SqliteQueryBackend, SqliteStoreBackend, type StartApiOptions, StdoutSink, type StoreBackend, type StoreBackendOptions, type SyncClassifyOptions, type SyncClassifyResult, TENANT_HEADER, type TenantContext, TenantMismatchError, type TenantOptions, type ToolResult, type TopologyDelta, type TopologyDiff, type TopologyInput, type TraversalResult, VectorStore, WebhookSink, type WebhookSinkOptions, applyInstall, applySharingLevel, assertReadOnly, assertSafeBind, assertSafeScanArg, assertSameTenant, assignColors, authorize, bearerToken, bookmarksScanner, buildCartographyToolHandlers, buildMapData, buildOpenApiDocument, buildReport, buildSinks, can, centralDbFromEnv, checkBearer, checkPrerequisites, checkReadOnly, clampText, classify, classifyDrift, cleanupTempFiles, cloudAwsScanner, cloudAzureScanner, cloudGcpScanner, codeAddMcpCommand, computeCentroid, computeClusterBounds, computeIdentity, connectionsScanner, contentHash, correlateTopology, createBashTool, createCartographyTools, createClaudeProvider, createDefaultRegistry, createHashEmbedder, createIngestHandler, createLocalEmbedder, createMcpServer, createOllamaProvider, createOpenAIProvider, createScanRunner, createSemanticSearch, createSqliteQueryBackend, currentOs, cursorDeeplink, dashboardHtml, databasesScanner, deepMerge, defaultAllowedHosts, defaultConfig, defaultContext, defaultProviderRegistry, defaultRegistry, defaultServerEntry, definePlugin, deriveSessionName, detectAnomalies, detectOrphans, detectShadowIt, diffTopology, edgesToConnections, enrichCosts, entitiesToYaml, evaluateCheck, evaluateRule, evidenceLine, executeGraphql, executeNlQuery, exportAll, exportBackstageYAML, exportComplianceReport, exportCostCSV, exportCostSummary, exportDiscoveryApp, exportJGF, exportJSON, extractListeningPorts, extractSignals, filterBySeverity, findAnonViolations, formatComplianceText, formatJira, formatPagerDuty, formatSlack, generateDependencyMermaid, generateDiffMermaid, generateTopologyMermaid, getClient, getRuleset, globalId, groupByDomain, handleGraphqlGet, hashToken, hexCorners, hexDistance, hexNeighbors, hexRing, hexSpiral, hexToPixel, hmacKey, hostname, ingestEnvelope, installedAppsScanner, isLoopbackHost, isPersonalHost, isReadOnlyCommand, isRemembered, isSecureWebhookUrl, k8sScanner, keyMetaOf, layoutClusters, listClients, listRulesets, loadConfig, loadOrgKey, loadPlugins, loadRuleset, localDiscoveryFn, log, logDebug, logError, logInfo, logWarn, machineId, maxSeverity, mcpServerObject, newAnomalies, nextRun, nodesToAssets, normalizeId, normalizeTenant, openStoreBackend, orgKeyPath, osUser, parseApiArgs, parseComposeDeps, parseConfig, parseConnectionString, parseCostCsv, parseCron, parseEstablished, parseNginxUpstreams, parseNlQuery, parseScanHint, parseTerraformState, pixelToHex, planInstall, portsScanner, postJson, previewShare, pseudonymize, pseudonymizeFragment, pseudonymizeString, pushDeltas, readConfigFile, redactConnectionString, redactSecrets, redactValue, renderDiff, resolveEffectiveLevel, resolveNlQuery, resolvePrincipal, resolveSharingLevel, resolveTenant, revalidateAnonymized, reversalKey, reversePseudonym, rotateOrgKey, runApi, runDiscovery, runDrift, runHttp, runLocalDiscovery, runOnce, runStdio, runSyncClassify, safeEnv, safeJson, safetyHook, sanitizeUntrusted, sanitizeValue, scopeReads, scoreTopology, securityRelevantChange, serializeConfig, serviceConfigScanner, setVerbose, shadeVariant, shapeToJsonSchema, shareHash, splitSegments, stableStringify, startApi, stripSensitive, terraformScanner, terraformTypeToNode, timingSafeEqual, toBackstageEntities, validateScanner, vscodeDeeplink, zodToJsonSchema };
4505
+ export { ACTIONS, ANOMALY_KINDS, ANOMALY_SEVERITIES, ANON_TOKEN, type Action, ActionSchema, type AgentProvider, type AgentRunContext, type AgentTool, type Anomaly, type AnomalyConfig, type AnomalyKind, type AnomalySeverity, type AnomalyThresholds, type AnonViolation, type AnonymizationLevel, type ApiServerOptions, type AskUserFn, type AuthConfig, AuthConfigSchema, AuthorizationError, type Awaitable, BARE_INTERNAL_HOST, type BackstageEntity, type BackstageMapOptions, type BindGuardOptions, type BoltDriver, type BoltRecord, type BoltResult, type BoltSession, CLIENTS, CONFIDENCE, CORRELATION_CONFIDENCE, COST_PERIODS, type CanonicalNode, type CartographyConfig, CartographyDB, type CartographyMapData, type CentralDbConfig, CentralDbConfigSchema, type ClassifiedItem, type ClassifyInput, type ClassifyResult, type ClientSpec, type Cluster, ClusterSchema, type ComplianceInput, type ComplianceReport, ComplianceReportSchema, type ComplianceRule, ComplianceRuleSchema, type Condition, ConditionSchema, ConfigError, type ConfigFile, ConfigFileSchema, type ConfigFormat, type Connection, ConnectionSchema, type Contributor, type ControlResult, ControlResultSchema, type CorrelatedTopology, type CorrelationEdge, type CorrelationSignal, type CostEntry, CostEntrySchema, type CostPeriod, type CostRecord, type CostSource, type CreateMcpServerOptions, type CredentialConfig, CredentialConfigSchema, type CredentialDb, type CredentialRecord, type CredentialStore, type CronFields, CsvCostSource, type CsvCostSourceOptions, DEFAULT_ANOMALY_THRESHOLDS, DEFAULT_FAST_MODEL, DEFAULT_INGEST_QUOTA, DEFAULT_LEAD_MODEL, DEFAULT_SERVER_NAME, DEFAULT_TENANT, DOMAIN_COLORS, DOMAIN_PALETTE, DRIFT_FIELDS, type DashboardOptions, type DataAsset, DataAssetSchema, type DependencyQuery, type DiscoveryEdge, type DiscoveryEvent, type DiscoveryFn, type DiscoveryNode, type DriftAlert, type DriftAlertItem, type DriftConfig, DriftConfigSchema, type DriftField, type DriftItemKind, type DriftRunRow, type DriftSink, type DriftSinkConfig, EDGE_RELATIONSHIPS, type EdgeRelationship, type EdgeRow, EdgeSchema, type EmbeddingProvider, type EnrichResult, type EntryOptions, type EstablishedConn, type EvidenceKind, type FetchLike, type FragmentKind, GraphStoreBackend, type GraphSummary, type HealthResult, type HttpOptions, INGEST_SCHEMA_VERSION, type IngestEnvelope, IngestEnvelopeSchema, type IngestHandler, type IngestHandlerOptions, type IngestOptions, type IngestResponse, type IngestResult, type InstallPlan, InvalidTenantError, type JiraIssue, type JiraOptions, JiraSink, type JiraSinkOptions, LOOPBACK_HOSTS, type LocalDiscoveryOptions, type LocalDiscoveryResult, type LogEntry, type LogLevel, MCP_BIN, type MatchStrategy, NODE_TYPES, NODE_TYPE_GROUPS, type NlIntent, type NlQueryOptions, type NlQueryResult, type NlRelation, type NodeAttribution, type NodeChange, type NodeIdentity, type NodeQuery, type NodeRow, NodeSchema, type NodeSignals, type NodeType, type NodesResult, NotFoundError, OUTPUT_FORMATS, type OperatorCycleResult, type OperatorOptions, type OrgKeyOptions, type OrgSummary, type OsKind, type OutputFormat, PACKAGE_NAME, PAGERDUTY_ENQUEUE_URL, PENDING_STATUSES, PERSONAL, PORT_MAP, PRIVATE_IP, PUSH_SCHEMA_VERSION, type PagerDutyEvent, PagerDutySink, type PagerDutySinkOptions, type ParsedApiArgs, type PendingShareRow, type PendingStatus, type PlanOptions, type PolicyResult, type PostJsonOptions, type Principal, PrincipalSchema, type ProviderFactory, type ProviderName, ProviderRegistry, type PushItem, type PushOptions, type PushResult, type QueryBackend, type QuotaConfig, type QuotaDecision, RELATION_TO_DIRECTION, ROLES, RateLimiter, type ResolveContext, type ResolveOptions, type Role, RoleSchema, type RuleCheck, RuleCheckSchema, type RuleScope, type Ruleset, RulesetSchema, type RunDriftOptions, SCAN_ARG_PATTERNS, SCHEMA_VERSION, SDL, SECURITY_METADATA_KEYS, SEVERITIES, SEVERITY_WEIGHT, SHARING_LEVELS, type ScanArgKind, type ScanContext, type ScanHintParams, type ScanResult, type Scanner, type ScannerPlugin, type ScannerPluginApi, ScannerRegistry, ScannerShape, type ScheduleConfig, ScheduleConfigSchema, type ScheduledRunResult, type Scope, type SearchFn, type SemanticSearchOptions, type ServerEntry, type SessionRow, type Severity, type SharePreview, type SharePreviewEntry, type SharingLevel, SharingLevelSchema, type SharingPolicy, type ShellKind, type SlackMessage, SlackSink, SqliteCredentialStore, SqliteQueryBackend, SqliteStoreBackend, type StartApiOptions, StdoutSink, type StoreBackend, type StoreBackendOptions, type SyncClassifyOptions, type SyncClassifyResult, TENANT_HEADER, type TenantContext, TenantMismatchError, type TenantOptions, type ToolResult, type TopologyDelta, type TopologyDiff, type TopologyInput, type TraversalResult, VectorStore, WebhookSink, type WebhookSinkOptions, applyInstall, applySharingLevel, assertReadOnly, assertSafeBind, assertSafeScanArg, assertSameTenant, assignColors, authorize, bearerToken, bookmarksScanner, buildCartographyToolHandlers, buildMapData, buildOpenApiDocument, buildReport, buildSinks, can, centralDbFromEnv, checkBearer, checkPrerequisites, checkReadOnly, clampText, classify, classifyDrift, cleanupTempFiles, cloudAwsScanner, cloudAzureScanner, cloudGcpScanner, codeAddMcpCommand, computeCentroid, computeClusterBounds, computeIdentity, connectionsScanner, contentHash, correlateTopology, createBashTool, createCartographyTools, createClaudeProvider, createDefaultRegistry, createHashEmbedder, createIngestHandler, createLocalEmbedder, createMcpServer, createOllamaProvider, createOpenAIProvider, createScanRunner, createSemanticSearch, createSqliteQueryBackend, currentOs, cursorDeeplink, dashboardHtml, databasesScanner, deepMerge, defaultAllowedHosts, defaultConfig, defaultContext, defaultProviderRegistry, defaultRegistry, defaultServerEntry, definePlugin, deriveSessionName, detectAnomalies, detectOrphans, detectShadowIt, diffTopology, edgesToConnections, enrichCosts, entitiesToYaml, evaluateCheck, evaluateRule, evidenceLine, executeGraphql, executeNlQuery, exportAll, exportBackstageYAML, exportComplianceReport, exportCostCSV, exportCostSummary, exportDiscoveryApp, exportJGF, exportJSON, extractListeningPorts, extractSignals, filterBySeverity, findAnonViolations, formatComplianceText, formatJira, formatPagerDuty, formatSlack, generateDependencyMermaid, generateDiffMermaid, generateTopologyMermaid, getClient, getRuleset, globalId, groupByDomain, handleGraphqlGet, hashToken, hexCorners, hexDistance, hexNeighbors, hexRing, hexSpiral, hexToPixel, hmacKey, hostname, ingestEnvelope, installedAppsScanner, isInCluster, isLoopbackHost, isPersonalHost, isReadOnlyCommand, isRemembered, isSecureWebhookUrl, k8sRegistry, k8sScanner, keyMetaOf, layoutClusters, listClients, listRulesets, loadConfig, loadOrgKey, loadPlugins, loadRuleset, localDiscoveryFn, log, logDebug, logError, logInfo, logWarn, machineId, maxSeverity, mcpServerObject, newAnomalies, nextRun, nodesToAssets, normalizeId, normalizeTenant, openStoreBackend, orgKeyPath, osUser, parseApiArgs, parseComposeDeps, parseConfig, parseConnectionString, parseCostCsv, parseCron, parseEstablished, parseNginxUpstreams, parseNlQuery, parseScanHint, parseTerraformState, pixelToHex, planInstall, portsScanner, postJson, previewShare, pseudonymize, pseudonymizeFragment, pseudonymizeId, pseudonymizeString, pushDeltas, readConfigFile, redactConnectionString, redactSecrets, redactValue, renderDiff, resolveEffectiveLevel, resolveNlQuery, resolvePrincipal, resolveSharingLevel, resolveTenant, revalidateAnonymized, reversalKey, reversePseudonym, rotateOrgKey, runApi, runDiscovery, runDrift, runHttp, runLocalDiscovery, runOnce, runOperator, runOperatorCycle, runStdio, runSyncClassify, safeEnv, safeJson, safetyHook, sanitizeUntrusted, sanitizeValue, scopeReads, scoreTopology, securityRelevantChange, serializeConfig, serviceConfigScanner, setVerbose, shadeVariant, shapeToJsonSchema, shareHash, splitSegments, stableStringify, startApi, stripSensitive, terraformScanner, terraformTypeToNode, timingSafeEqual, toBackstageEntities, validateScanner, vscodeDeeplink, zodToJsonSchema };
package/dist/index.js CHANGED
@@ -4652,6 +4652,8 @@ function reversalKey(orgKey) {
4652
4652
  // src/anonymize.ts
4653
4653
  var PRIVATE_IP = /\b(?:10(?:\.\d{1,3}){3}|192\.168(?:\.\d{1,3}){2}|172\.(?:1[6-9]|2\d|3[01])(?:\.\d{1,3}){2})\b/g;
4654
4654
  var HOSTNAME = /\b(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,}\b/gi;
4655
+ var BARE_INTERNAL_HOST = /^[a-z0-9]+(?:-[a-z0-9]+)+$|^[a-z]+\d+$|^\d+[a-z]+$/i;
4656
+ var ANON_TOKEN = /^anon:(?:host|user|path|ip):[a-z2-7]+$/;
4655
4657
  var POSIX_PATH = /(?:^|(?<=\s|=|:|"|'|\())(\/[A-Za-z0-9._-]+(?:\/[A-Za-z0-9._-]+)+)/g;
4656
4658
  var WIN_PATH = /\b[A-Za-z]:\\[A-Za-z0-9._\\-]+/g;
4657
4659
  var B32_ALPHABET = "abcdefghijklmnopqrstuvwxyz234567";
@@ -4706,8 +4708,18 @@ function pseudonymizeString(s, orgKey, db) {
4706
4708
  (_m, user, host2) => `${pseudonymizeFragment(user, "user", orgKey, db)}@${pseudonymizeFragment(host2, "host", orgKey, db)}`
4707
4709
  );
4708
4710
  out = out.replace(HOSTNAME, (m) => pseudonymizeFragment(m, "host", orgKey, db));
4711
+ const trimmed = out.trim();
4712
+ if (out === s && !ANON_TOKEN.test(trimmed) && BARE_INTERNAL_HOST.test(trimmed)) {
4713
+ out = pseudonymizeFragment(trimmed, "host", orgKey, db);
4714
+ }
4709
4715
  return out;
4710
4716
  }
4717
+ function pseudonymizeId(id, orgKey, db) {
4718
+ const segments = id.split(":");
4719
+ if (segments.length <= 1) return pseudonymizeString(id, orgKey, db);
4720
+ const [type, ...rest] = segments;
4721
+ return [type, ...rest.map((seg) => pseudonymizeString(seg, orgKey, db))].join(":");
4722
+ }
4711
4723
  function pseudonymize(value, orgKey, db) {
4712
4724
  if (typeof value === "string") return pseudonymizeString(value, orgKey, db);
4713
4725
  if (Array.isArray(value)) return value.map((v) => pseudonymize(v, orgKey, db));
@@ -4734,8 +4746,6 @@ var FQDN = /\b(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,}\b/gi;
4734
4746
  var POSIX_PATH2 = /(?:^|(?<=\s|=|:|"|'|\())(\/[A-Za-z0-9._-]+(?:\/[A-Za-z0-9._-]+)+)/g;
4735
4747
  var WIN_PATH2 = /\b[A-Za-z]:\\[A-Za-z0-9._\\-]+/g;
4736
4748
  var HOME_USER = /(?:\/home\/|\/Users\/|[A-Za-z]:\\Users\\)([A-Za-z0-9._-]+)/g;
4737
- var BARE_INTERNAL_HOST = /^[a-z0-9]+(?:-[a-z0-9]+)+$|^[a-z]+\d+$|^\d+[a-z]+$/i;
4738
- var ANON_TOKEN = /^anon:(?:host|user|path|ip):[a-z2-7]+$/;
4739
4749
  function violationsInString(s, path) {
4740
4750
  const out = [];
4741
4751
  const trimmed = s.trim();
@@ -5125,9 +5135,10 @@ function resolveEffectiveLevel(node, policy) {
5125
5135
  function applySharingLevel(node, level, orgKey, db) {
5126
5136
  if (level === "none") return null;
5127
5137
  if (level === "full") return { ...node, metadata: { ...node.metadata ?? {} }, tags: [...node.tags ?? []] };
5138
+ const { globalId: _g, contentHash: _h, ...rest } = node;
5128
5139
  return {
5129
- ...node,
5130
- id: pseudonymizeString(node.id, orgKey, db),
5140
+ ...rest,
5141
+ id: pseudonymizeId(node.id, orgKey, db),
5131
5142
  name: pseudonymizeString(node.name, orgKey, db),
5132
5143
  metadata: pseudonymize(node.metadata ?? {}, orgKey, db),
5133
5144
  tags: (node.tags ?? []).map((t) => pseudonymizeString(t, orgKey, db))
@@ -5979,7 +5990,7 @@ function correlateTopology(nodes, _edges = []) {
5979
5990
 
5980
5991
  // src/mcp/server.ts
5981
5992
  var SERVER_NAME = "cartography";
5982
- var SERVER_VERSION = "2.11.0";
5993
+ var SERVER_VERSION = "2.12.1";
5983
5994
  var SERVICE_TYPES = NODE_TYPE_GROUPS.web;
5984
5995
  var DATA_TYPES = NODE_TYPE_GROUPS.data;
5985
5996
  var lexicalSearch = async (db, sessionId, query, opts) => db.searchNodes(sessionId, query, { types: opts.types, limit: opts.limit }).map((node) => ({ node }));
@@ -9901,6 +9912,63 @@ Use ask_user when you need context from the user.`;
9901
9912
  }
9902
9913
  }
9903
9914
 
9915
+ // src/k8s/operator.ts
9916
+ function k8sRegistry() {
9917
+ return new ScannerRegistry().register(k8sScanner);
9918
+ }
9919
+ function isInCluster(env = process.env) {
9920
+ return typeof env["KUBERNETES_SERVICE_HOST"] === "string" && env["KUBERNETES_SERVICE_HOST"].length > 0;
9921
+ }
9922
+ function pruneToRetention(db, keep, tenant) {
9923
+ const stale = db.getSessions(tenant).slice(Math.max(1, keep));
9924
+ for (const s of stale) db.deleteSession(s.id);
9925
+ return stale.length;
9926
+ }
9927
+ async function runOperatorCycle(db, config, opts = {}) {
9928
+ const sessionId = db.createSession("discover", config);
9929
+ const discover = opts.discover ?? ((d, s) => runLocalDiscovery(d, s, { registry: k8sRegistry() }));
9930
+ const res = await discover(db, sessionId);
9931
+ const sess = db.getSession(sessionId);
9932
+ if (sess && !sess.name) db.setSessionName(sessionId, deriveSessionName(db.getGraphSummary(sessionId), sess.startedAt));
9933
+ const driftFn = opts.drift ?? ((d, c) => runDrift(d, c));
9934
+ const drift = await driftFn(db, config);
9935
+ pruneToRetention(db, opts.retain ?? 10, normalizeTenant(config.organization));
9936
+ return { sessionId, nodes: res.nodes, edges: res.edges, drift };
9937
+ }
9938
+ async function runOperator(db, config, opts = {}) {
9939
+ const log2 = opts.log ?? ((m) => process.stderr.write(m + "\n"));
9940
+ const intervalMs = opts.intervalMs ?? 5 * 6e4;
9941
+ const sleep = opts.sleep ?? ((ms) => new Promise((resolve3) => {
9942
+ if (opts.signal?.aborted) {
9943
+ resolve3();
9944
+ return;
9945
+ }
9946
+ const t = setTimeout(() => {
9947
+ opts.signal?.removeEventListener?.("abort", onAbort);
9948
+ resolve3();
9949
+ }, ms);
9950
+ const onAbort = () => {
9951
+ clearTimeout(t);
9952
+ resolve3();
9953
+ };
9954
+ opts.signal?.addEventListener?.("abort", onAbort, { once: true });
9955
+ }));
9956
+ log2(`Cartograph Kubernetes operator (in-cluster: ${isInCluster()}, interval: ${Math.round(intervalMs / 1e3)}s${opts.once ? ", single pass" : ""})`);
9957
+ for (; ; ) {
9958
+ try {
9959
+ const c = await runOperatorCycle(db, config, opts);
9960
+ log2(
9961
+ `reconcile: session ${c.sessionId} \u2014 ${c.nodes} nodes, ${c.edges} edges` + (c.drift ? `, drift ${c.drift.severity} (${c.drift.items.length} change${c.drift.items.length === 1 ? "" : "s"})` : ", no drift")
9962
+ );
9963
+ } catch (err) {
9964
+ log2(`reconcile failed: ${err instanceof Error ? err.message : String(err)}`);
9965
+ }
9966
+ if (opts.once || opts.signal?.aborted) return;
9967
+ await sleep(intervalMs);
9968
+ if (opts.signal?.aborted) return;
9969
+ }
9970
+ }
9971
+
9904
9972
  // src/cost.ts
9905
9973
  import { readFileSync as readFileSync7 } from "fs";
9906
9974
  import { resolve as resolve2 } from "path";
@@ -12188,9 +12256,11 @@ function checkClaudePrerequisites() {
12188
12256
  }
12189
12257
  export {
12190
12258
  ACTIONS,
12259
+ ANON_TOKEN,
12191
12260
  ActionSchema,
12192
12261
  AuthConfigSchema,
12193
12262
  AuthorizationError,
12263
+ BARE_INTERNAL_HOST,
12194
12264
  CLIENTS,
12195
12265
  CONFIDENCE,
12196
12266
  CORRELATION_CONFIDENCE,
@@ -12354,11 +12424,13 @@ export {
12354
12424
  hostname,
12355
12425
  ingestEnvelope,
12356
12426
  installedAppsScanner,
12427
+ isInCluster,
12357
12428
  isLoopbackHost,
12358
12429
  isPersonalHost,
12359
12430
  isReadOnlyCommand,
12360
12431
  isRemembered,
12361
12432
  isSecureWebhookUrl,
12433
+ k8sRegistry,
12362
12434
  k8sScanner,
12363
12435
  keyMetaOf,
12364
12436
  layoutClusters,
@@ -12403,6 +12475,7 @@ export {
12403
12475
  previewShare,
12404
12476
  pseudonymize,
12405
12477
  pseudonymizeFragment,
12478
+ pseudonymizeId,
12406
12479
  pseudonymizeString,
12407
12480
  pushDeltas,
12408
12481
  readConfigFile,
@@ -12425,6 +12498,8 @@ export {
12425
12498
  runHttp,
12426
12499
  runLocalDiscovery,
12427
12500
  runOnce,
12501
+ runOperator,
12502
+ runOperatorCycle,
12428
12503
  runStdio,
12429
12504
  runSyncClassify,
12430
12505
  safeEnv,