diffwiki-core 0.14.0 → 0.15.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.
@@ -0,0 +1,585 @@
1
+ /**
2
+ * Wire-protocol and SDK types shared by the plugin authoring SDK (`sdk.ts`) and
3
+ * re-exported to plugin authors via the `diffwiki-core/plugin` subpath.
4
+ *
5
+ * @module
6
+ */
7
+ /** Log severity levels for plugin diagnostic messages. */
8
+ type LogLevel = 'info' | 'warn' | 'error';
9
+ /** A logging function that plugins use to emit diagnostic messages to stderr. */
10
+ type PluginLogFn = (level: LogLevel, message: string) => void;
11
+ /** A wire-format collection as received in handler params. */
12
+ interface WireCollection {
13
+ name: string;
14
+ path: string;
15
+ }
16
+ /** Diagnostic entry returned by the health handler. */
17
+ interface WireDiagnostic {
18
+ level: 'ok' | 'warn' | 'error';
19
+ message: string;
20
+ }
21
+ /** Readiness details returned by the health handler. */
22
+ interface WireReadiness {
23
+ toolInstalled: boolean;
24
+ modelsPresent: boolean;
25
+ indexBuilt: boolean;
26
+ docsIndexed: number;
27
+ embeddingsPending: number;
28
+ firstSearchCost: 'instant' | 'model-load' | 'model-download';
29
+ }
30
+ /** A single search hit returned by the search handler. */
31
+ interface SearchHandlerHit {
32
+ collection: string;
33
+ relPath: string;
34
+ title: string;
35
+ snippet?: string;
36
+ score?: number;
37
+ docid?: string;
38
+ tags?: string[];
39
+ /** Verbatim engine chunk (unsanitized), surfaced in the search UI's inspection popover. */
40
+ rawChunk?: string;
41
+ /** The chunk cleaned to plain text, untruncated (full form for the popover). */
42
+ cleanedChunk?: string;
43
+ /** Absolute source line the chunk starts at, when the engine reports it. */
44
+ line?: number;
45
+ /** True when `snippet` is a body-preview fallback rather than the cleaned chunk. */
46
+ snippetFromBody?: boolean;
47
+ }
48
+ /** Result shape returned by the search handler. */
49
+ interface SearchHandlerResult {
50
+ hits: SearchHandlerHit[];
51
+ }
52
+ /** Result shape returned by the index handler. */
53
+ interface IndexHandlerResult {
54
+ indexed: number;
55
+ }
56
+ /** Result shape returned by the health handler. */
57
+ interface HealthHandlerResult {
58
+ ready: boolean;
59
+ readiness?: WireReadiness;
60
+ diagnostics: WireDiagnostic[];
61
+ }
62
+ /** Result shape returned by the setup handler. */
63
+ interface SetupHandlerResult {
64
+ ready: boolean;
65
+ steps?: Array<{
66
+ step: string;
67
+ ok: boolean;
68
+ message?: string;
69
+ }>;
70
+ }
71
+ /** Result shape returned by the onEvent handler. */
72
+ interface EventHandlerResult {
73
+ accepted: boolean;
74
+ }
75
+ /** Parameters passed to the search handler. */
76
+ /** A caller-supplied, pre-expanded query variant passed through to the engine. */
77
+ interface SearchExpansion {
78
+ type: 'lex' | 'vec' | 'hyde';
79
+ query: string;
80
+ }
81
+ interface SearchParams {
82
+ term: string;
83
+ collections: WireCollection[];
84
+ collection?: string;
85
+ type?: string;
86
+ limit?: number;
87
+ /** Pre-expanded query variants from an upstream LLM; engines that support
88
+ * structured search use these instead of expanding `term` themselves. */
89
+ expansions?: SearchExpansion[];
90
+ }
91
+ /** Parameters passed to the index handler. */
92
+ interface IndexParams {
93
+ collections: WireCollection[];
94
+ embed?: boolean;
95
+ }
96
+ /** Parameters passed to the setup handler. */
97
+ interface SetupParams {
98
+ collections: WireCollection[];
99
+ embed?: boolean;
100
+ prefetchModels?: boolean;
101
+ }
102
+ /** Parameters passed to the onEvent handler. */
103
+ interface EventParams {
104
+ event: string;
105
+ collection: WireCollection;
106
+ relPath?: string;
107
+ collections: WireCollection[];
108
+ }
109
+ /** Parameters passed to the health handler. */
110
+ interface HealthParams {
111
+ collections: WireCollection[];
112
+ }
113
+ /** Plugin capabilities advertised during describe. */
114
+ interface PluginCapabilities$1 {
115
+ searchTypes: string[];
116
+ collectionFilter: boolean;
117
+ events: boolean;
118
+ }
119
+ /**
120
+ * An external executable a plugin needs at runtime (e.g. `qmd`, `rg`).
121
+ *
122
+ * Declaring a dependency lets the plugin resolve the binary uniformly and lets
123
+ * `setup`/`health` report it. When `npm` is set, the package is expected to be a
124
+ * regular dependency in the plugin's own `package.json`, so `diffwiki plugin
125
+ * install` pulls it transitively and {@link ResolvedDependency} finds its bin in
126
+ * the plugin's `node_modules` — no global install required.
127
+ */
128
+ interface PluginDependency {
129
+ /** The executable name, e.g. `'qmd'` or `'rg'`. */
130
+ command: string;
131
+ /** npm package that provides the executable; when set, the local bin is preferred over PATH. */
132
+ npm?: string;
133
+ /** Human-facing manual install hint, shown when the dependency is unresolved. */
134
+ hint?: string;
135
+ }
136
+ /**
137
+ * The outcome of resolving a {@link PluginDependency}: the argv prefix to invoke
138
+ * it, plus where it was found. `command` is null when unresolved.
139
+ */
140
+ interface ResolvedDependency {
141
+ dependency: PluginDependency;
142
+ /** Argv prefix to spawn the tool, or null if unresolved. */
143
+ command: string[] | null;
144
+ /** How it resolved: the npm-provided local bin, the system PATH, or nowhere. */
145
+ source: 'npm' | 'path' | 'missing';
146
+ }
147
+ /** The handler functions a plugin provides. */
148
+ interface PluginHandlers {
149
+ /** Handle a search request. Required for search plugins. */
150
+ search: (params: SearchParams, log: PluginLogFn) => Promise<SearchHandlerResult> | SearchHandlerResult;
151
+ /** Handle a reindex request. Optional -- defaults to `{ indexed: 0 }`. */
152
+ index?: (params: IndexParams, log: PluginLogFn) => Promise<IndexHandlerResult> | IndexHandlerResult;
153
+ /** Handle an initial setup/provisioning request. Optional -- defaults to `{ ready: true }`. */
154
+ setup?: (params: SetupParams, log: PluginLogFn) => Promise<SetupHandlerResult> | SetupHandlerResult;
155
+ /** Handle a lifecycle event (article/collection add/update/remove). Optional. */
156
+ onEvent?: (params: EventParams, log: PluginLogFn) => Promise<EventHandlerResult> | EventHandlerResult;
157
+ /** Report plugin health and readiness. Optional. */
158
+ health?: (params: HealthParams, log: PluginLogFn) => Promise<HealthHandlerResult> | HealthHandlerResult;
159
+ }
160
+ /** The definition object passed to `definePlugin()`. */
161
+ interface PluginDefinition {
162
+ /** Plugin name (must match the name used in `diffwiki plugin register`). */
163
+ name: string;
164
+ /** Plugin kind. Currently only `'search'` is supported. */
165
+ kind: 'search';
166
+ /** Semantic version string. */
167
+ version?: string;
168
+ /** Plugin capabilities advertised to the host. */
169
+ capabilities: PluginCapabilities$1;
170
+ /** External executables the plugin needs. Reported via `describe` and resolvable via {@link ResolvedDependency}. */
171
+ dependencies?: PluginDependency[];
172
+ /** Handler functions for each operation. */
173
+ handlers: PluginHandlers;
174
+ }
175
+ /** The object returned by `definePlugin()`. Call `.run()` to serve one request. */
176
+ interface DefinedPlugin {
177
+ /** The plugin definition. */
178
+ definition: PluginDefinition;
179
+ /**
180
+ * Read one JSON request from stdin, dispatch to the matching handler, write
181
+ * the JSON response to stdout, and exit. Exit code 0 on success, 1 on
182
+ * handler error. Logs go to stderr.
183
+ */
184
+ run: () => void;
185
+ }
186
+ /** Options for `runProcess` and `runProcessJson`. */
187
+ interface RunProcessOptions {
188
+ /** Environment variables for the child process. Defaults to `process.env`. */
189
+ env?: NodeJS.ProcessEnv;
190
+ /** Timeout in milliseconds. No timeout by default. */
191
+ timeout?: number;
192
+ }
193
+
194
+ /** Audience axis — who an article is for. Private is never published; system is diffwiki-internal (hidden unless `showSystem`). Missing/invalid → 'public'. */
195
+ type Audience = 'public' | 'private' | 'system';
196
+ /** Lifecycle axis — readiness. Draft is unpublished; deprecated is superseded. Missing/invalid → 'published'. */
197
+ type PublishStatus = 'draft' | 'published' | 'deprecated';
198
+ type CollectionType = 'global' | 'repo' | 'external';
199
+ interface CollectionEntry {
200
+ name: string;
201
+ type: CollectionType;
202
+ /** Absolute path to the collection's content directory. */
203
+ path: string;
204
+ createdAt: string;
205
+ /** Marks a diffwiki-internal collection (e.g. `transcripts`). 'system' hides it unless `showSystem`. */
206
+ audience?: Audience;
207
+ /** External only: stable git repo id (see `repoId`). Identity + dedupe key. */
208
+ id?: string;
209
+ /** External only: absolute repo root (branch/behind + open-at-root). */
210
+ repoRoot?: string;
211
+ /** External only: content dir relative to `repoRoot` (default "docs"). */
212
+ docsDir?: string;
213
+ }
214
+ interface Registry {
215
+ version: number;
216
+ collections: CollectionEntry[];
217
+ }
218
+ interface Config {
219
+ defaultCollection?: string;
220
+ defaultSearch?: string;
221
+ /** Editor command used by `diffwiki edit` (e.g. "code -w", "hx"). Falls back to $VISUAL/$EDITOR. */
222
+ editor?: string;
223
+ /** Reveal system-audience content in search, nav, and the UI (default: false). Stored as boolean or "true". */
224
+ showSystem?: boolean;
225
+ }
226
+ interface Article {
227
+ title: string;
228
+ tags: string[];
229
+ /** Absolute path to the article file. */
230
+ path: string;
231
+ collection: string;
232
+ }
233
+ interface RepoConfig {
234
+ collection: string;
235
+ /** Path to the wiki directory, relative to the repo root. */
236
+ path: string;
237
+ }
238
+ /** A home-page card (VitePress-style): icon + title + subtitle linking into the site. */
239
+ interface HomeCard {
240
+ /** Icon name from the curated home-card icon set; unknown/missing → no icon. */
241
+ icon?: string;
242
+ title: string;
243
+ subtitle?: string;
244
+ /** In-site path, e.g. "/getting-started". */
245
+ link: string;
246
+ }
247
+ /** Home-page customization from `diffwiki.yaml` → `site.home`. */
248
+ interface SiteHome {
249
+ /** Line shown under the wordmark on the home page. */
250
+ tagline?: string;
251
+ /** Cards rendered below the search bar. */
252
+ cards?: HomeCard[];
253
+ }
254
+ /** Footer copyright notice from `diffwiki.yaml` → `site.copyright`. Applies to the
255
+ * site/software; article CONTENT copyright stays with its respective authors. */
256
+ interface SiteCopyright {
257
+ /** The full notice text, e.g. "© 2026 Acme, Inc." */
258
+ text: string;
259
+ /** Optional URL — renders the notice as a link. */
260
+ url?: string;
261
+ }
262
+ /** Site-level config from `diffwiki.yaml` → `site`. The diffwiki logo + wordmark
263
+ * are fixed branding and deliberately not configurable. */
264
+ interface SiteConfig {
265
+ /** Project repository URL for the top-nav GitHub link. */
266
+ repo?: string;
267
+ /** Footer copyright notice; no default — the footer is empty when unset. */
268
+ copyright?: SiteCopyright;
269
+ home?: SiteHome;
270
+ }
271
+ /** One collection declared in `diffwiki.yaml` → `collections[]`. */
272
+ interface ProjectCollection {
273
+ name: string;
274
+ /** Content directory, relative to the project root. */
275
+ path: string;
276
+ /** Optional display order (ascending). Unset sorts after ordered ones, keeping list order. */
277
+ order?: number;
278
+ }
279
+ /** Optional recall/search context from `diffwiki.yaml` → `context`. */
280
+ interface ProjectContext {
281
+ /** Collection names recall/search should filter to by default. */
282
+ collections: string[];
283
+ }
284
+ /**
285
+ * Normalised repo-root `diffwiki.yaml`. The extended form carries `site` +
286
+ * `collections[]`; the legacy `{ collection, path }` form is folded into a
287
+ * one-element `collections` by the parser.
288
+ */
289
+ interface ProjectConfig {
290
+ site?: SiteConfig;
291
+ collections: ProjectCollection[];
292
+ context?: ProjectContext;
293
+ }
294
+ /** A node in a collection's article tree. Branches have `children`; leaves have `slug`. */
295
+ interface ArticleNode {
296
+ /** Segment label — dir name for branches, filename-without-ext for leaves. */
297
+ name: string;
298
+ /** Display title — frontmatter `title` (leaf) or the folder's index title, else `name`. */
299
+ title?: string;
300
+ /**
301
+ * Path within the collection, without extension, e.g. "guide/setup". Set on
302
+ * leaves (the article) and on branches (the folder, navigable to its index).
303
+ */
304
+ slug?: string;
305
+ /** Audience, set only when 'private' (omitted for 'public'). */
306
+ audience?: Audience;
307
+ /** Lifecycle status, set only when 'draft' (omitted for 'published'). */
308
+ status?: PublishStatus;
309
+ /** Frontmatter `order` — nav sort within a folder (ascending; unset sorts after). */
310
+ order?: number;
311
+ /** Branch only: nested nodes. */
312
+ children?: ArticleNode[];
313
+ }
314
+ /** A resolved article's content, returned by `readArticle`. */
315
+ interface ArticleContent {
316
+ coll: string;
317
+ slug: string;
318
+ title: string;
319
+ tags: string[];
320
+ /** Audience from frontmatter ('public' when absent). */
321
+ audience: Audience;
322
+ /** Lifecycle status from frontmatter ('published' when absent). */
323
+ status: PublishStatus;
324
+ /** Frontmatter-stripped body (md/mdx). */
325
+ body: string;
326
+ /** Absolute path to the file on disk. */
327
+ path: string;
328
+ /**
329
+ * True when the resolved file is a folder-index page (`<slug>/index.md` or
330
+ * `<slug>/README.md`) rather than a leaf `<slug>.md`. The route slug is the
331
+ * same for both, so this flag is needed to resolve folder-local relative
332
+ * links against the article's own folder.
333
+ */
334
+ isIndex: boolean;
335
+ }
336
+ type PluginKind = 'search';
337
+ declare const NATIVE_ENGINE = "native";
338
+
339
+ interface QueryOptions {
340
+ engine?: string;
341
+ /** Limit to a single collection name, or a set of names. Empty/undefined = all. */
342
+ collection?: string | string[];
343
+ type?: string;
344
+ limit?: number;
345
+ /** Reveal system-audience content (default: config `showSystem`, else false). */
346
+ showSystem?: boolean;
347
+ /**
348
+ * Pre-expanded query variants (from a smarter upstream LLM). When present, an
349
+ * engine that supports structured search should use these instead of expanding
350
+ * the bare term itself. The `term` is still passed as ranking intent.
351
+ */
352
+ expansions?: SearchExpansion[];
353
+ }
354
+ interface QueryHit {
355
+ collection: string;
356
+ path: string;
357
+ title: string;
358
+ tags: string[];
359
+ snippet?: string;
360
+ score?: number;
361
+ docid?: string;
362
+ /** Verbatim engine chunk (unsanitized) for the search UI's inspection popover. */
363
+ rawChunk?: string;
364
+ /** The chunk cleaned to plain text, untruncated (full form for the popover). */
365
+ cleanedChunk?: string;
366
+ /** Absolute source line the chunk starts at, when the engine reports it. */
367
+ line?: number;
368
+ /** True when `snippet` is a body-preview fallback rather than the cleaned chunk. */
369
+ snippetFromBody?: boolean;
370
+ }
371
+ type DiagnosticLevel = 'ok' | 'warn' | 'error';
372
+ interface Diagnostic {
373
+ level: DiagnosticLevel;
374
+ message: string;
375
+ }
376
+ interface PluginRecord {
377
+ name: string;
378
+ kind: PluginKind;
379
+ command: string[];
380
+ version?: string;
381
+ /** Capabilities cached at install/register time via the `describe` op. */
382
+ capabilities?: PluginCapabilities;
383
+ enabled: boolean;
384
+ managed?: boolean;
385
+ }
386
+ interface PluginRegistryFile {
387
+ version: number;
388
+ plugins: PluginRecord[];
389
+ }
390
+ /** Capabilities a plugin advertises via the `describe` op, cached in the registry. */
391
+ interface PluginCapabilities {
392
+ /** Search types the plugin supports (e.g. `['keyword', 'semantic', 'hybrid']`). */
393
+ searchTypes: string[];
394
+ /** Whether the plugin supports filtering results by collection. */
395
+ collectionFilter: boolean;
396
+ /** Whether the plugin handles lifecycle events (article/collection mutations). */
397
+ events: boolean;
398
+ }
399
+ interface PluginReadiness {
400
+ toolInstalled: boolean;
401
+ modelsPresent: boolean;
402
+ indexBuilt: boolean;
403
+ docsIndexed: number;
404
+ embeddingsPending: number;
405
+ firstSearchCost: 'instant' | 'model-load' | 'model-download';
406
+ }
407
+ interface PluginHealth {
408
+ ready: boolean;
409
+ readiness?: PluginReadiness;
410
+ diagnostics: Diagnostic[];
411
+ }
412
+ interface SearchMode {
413
+ plugin: string;
414
+ type: string;
415
+ label: string;
416
+ }
417
+ type PluginEvent = 'collection-added' | 'collection-removed' | 'article-created' | 'article-updated' | 'article-removed';
418
+ /**
419
+ * Host-side facade for a search plugin. Each method is backed by a one-shot
420
+ * subprocess invocation -- there is no persistent process and no `close()`.
421
+ */
422
+ interface SearchProvider {
423
+ /** Plugin name. */
424
+ name: string;
425
+ /** Plugin capabilities (cached from the `describe` op). */
426
+ capabilities: PluginCapabilities;
427
+ /** Run a search query and return hits with absolute paths. */
428
+ handleSearch(term: string, collections: CollectionEntry[], opts?: QueryOptions): Promise<QueryHit[]>;
429
+ /** Rebuild the search index. Returns the number of documents indexed. */
430
+ reindex(collections: CollectionEntry[], opts?: {
431
+ embed?: boolean;
432
+ }): Promise<number>;
433
+ /** Emit a lifecycle event to the plugin (best-effort). */
434
+ emitEvent(event: PluginEvent, collection: string, relPath: string | undefined, collections: CollectionEntry[]): Promise<void>;
435
+ /** Check plugin health and readiness. */
436
+ health(collections: CollectionEntry[]): Promise<PluginHealth>;
437
+ }
438
+ interface NodeMeta {
439
+ branch?: string;
440
+ behind?: number;
441
+ }
442
+ interface TreeNode {
443
+ name: string;
444
+ title?: string;
445
+ path?: string;
446
+ /** Audience; present only when 'private' (drives the sidebar lock). */
447
+ audience?: Audience;
448
+ /** Lifecycle status; present only when 'draft' (drives the sidebar DRAFT tag). */
449
+ status?: PublishStatus;
450
+ children?: TreeNode[];
451
+ /** Set only on top-level collection rows: git branch/behind badge data. */
452
+ meta?: NodeMeta;
453
+ }
454
+ interface CollectionInfo {
455
+ name: string;
456
+ type: CollectionType;
457
+ path: string;
458
+ /** Display title from the collection's root index page frontmatter; falls back to `name` in the UI. */
459
+ title?: string;
460
+ branch?: string;
461
+ behind?: number;
462
+ /** Audience from the collection's root index page; present only when 'private'. */
463
+ audience?: Audience;
464
+ /** Lifecycle status from the collection's root index page; present only when 'draft'. */
465
+ status?: PublishStatus;
466
+ }
467
+ interface CollectionTree {
468
+ collection: CollectionInfo;
469
+ nodes: TreeNode[];
470
+ }
471
+ interface TocItem {
472
+ slug: string;
473
+ text: string;
474
+ depth: number;
475
+ }
476
+ interface DocData {
477
+ coll: string;
478
+ slug: string;
479
+ title: string;
480
+ tags: string[];
481
+ /** Audience; present only when 'private'. */
482
+ audience?: Audience;
483
+ /** Lifecycle status; present only when 'draft'. */
484
+ status?: PublishStatus;
485
+ html: string;
486
+ toc: TocItem[];
487
+ path: string;
488
+ /** ISO-8601 creation date, sourced from git history / filesystem (not frontmatter). */
489
+ created?: string;
490
+ /** ISO-8601 last-update date, sourced from git history / filesystem (not frontmatter). */
491
+ updated?: string;
492
+ /** Local knowledge-graph neighbourhood for this page (this node + its direct links). */
493
+ graph: LocalGraph;
494
+ }
495
+ interface ListingEntry {
496
+ name: string;
497
+ title: string;
498
+ path: string;
499
+ isDir: boolean;
500
+ }
501
+ type PageData = ({
502
+ kind: 'doc';
503
+ } & DocData) | {
504
+ kind: 'listing';
505
+ coll: string;
506
+ slug: string;
507
+ title: string;
508
+ entries: ListingEntry[];
509
+ };
510
+ /**
511
+ * One node in the knowledge graph. Two kinds:
512
+ * - `article` — a wiki page. `id` is `"<coll>/<slug>"`, with `coll`/`slug` set.
513
+ * - `tag` — an Obsidian-style tag hub. `id` is `"tag:<name>"`; `coll`/`slug` are
514
+ * empty (a tag is not a page, so clicking it never navigates), `title` is `#name`.
515
+ */
516
+ interface GraphNode {
517
+ id: string;
518
+ kind: 'article' | 'tag';
519
+ coll: string;
520
+ slug: string;
521
+ title: string;
522
+ }
523
+ /**
524
+ * A graph edge. `kind` distinguishes an explicit hyperlink between two articles
525
+ * (`link`) from an article↔tag-hub membership edge (`tag`). For `link` edges the
526
+ * direction (source→target) is the link direction; `tag` edges go article→tag.
527
+ */
528
+ interface GraphEdge {
529
+ source: string;
530
+ target: string;
531
+ kind: 'link' | 'tag';
532
+ }
533
+ /** The whole-wiki knowledge graph. */
534
+ interface LinkGraph {
535
+ nodes: GraphNode[];
536
+ edges: GraphEdge[];
537
+ }
538
+ /**
539
+ * The local neighbourhood of one node: the node itself plus its directly linked
540
+ * (outgoing) and linking (incoming) neighbours, and the edges among them. `focus`
541
+ * is the id of the page this neighbourhood is centred on.
542
+ */
543
+ interface LocalGraph {
544
+ focus: string;
545
+ nodes: GraphNode[];
546
+ edges: GraphEdge[];
547
+ }
548
+
549
+ interface ParsedArticle {
550
+ title: string;
551
+ tags: string[];
552
+ created?: string;
553
+ audience: Audience;
554
+ status: PublishStatus;
555
+ body: string;
556
+ }
557
+ interface SerializableArticle {
558
+ title: string;
559
+ tags: string[];
560
+ audience?: Audience;
561
+ status?: PublishStatus;
562
+ body: string;
563
+ }
564
+ /**
565
+ * Remove a leading frontmatter block, returning the body **verbatim** — unlike
566
+ * {@link parseArticle}, no leading-whitespace trimming — so a caller that needs
567
+ * the body's original line offsets (e.g. a search index that blanks frontmatter
568
+ * to keep source line numbers aligned) can reconstruct them from the removed
569
+ * span. Returns the input unchanged when there is no frontmatter.
570
+ */
571
+ declare function stripFrontmatter(raw: string): string;
572
+ /**
573
+ * Parse a document's YAML frontmatter into a raw key/value object (every key,
574
+ * not just the article axes), plus the body. Bundler-safe via the pinned `yaml`
575
+ * engine. Use this for metadata files (e.g. template frontmatter carrying
576
+ * `shape`/`purpose`) where {@link parseArticle}'s fixed fields don't fit.
577
+ */
578
+ declare function parseFrontmatter(raw: string): {
579
+ data: Record<string, unknown>;
580
+ body: string;
581
+ };
582
+ declare function parseArticle(raw: string): ParsedArticle;
583
+ declare function serializeArticle(article: SerializableArticle): string;
584
+
585
+ export { type ResolvedDependency as $, type Audience as A, type PluginHealth as B, type Config as C, type Diagnostic as D, type PluginReadiness as E, type ProjectCollection as F, type GraphEdge as G, type HomeCard as H, type ProjectContext as I, type SearchExpansion as J, type SerializableArticle as K, type LinkGraph as L, type SiteCopyright as M, NATIVE_ENGINE as N, type SiteHome as O, type PublishStatus as P, type QueryHit as Q, type Registry as R, type SiteConfig as S, type TreeNode as T, parseArticle as U, parseFrontmatter as V, serializeArticle as W, stripFrontmatter as X, type PluginDefinition as Y, type DefinedPlugin as Z, type PluginDependency as _, type CollectionEntry as a, type RunProcessOptions as a0, type EventHandlerResult as a1, type EventParams as a2, type HealthHandlerResult as a3, type HealthParams as a4, type IndexHandlerResult as a5, type IndexParams as a6, type LogLevel as a7, type PluginCapabilities$1 as a8, type PluginHandlers as a9, type PluginLogFn as aa, type SearchHandlerHit as ab, type SearchHandlerResult as ac, type SearchParams as ad, type SetupHandlerResult as ae, type SetupParams as af, type WireCollection as ag, type WireDiagnostic as ah, type WireReadiness as ai, type Article as b, type RepoConfig as c, type ProjectConfig as d, type CollectionInfo as e, type CollectionTree as f, type PageData as g, type ArticleNode as h, type QueryOptions as i, type ParsedArticle as j, type ArticleContent as k, type TocItem as l, type LocalGraph as m, type SearchMode as n, type SearchProvider as o, type PluginRecord as p, type PluginEvent as q, type PluginKind as r, type PluginRegistryFile as s, type CollectionType as t, type DiagnosticLevel as u, type DocData as v, type GraphNode as w, type ListingEntry as x, type NodeMeta as y, type PluginCapabilities as z };