@skill-map/cli 0.35.0 → 0.37.0

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.
@@ -552,6 +552,55 @@ interface LinkLocation {
552
552
  column?: number;
553
553
  offset?: number;
554
554
  }
555
+ /**
556
+ * One syntactic site in the source node's body that contributed to a
557
+ * `Link`. Multiple occurrences accumulate when the same edge is detected
558
+ * by more than one extractor (e.g. `@./foo.md` from `at-directive` and
559
+ * `[label](./foo.md)` from `markdown-link` both resolve to the same
560
+ * target), or when the same extractor walks an extractor-internal
561
+ * dedup boundary. Today the merged edge's `trigger` / `location`
562
+ * mirror the FIRST occurrence; the array carries every site so the
563
+ * `core/redundant-target-reference` analyzer can flag multi-form
564
+ * references and rename operations can find every author surface.
565
+ */
566
+ interface LinkOccurrence {
567
+ /**
568
+ * Extractor id that observed this occurrence. Matches an entry of
569
+ * the parent `Link.sources[]` (extractor + occurrence are not 1:1,
570
+ * the same extractor can produce multiple occurrences when the
571
+ * intra-extractor dedup is relaxed in the future).
572
+ */
573
+ extractor: string;
574
+ /**
575
+ * Original substring as it appeared in the body (`@./real-agent.md`,
576
+ * `[deploy](./deploy.md)`, `/help`, `@team-lead`). Preserves author
577
+ * casing and the leading sigil so the analyzer can surface it
578
+ * verbatim in fix-up messages.
579
+ */
580
+ originalTrigger: string;
581
+ /**
582
+ * Position of the occurrence in the body. Optional, an extractor
583
+ * that does not track line numbers yet (legacy emit paths) omits
584
+ * this field; the analyzer falls back to "unknown line" in messages.
585
+ */
586
+ location?: LinkLocation | null;
587
+ }
588
+ /**
589
+ * External URL referenced from a node's body. Populated by the
590
+ * `core/external-url-counter` extractor and surfaced on the node so
591
+ * the inspector can list every outgoing http(s) reference without
592
+ * re-walking the body. Distinct from internal `Link` (which connects
593
+ * nodes inside the graph), external refs are leaf metadata: no
594
+ * counterparty node, no resolution.
595
+ */
596
+ interface IExternalRef {
597
+ /** Normalised URL (lowercased host, fragment stripped). */
598
+ url: string;
599
+ /** 1-indexed line of the occurrence in the source body, when known. */
600
+ line?: number;
601
+ /** Verbatim author substring (sigil-free; usually equals `url`). */
602
+ originalTrigger?: string;
603
+ }
555
604
  interface Node {
556
605
  path: string;
557
606
  /**
@@ -570,6 +619,15 @@ interface Node {
570
619
  linksOutCount: number;
571
620
  linksInCount: number;
572
621
  externalRefsCount: number;
622
+ /**
623
+ * Distinct external URLs referenced from this node's body, in
624
+ * extractor-order (first-seen wins, dedup is by normalised URL).
625
+ * Empty / absent when the body has no http(s) URLs. The denormalised
626
+ * `externalRefsCount` MUST equal `externalRefs.length` whenever
627
+ * both are present. Surfaced via `/api/nodes` so the inspector can
628
+ * list each URL without an extra round-trip.
629
+ */
630
+ externalRefs?: IExternalRef[];
573
631
  frontmatter?: Record<string, unknown>;
574
632
  tokens?: TripleSplit;
575
633
  /**
@@ -657,6 +715,30 @@ interface Link {
657
715
  sources: string[];
658
716
  trigger?: LinkTrigger | null;
659
717
  location?: LinkLocation | null;
718
+ /**
719
+ * Every syntactic site in the source body that contributed to this
720
+ * edge. Populated by extractors at emit time (one entry per emission)
721
+ * and accumulated by `dedupeLinks` when two extractors converge on the
722
+ * same `(source, target, kind, normalizedTrigger)` key. Empty / absent
723
+ * for legacy emits or for synthetic links (frontmatter-driven
724
+ * references, sidecar annotations) that have no body position. The
725
+ * `core/redundant-target-reference` analyzer walks this array to
726
+ * detect multi-form references to the same target from one body.
727
+ */
728
+ occurrences?: LinkOccurrence[];
729
+ /**
730
+ * Node path the link resolves to, when the post-walk
731
+ * `liftResolvedLinkConfidence` transform succeeded in matching the
732
+ * (trigger-style or path-style) target against the live graph. Equal
733
+ * to `link.target` for path-style links that hit a node directly;
734
+ * different from `link.target` for trigger-style links (a Claude
735
+ * `@real-agent` mention resolves to `.claude/agents/real-agent.md`,
736
+ * but `link.target` keeps the authored trigger). Absent when the
737
+ * link is unresolved (broken). The BFF `/api/links?to=<path>` uses
738
+ * this field to surface incoming edges that reach the node by name,
739
+ * not just by literal path.
740
+ */
741
+ resolvedTarget?: string | null;
660
742
  raw?: string | null;
661
743
  }
662
744
  /**
@@ -677,11 +759,16 @@ type SignalScope = 'body' | 'frontmatter' | 'sidecar';
677
759
  type SignalContext = 'code-block' | 'inline-code' | 'escaped';
678
760
  /**
679
761
  * Byte-range location for a body-scope `Signal`. `start` is inclusive,
680
- * `end` is exclusive (one past the last char).
762
+ * `end` is exclusive (one past the last char). `line` is the optional
763
+ * 1-indexed line number containing `start`, populated by extractors
764
+ * that already compute line tracking via `computeLineStarts` so the
765
+ * resolver's materialised `Link` preserves `link.location.line`
766
+ * without re-walking the body.
681
767
  */
682
768
  interface SignalRange {
683
769
  start: number;
684
770
  end: number;
771
+ line?: number;
685
772
  }
686
773
  /**
687
774
  * One alternative interpretation of a `Signal`. The resolver picks the
@@ -735,6 +822,59 @@ interface Signal {
735
822
  context?: SignalContext | null;
736
823
  /** One or more alternative interpretations. At least one. */
737
824
  candidates: SignalCandidate[];
825
+ /**
826
+ * Resolver outcome annotation, populated by `resolveSignals`. Absent on
827
+ * raw extractor emissions (before the resolver runs). When
828
+ * `outcome === 'materialised'`, `winnerIndex` points into `candidates[]`
829
+ * of the candidate the resolver chose; a corresponding `Link` was added
830
+ * to the graph. When `outcome === 'rejected'`, one of `rejectedBy` /
831
+ * `extractorDisabled` / `belowFloor` is set and no Link materialised.
832
+ * Both materialised and rejected Signals remain on
833
+ * `IAnalyzerContext.signals` so the `core/signal-collision` analyzer can
834
+ * surface losers as `warn` issues. Mirrors
835
+ * `signal.schema.json#/properties/resolution`.
836
+ */
837
+ resolution?: ISignalResolution;
838
+ }
839
+ /**
840
+ * Why the resolver chose to materialise or reject a `Signal`. Populated by
841
+ * `resolveSignals`; carries no meaning before that pass.
842
+ */
843
+ interface ISignalResolution {
844
+ outcome: 'materialised' | 'rejected';
845
+ /** Index into `Signal.candidates[]` of the winner. Set when `outcome === 'materialised'`. */
846
+ winnerIndex?: number;
847
+ /**
848
+ * Set when the Signal lost a cross-extractor range-overlap collision
849
+ * against another Signal at the same `source`. Names the winning Signal
850
+ * so an analyzer (or the operator drilling into the sidecar) can see WHO
851
+ * won and WHY.
852
+ */
853
+ rejectedBy?: {
854
+ source: string;
855
+ range: SignalRange;
856
+ /** Qualified id (`<plugin>/<extractor>`) of the winning candidate's extractor. */
857
+ extractorId: string;
858
+ reason: 'kind-priority' | 'higher-confidence' | 'longer-range' | 'earlier-declaration';
859
+ };
860
+ /**
861
+ * Phase 4+ stub: populated when every candidate of this Signal came from
862
+ * an extractor the operator disabled via
863
+ * `plugins.<id>.extensions.<extId>.enabled`. Today the resolver never
864
+ * sets this; documented so analyzer surfaces can be built when the filter
865
+ * lands.
866
+ */
867
+ extractorDisabled?: {
868
+ extractorId: string;
869
+ };
870
+ /**
871
+ * Phase 4+ stub: populated when every candidate's `confidence` fell below
872
+ * the configured floor. Today the resolver materialises every Signal that
873
+ * survives overlap regardless of confidence.
874
+ */
875
+ belowFloor?: {
876
+ threshold: number;
877
+ };
738
878
  }
739
879
  interface IssueFix {
740
880
  summary?: string;
@@ -1756,12 +1896,12 @@ interface IProviderKind {
1756
1896
  * kinds (`agent`, `command`, `skill` per their schemas) typically
1757
1897
  * declare this first.
1758
1898
  * - `'filename-basename'`, `basename(path)` without the extension.
1759
- * For Claude/Gemini/OpenAI agents and commands the filename IS the
1899
+ * For Claude/OpenAI agents and commands the filename IS the
1760
1900
  * invocation handle when `name:` is absent.
1761
- * - `'dirname'`, `basename(dirname(path))`. Anthropic skills + Gemini
1762
- * skills + agent-skills resolve to the directory between the
1763
- * skills root and the SKILL.md (e.g.
1764
- * `.claude/skills/foo/SKILL.md` → `foo`).
1901
+ * - `'dirname'`, `basename(dirname(path))`. Anthropic skills +
1902
+ * agent-skills (open standard, also adopted by Antigravity)
1903
+ * resolve to the directory between the skills root and the
1904
+ * SKILL.md (e.g. `.claude/skills/foo/SKILL.md` → `foo`).
1765
1905
  *
1766
1906
  * Compare with `IProvider.resolution` (which declares which target
1767
1907
  * kinds resolve which link.kind): `identifiers` is a per-kind detail
@@ -1930,7 +2070,7 @@ interface IProvider extends IExtensionBase {
1930
2070
  * orchestrator drops the duplicate.
1931
2071
  *
1932
2072
  * Convention: a Provider's classify returns one of its own `kinds`
1933
- * map keys for paths in its territory (`.claude/`, `.gemini/`,
2073
+ * map keys for paths in its territory (`.claude/`, `.codex/`,
1934
2074
  * `.agents/skills/`, etc.) and `null` elsewhere. External Providers
1935
2075
  * (Cursor, Obsidian, …) follow the same rule: claim what's yours,
1936
2076
  * disclaim everything else. The orchestrator does not validate the
@@ -1969,6 +2109,107 @@ interface IProvider extends IExtensionBase {
1969
2109
  * confidence-lift contract, which runs against the merged Link graph.
1970
2110
  */
1971
2111
  resolution?: Record<string, string[]>;
2112
+ /**
2113
+ * Lens gating flag for vendor providers. When `true`, this Provider's
2114
+ * `classify()` only runs (and the walker only iterates its territory)
2115
+ * if `provider.id === activeProvider` (the project's active lens).
2116
+ * When `false` or omitted (default), the Provider is universal and
2117
+ * classifies unconditionally, regardless of the active lens.
2118
+ *
2119
+ * Vendor providers (`claude`, `openai`, `antigravity`) MUST set this
2120
+ * to `true`: the actual runtimes never read each other's on-disk
2121
+ * formats (Claude Code does not consume `.codex/`; Codex CLI does not
2122
+ * consume `.claude/`), and offering every file to every provider
2123
+ * fabricates cross-vendor graph edges the runtimes themselves reject.
2124
+ *
2125
+ * Universal providers (the open-standard `agent-skills`, the markdown
2126
+ * fallback `core/markdown`, any future format-based fallback) keep
2127
+ * this `false`: their territory is consumed by every vendor and they
2128
+ * MUST run on every scan, regardless of the active lens.
2129
+ *
2130
+ * When `activeProvider === null` (no lens resolved, e.g. a project
2131
+ * with no provider markers), the walker bypasses the gate entirely
2132
+ * and every gated Provider runs, mirroring the permissive
2133
+ * extractor-side fallback for unlensed projects.
2134
+ *
2135
+ * Default `undefined` ≡ `false` ≡ universal. The field affects
2136
+ * classification ONLY; extractors continue to filter via their own
2137
+ * `precondition.provider` allowlist and are unaffected by this flag.
2138
+ */
2139
+ gatedByActiveLens?: boolean;
2140
+ /**
2141
+ * Reserved invocation names this Provider's runtime owns for each
2142
+ * kind. Maps a `node.kind` to the set of normalised names the runtime
2143
+ * uses for its built-in invocables (e.g. `claude` reserves
2144
+ * `['help', 'clear', 'init', …]` under `command` because typing
2145
+ * `/help` in the Claude CLI runs the built-in help screen, not a
2146
+ * user-authored `.claude/commands/help.md`).
2147
+ *
2148
+ * Two consumers share the catalog:
2149
+ *
2150
+ * 1. The `core/reserved-name` analyzer scans every user node and
2151
+ * emits a `warn` issue when the node's normalised identifiers
2152
+ * (per `IProviderKind.identifiers`) intersect the reserved list
2153
+ * for its provider + kind. The user file is silently shadowed
2154
+ * by the runtime, the analyzer surfaces it so the operator can
2155
+ * rename.
2156
+ * 2. The post-walk confidence-lift transform downgrades any link
2157
+ * that resolves to a reserved node (by path OR by name) to a
2158
+ * very low confidence floor (today `0.1`) instead of bumping
2159
+ * to `1.0`. The graph then reflects "this edge exists in disk
2160
+ * but the runtime ignores the target".
2161
+ *
2162
+ * Default `undefined` ≡ empty map ≡ no reserved names. Reserved
2163
+ * lookup normalises both sides via the §Extractor · trigger
2164
+ * normalization pipeline (lowercase, NFD, separator unification),
2165
+ * so a literal `Init-Project` in the manifest still matches a user
2166
+ * `name: init project` or filename `Init-Project.md`.
2167
+ *
2168
+ * The set is intentionally per-kind, not global: a name reserved for
2169
+ * commands (`/help`) may legitimately appear as a skill (a "help"
2170
+ * skill that triggers via something other than the command channel).
2171
+ * Providers MUST scope each entry to the kind the runtime actually
2172
+ * consumes.
2173
+ */
2174
+ reservedNames?: Record<string, readonly string[]>;
2175
+ /**
2176
+ * Per-Provider ranking hints consumed by the Signal IR **resolver
2177
+ * phase** (kernel `resolveSignals`). Drives intra-Signal candidate
2178
+ * selection AND cross-Signal range-overlap tiebreaks.
2179
+ *
2180
+ * Optional, when absent the resolver uses the default tiebreak chain:
2181
+ * `confidence` DESC → `range` length DESC → extractor declaration
2182
+ * order. Most Providers do not need to declare this; the default chain
2183
+ * is correct unless the Provider has a kind-specific preference (e.g.
2184
+ * "treat `invokes` edges as more important than `mentions` of the
2185
+ * same range").
2186
+ *
2187
+ * Distinct from the `resolution` field above: `resolverRules` ranks
2188
+ * candidates INSIDE the Signal IR (the candidate that becomes a Link
2189
+ * in the first place); `resolution` ranks Links AFTER they exist
2190
+ * (confidence lift on already-emitted edges). The two surfaces share
2191
+ * no mechanism and intentionally do not compose.
2192
+ */
2193
+ resolverRules?: IResolverRules;
2194
+ }
2195
+ /**
2196
+ * Per-Provider Signal IR resolver ranking hints. Mirrors
2197
+ * `extensions/provider.schema.json#/properties/resolverRules`.
2198
+ */
2199
+ interface IResolverRules {
2200
+ /**
2201
+ * When present, the resolver ranks candidates whose `kind` appears
2202
+ * earlier in this array ABOVE candidates whose `kind` appears later.
2203
+ * Candidates whose `kind` is absent from the array drop to the end
2204
+ * (after every listed kind). Ties inside the same `kindPriority`
2205
+ * bucket fall through to the `confidence` → range-length → declaration
2206
+ * order tiebreaks.
2207
+ *
2208
+ * Example: a Provider that wants `invokes` edges to win against
2209
+ * `mentions` / `references` of the same byte range declares
2210
+ * `['invokes', 'references', 'mentions']`.
2211
+ */
2212
+ kindPriority?: readonly LinkKind[];
1972
2213
  }
1973
2214
  /**
1974
2215
  * Declarative read config a Provider declares via `IProvider.read`.
@@ -2234,6 +2475,21 @@ interface IAnalyzerContext {
2234
2475
  * adapter does not maintain the side index. Treat as read-only.
2235
2476
  */
2236
2477
  referenceablePaths?: ReadonlySet<string>;
2478
+ /**
2479
+ * Paths of nodes whose normalised identifier(s) intersect their
2480
+ * Provider's `reservedNames[kind]` catalog (e.g. a user-authored
2481
+ * `.claude/commands/help.md` whose name normalises to `help`,
2482
+ * shadowed by Claude's built-in `/help` command). The set is
2483
+ * computed once per scan by the orchestrator (mirroring the same
2484
+ * set threaded to the post-walk confidence-lift transform), so
2485
+ * analyzers consume it without re-deriving every node's
2486
+ * identifiers. The single consumer today is `core/reserved-name`,
2487
+ * which projects one warn issue per entry; future analyzers MAY
2488
+ * read the set for cross-rule cohesion (e.g. an action that
2489
+ * suggests rename targets). Absent for legacy callers (older
2490
+ * `runScan` sites that never wired the field through).
2491
+ */
2492
+ reservedNodePaths?: ReadonlySet<string>;
2237
2493
  /**
2238
2494
  * Absolute path of the scan's project root (cwd of the invocation).
2239
2495
  * Threaded into the analyzer pass so an analyzer that needs to
@@ -3048,8 +3304,8 @@ interface RunScanOptions {
3048
3304
  * - `null`: explicit "no lens". Provider-specific extractors are
3049
3305
  * unconditionally skipped (spec-strict).
3050
3306
  * - `undefined`: kernel auto-detects from `options.roots[0]` using
3051
- * filesystem markers (`.claude/`, `.gemini/`, `.codex/`,
3052
- * `AGENTS.md`). Convenient default for out-of-band callers
3307
+ * filesystem markers (`.claude/`, `.codex/`, `AGENTS.md`).
3308
+ * Convenient default for out-of-band callers
3053
3309
  * (integration tests, embedders) that don't thread a settings
3054
3310
  * reader. Production callers (scan-runner) resolve upstream and
3055
3311
  * pass `string | null` explicitly, never `undefined`.
@@ -4042,4 +4298,4 @@ interface Kernel {
4042
4298
  }
4043
4299
  declare function createKernel(): Kernel;
4044
4300
 
4045
- export { type Confidence, DuplicateExtensionError, EXTENSION_KINDS, type ExecutionFailureReason, type ExecutionKind, type ExecutionRecord, type ExecutionRunner, type ExecutionStatus, ExportQueryError, type Extension, type ExtensionKind, type FilesystemPort, HOOK_TRIGGERS, type HistoryStats, type HistoryStatsErrorRates, type HistoryStatsExecutionsPerPeriod, type HistoryStatsPerActionRate, type HistoryStatsTokensPerAction, type HistoryStatsTopNode, type HistoryStatsTotals, type IAction, type IActionContext, type IActionPrecondition, type IActionResult, type IAnalyzer, type IAnalyzerContext, type IAnnotationContribution, type ICreateFsWatcherOptions, type IDedicatedStorePersist, type IDedicatedStoreWrapper, type IDiscoveredPlugin, type IEnrichmentRecord, type IExportQuery, type IExportSubset, type IExtensionBase, type IExtractor, type IExtractorCallbacks, type IExtractorContext, type IExtractorRunRecord, type IFormatter, type IFormatterContext, type IFsWatcher, type IHook, type IHookContext, type IHookDispatcher, type IIssueRow, type IKvStorePersist, type IKvStoreWrapper, type ILoadedExtension, type INodeBundle, type INodeChange, type INodeCounts, type INodeFilter, type IPersistOptions, type IPersistedEnrichment, type IPluginManifest, type IPluginStorageSchema, type IPluginStore, type IProvider, type IRawNode, type IRegisteredAnnotationKey, type IRegisteredViewContribution, type IRunOptions, type IRunResult, type IScanDelta, type ISettingDeclaration, type ITransactionalStorage, type IViewContribution, type IWalkOptions, type IWatchBatch, type IWatchEvent, InMemoryProgressEmitter, type Issue, type IssueFix, KV_SCHEMA_KEY, type Kernel, LOG_LEVELS, type Link, type LinkKind, type LinkLocation, type LinkTrigger, type LogRecord, type LoggerPort, type Node, type NodeKind, type NodeStat, type PluginLoaderPort, type ProgressEmitterPort, type ProgressEvent, Registry, type RenameOp, type RunScanOptions, type RunnerPort, type ScanResult, type ScanScannedBy, type ScanStats, type Severity, SilentLogger, type Stability, type StoragePort, type TActionWrite, type TExecutionMode, type TGranularity, type THookFilter, type THookTrigger, type TInputTypeName, type TLogLevel, type TLogMethodLevel, type TNodeChangeReason, type TPluginLoadStatus, type TPluginStorage, type TProgressListener, type TSettingValue, type TSeverity, type TSlotName, type TWatchEventKind, type TripleSplit, applyExportQuery, computeScanDelta, configureLogger, createChokidarWatcher, createKernel, detectRenamesAndOrphans, getActiveLogger, isEmptyDelta, isLogLevel, log, logLevelRank, makeDedicatedStoreWrapper, makeEvent, makeHookDispatcher, makeKvStoreWrapper, makePluginStore, mergeNodeWithEnrichments, parseExportQuery, parseLogLevel, qualifiedExtensionId, resetLogger, runExtractorsForNode, runScan, runScanWithRenames };
4301
+ export { type Confidence, DuplicateExtensionError, EXTENSION_KINDS, type ExecutionFailureReason, type ExecutionKind, type ExecutionRecord, type ExecutionRunner, type ExecutionStatus, ExportQueryError, type Extension, type ExtensionKind, type FilesystemPort, HOOK_TRIGGERS, type HistoryStats, type HistoryStatsErrorRates, type HistoryStatsExecutionsPerPeriod, type HistoryStatsPerActionRate, type HistoryStatsTokensPerAction, type HistoryStatsTopNode, type HistoryStatsTotals, type IAction, type IActionContext, type IActionPrecondition, type IActionResult, type IAnalyzer, type IAnalyzerContext, type IAnnotationContribution, type ICreateFsWatcherOptions, type IDedicatedStorePersist, type IDedicatedStoreWrapper, type IDiscoveredPlugin, type IEnrichmentRecord, type IExportQuery, type IExportSubset, type IExtensionBase, type IExternalRef, type IExtractor, type IExtractorCallbacks, type IExtractorContext, type IExtractorRunRecord, type IFormatter, type IFormatterContext, type IFsWatcher, type IHook, type IHookContext, type IHookDispatcher, type IIssueRow, type IKvStorePersist, type IKvStoreWrapper, type ILoadedExtension, type INodeBundle, type INodeChange, type INodeCounts, type INodeFilter, type IPersistOptions, type IPersistedEnrichment, type IPluginManifest, type IPluginStorageSchema, type IPluginStore, type IProvider, type IRawNode, type IRegisteredAnnotationKey, type IRegisteredViewContribution, type IRunOptions, type IRunResult, type IScanDelta, type ISettingDeclaration, type ITransactionalStorage, type IViewContribution, type IWalkOptions, type IWatchBatch, type IWatchEvent, InMemoryProgressEmitter, type Issue, type IssueFix, KV_SCHEMA_KEY, type Kernel, LOG_LEVELS, type Link, type LinkKind, type LinkLocation, type LinkOccurrence, type LinkTrigger, type LogRecord, type LoggerPort, type Node, type NodeKind, type NodeStat, type PluginLoaderPort, type ProgressEmitterPort, type ProgressEvent, Registry, type RenameOp, type RunScanOptions, type RunnerPort, type ScanResult, type ScanScannedBy, type ScanStats, type Severity, SilentLogger, type Stability, type StoragePort, type TActionWrite, type TExecutionMode, type TGranularity, type THookFilter, type THookTrigger, type TInputTypeName, type TLogLevel, type TLogMethodLevel, type TNodeChangeReason, type TPluginLoadStatus, type TPluginStorage, type TProgressListener, type TSettingValue, type TSeverity, type TSlotName, type TWatchEventKind, type TripleSplit, applyExportQuery, computeScanDelta, configureLogger, createChokidarWatcher, createKernel, detectRenamesAndOrphans, getActiveLogger, isEmptyDelta, isLogLevel, log, logLevelRank, makeDedicatedStoreWrapper, makeEvent, makeHookDispatcher, makeKvStoreWrapper, makePluginStore, mergeNodeWithEnrichments, parseExportQuery, parseLogLevel, qualifiedExtensionId, resetLogger, runExtractorsForNode, runScan, runScanWithRenames };