folderblog 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +109 -48
  2. package/dist/chunk-24MKFHML.cjs +143 -0
  3. package/dist/chunk-3RG5ZIWI.js +8 -0
  4. package/dist/chunk-4ZJGUMHS.cjs +78 -0
  5. package/dist/chunk-HMQIQUPB.cjs +387 -0
  6. package/dist/chunk-IXP35S24.js +1715 -0
  7. package/dist/chunk-OBGZSXTJ.cjs +10 -0
  8. package/dist/chunk-PARGDJNY.js +76 -0
  9. package/dist/chunk-QA4KPPTA.cjs +1787 -0
  10. package/dist/chunk-XP5J4LFJ.js +127 -0
  11. package/dist/chunk-ZRUBI3GH.js +370 -0
  12. package/dist/cli/bin.cjs +25 -0
  13. package/dist/cli/bin.d.cts +1 -0
  14. package/dist/cli/bin.d.ts +1 -0
  15. package/dist/cli/bin.js +23 -0
  16. package/dist/cli/index.cjs +22 -0
  17. package/dist/cli/index.d.cts +39 -0
  18. package/dist/cli/index.d.ts +39 -0
  19. package/dist/cli/index.js +15 -0
  20. package/dist/config-DFr-htlO.d.cts +887 -0
  21. package/dist/config-DFr-htlO.d.ts +887 -0
  22. package/dist/index.cjs +488 -1
  23. package/dist/index.d.cts +76 -8
  24. package/dist/index.d.ts +76 -8
  25. package/dist/index.js +153 -1
  26. package/dist/processor/index.cjs +337 -0
  27. package/dist/processor/index.d.cts +491 -0
  28. package/dist/processor/index.d.ts +491 -0
  29. package/dist/processor/index.js +4 -0
  30. package/dist/processor/plugins.cjs +51 -0
  31. package/dist/processor/plugins.d.cts +174 -0
  32. package/dist/processor/plugins.d.ts +174 -0
  33. package/dist/processor/plugins.js +2 -0
  34. package/dist/processor/types.cjs +67 -0
  35. package/dist/processor/types.d.cts +47 -0
  36. package/dist/processor/types.d.ts +47 -0
  37. package/dist/processor/types.js +2 -0
  38. package/dist/server/index.cjs +36 -0
  39. package/dist/server/index.d.cts +56 -0
  40. package/dist/server/index.d.ts +56 -0
  41. package/dist/server/index.js +34 -0
  42. package/package.json +63 -11
@@ -0,0 +1,887 @@
1
+ /**
2
+ * Issue tracking types for @repo-md/processor-core
3
+ */
4
+ type IssueSeverity = 'error' | 'warning' | 'info';
5
+ type IssueCategory = 'broken-link' | 'missing-media' | 'media-processing' | 'slug-conflict' | 'mermaid-error' | 'frontmatter-error' | 'parse-error' | 'file-access' | 'embedding-error' | 'database-error' | 'plugin-error' | 'configuration' | 'other';
6
+ type IssueModule = 'markdown-parser' | 'image-processor' | 'embed-mermaid' | 'embed-media' | 'link-resolver' | 'slug-generator' | 'frontmatter-parser' | 'file-system' | 'config-validator' | 'post-processor' | 'text-embeddings' | 'image-embeddings' | 'similarity' | 'database' | 'plugin-manager' | 'other';
7
+ /**
8
+ * Base interface for all processing issues
9
+ */
10
+ interface ProcessingIssue {
11
+ readonly severity: IssueSeverity;
12
+ readonly category: IssueCategory;
13
+ readonly module: IssueModule;
14
+ readonly message: string;
15
+ readonly filePath?: string;
16
+ readonly lineNumber?: number;
17
+ readonly columnNumber?: number;
18
+ readonly context?: Readonly<Record<string, unknown>>;
19
+ readonly timestamp: string;
20
+ }
21
+ /**
22
+ * Broken link issue
23
+ */
24
+ interface BrokenLinkIssue extends ProcessingIssue {
25
+ readonly category: 'broken-link';
26
+ readonly module: 'link-resolver';
27
+ readonly context: {
28
+ readonly linkText: string;
29
+ readonly linkTarget: string;
30
+ readonly linkType: 'wiki' | 'markdown' | 'frontmatter';
31
+ readonly suggestions?: readonly string[];
32
+ };
33
+ }
34
+ /**
35
+ * Missing media issue
36
+ */
37
+ interface MissingMediaIssue extends ProcessingIssue {
38
+ readonly category: 'missing-media';
39
+ readonly module: 'embed-media' | 'image-processor';
40
+ readonly context: {
41
+ readonly mediaPath: string;
42
+ readonly referencedFrom: 'content' | 'frontmatter' | 'embed';
43
+ readonly originalReference?: string;
44
+ };
45
+ }
46
+ /**
47
+ * Media processing issue
48
+ */
49
+ interface MediaProcessingIssue extends ProcessingIssue {
50
+ readonly category: 'media-processing';
51
+ readonly module: 'image-processor';
52
+ readonly context: {
53
+ readonly mediaPath: string;
54
+ readonly operation: 'read' | 'optimize' | 'resize' | 'hash' | 'copy';
55
+ readonly errorMessage: string;
56
+ readonly errorCode?: string;
57
+ };
58
+ }
59
+ /**
60
+ * Slug conflict issue
61
+ */
62
+ interface SlugConflictIssue extends ProcessingIssue {
63
+ readonly category: 'slug-conflict';
64
+ readonly module: 'slug-generator';
65
+ readonly context: {
66
+ readonly originalSlug: string;
67
+ readonly finalSlug: string;
68
+ readonly conflictingFiles: readonly string[];
69
+ };
70
+ }
71
+ /**
72
+ * Mermaid error issue
73
+ */
74
+ interface MermaidErrorIssue extends ProcessingIssue {
75
+ readonly category: 'mermaid-error';
76
+ readonly module: 'embed-mermaid';
77
+ readonly context: {
78
+ readonly errorType: 'plugin-load' | 'render-fail' | 'missing-deps';
79
+ readonly diagramContent?: string;
80
+ readonly fallback: string;
81
+ };
82
+ }
83
+ /**
84
+ * Embedding error issue
85
+ */
86
+ interface EmbeddingErrorIssue extends ProcessingIssue {
87
+ readonly category: 'embedding-error';
88
+ readonly module: 'text-embeddings' | 'image-embeddings';
89
+ readonly context: {
90
+ readonly embeddingType: 'text' | 'image';
91
+ readonly operation: 'initialize' | 'embed' | 'batch';
92
+ readonly errorMessage: string;
93
+ };
94
+ }
95
+ /**
96
+ * Plugin error issue
97
+ */
98
+ interface PluginErrorIssue extends ProcessingIssue {
99
+ readonly category: 'plugin-error';
100
+ readonly module: 'plugin-manager';
101
+ readonly context: {
102
+ readonly pluginName: string;
103
+ readonly operation: 'initialize' | 'process' | 'dispose';
104
+ readonly errorMessage: string;
105
+ };
106
+ }
107
+ declare const isBrokenLinkIssue: (issue: ProcessingIssue) => issue is BrokenLinkIssue;
108
+ declare const isMissingMediaIssue: (issue: ProcessingIssue) => issue is MissingMediaIssue;
109
+ declare const isMediaProcessingIssue: (issue: ProcessingIssue) => issue is MediaProcessingIssue;
110
+ declare const isSlugConflictIssue: (issue: ProcessingIssue) => issue is SlugConflictIssue;
111
+ declare const isMermaidErrorIssue: (issue: ProcessingIssue) => issue is MermaidErrorIssue;
112
+ declare const isEmbeddingErrorIssue: (issue: ProcessingIssue) => issue is EmbeddingErrorIssue;
113
+ declare const isPluginErrorIssue: (issue: ProcessingIssue) => issue is PluginErrorIssue;
114
+ interface IssueSummary {
115
+ readonly totalIssues: number;
116
+ readonly errorCount: number;
117
+ readonly warningCount: number;
118
+ readonly infoCount: number;
119
+ readonly filesAffected: number;
120
+ readonly categoryCounts: Readonly<Record<IssueCategory, number>>;
121
+ readonly moduleCounts: Readonly<Record<IssueModule, number>>;
122
+ }
123
+ interface IssueReport {
124
+ readonly issues: readonly ProcessingIssue[];
125
+ readonly summary: IssueSummary;
126
+ readonly metadata: {
127
+ readonly processStartTime: string;
128
+ readonly processEndTime: string;
129
+ readonly processorVersion?: string;
130
+ };
131
+ }
132
+ interface IssueFilterOptions {
133
+ readonly severity?: IssueSeverity | readonly IssueSeverity[];
134
+ readonly category?: IssueCategory | readonly IssueCategory[];
135
+ readonly module?: IssueModule | readonly IssueModule[];
136
+ readonly filePath?: string | readonly string[];
137
+ }
138
+
139
+ /**
140
+ * Issue Collector Service
141
+ *
142
+ * Functional service for collecting and managing processing issues.
143
+ * Uses immutable patterns - returns new state rather than mutating.
144
+ */
145
+
146
+ interface IssueCollectorState {
147
+ readonly issues: readonly ProcessingIssue[];
148
+ readonly startTime: string;
149
+ }
150
+ /**
151
+ * Service for collecting and managing processing issues.
152
+ * Provides both mutable (class-based) and functional interfaces.
153
+ */
154
+ declare class IssueCollector {
155
+ private issues;
156
+ private readonly startTime;
157
+ constructor();
158
+ /**
159
+ * Add a generic issue
160
+ */
161
+ addIssue(issue: Omit<ProcessingIssue, 'timestamp'>): void;
162
+ /**
163
+ * Add a broken link issue
164
+ */
165
+ addBrokenLink(params: {
166
+ filePath: string;
167
+ lineNumber?: number;
168
+ linkText: string;
169
+ linkTarget: string;
170
+ linkType: 'wiki' | 'markdown' | 'frontmatter';
171
+ suggestions?: readonly string[];
172
+ }): void;
173
+ /**
174
+ * Add a missing media issue
175
+ */
176
+ addMissingMedia(params: {
177
+ filePath: string;
178
+ lineNumber?: number;
179
+ mediaPath: string;
180
+ referencedFrom: 'content' | 'frontmatter' | 'embed';
181
+ originalReference?: string;
182
+ module?: 'embed-media' | 'image-processor';
183
+ }): void;
184
+ /**
185
+ * Add a media processing error
186
+ */
187
+ addMediaProcessingError(params: {
188
+ filePath: string;
189
+ mediaPath: string;
190
+ operation: 'read' | 'optimize' | 'resize' | 'hash' | 'copy';
191
+ errorMessage: string;
192
+ errorCode?: string;
193
+ }): void;
194
+ /**
195
+ * Add a slug conflict warning
196
+ */
197
+ addSlugConflict(params: {
198
+ filePath: string;
199
+ originalSlug: string;
200
+ finalSlug: string;
201
+ conflictingFiles: readonly string[];
202
+ }): void;
203
+ /**
204
+ * Add a mermaid error
205
+ */
206
+ addMermaidError(params: {
207
+ filePath: string;
208
+ lineNumber?: number;
209
+ errorType: 'plugin-load' | 'render-fail' | 'missing-deps';
210
+ message: string;
211
+ diagramContent?: string;
212
+ fallback: string;
213
+ }): void;
214
+ /**
215
+ * Add an embedding error
216
+ */
217
+ addEmbeddingError(params: {
218
+ filePath?: string;
219
+ embeddingType: 'text' | 'image';
220
+ operation: 'initialize' | 'embed' | 'batch';
221
+ errorMessage: string;
222
+ }): void;
223
+ /**
224
+ * Add a plugin error
225
+ */
226
+ addPluginError(params: {
227
+ pluginName: string;
228
+ operation: 'initialize' | 'process' | 'dispose';
229
+ errorMessage: string;
230
+ }): void;
231
+ /**
232
+ * Get all issues
233
+ */
234
+ getIssues(): readonly ProcessingIssue[];
235
+ /**
236
+ * Filter issues
237
+ */
238
+ filterIssues(options: IssueFilterOptions): readonly ProcessingIssue[];
239
+ /**
240
+ * Get issue count by severity
241
+ */
242
+ getCountBySeverity(severity: IssueSeverity): number;
243
+ /**
244
+ * Check if there are any errors
245
+ */
246
+ hasErrors(): boolean;
247
+ /**
248
+ * Get summary string for console output
249
+ */
250
+ getSummaryString(): string;
251
+ /**
252
+ * Generate the final report
253
+ */
254
+ generateReport(): IssueReport;
255
+ /**
256
+ * Clear all issues (for testing)
257
+ */
258
+ clear(): void;
259
+ }
260
+ /**
261
+ * Filter issues based on criteria
262
+ */
263
+ declare const filterIssues: (issues: readonly ProcessingIssue[], options: IssueFilterOptions) => readonly ProcessingIssue[];
264
+ /**
265
+ * Calculate issue summary
266
+ */
267
+ declare const calculateSummary: (issues: readonly ProcessingIssue[]) => IssueSummary;
268
+ /**
269
+ * Generate issue report
270
+ */
271
+ declare const generateIssueReport: (issues: readonly ProcessingIssue[], startTime: string, endTime: string) => IssueReport;
272
+
273
+ /**
274
+ * Cache types for @repo-md/processor-core
275
+ *
276
+ * These types support incremental builds by allowing the processor
277
+ * to skip re-processing files that haven't changed.
278
+ */
279
+
280
+ /**
281
+ * Cached metadata for a previously processed media file.
282
+ * Contains all information needed to skip image processing
283
+ * while still generating correct HTML output with dimensions.
284
+ */
285
+ interface CachedMediaMetadata {
286
+ /** Original image width */
287
+ readonly width: number;
288
+ /** Original image height */
289
+ readonly height: number;
290
+ /** Output format (webp, avif, jpeg, png) */
291
+ readonly format: string;
292
+ /** Output file size in bytes */
293
+ readonly size: number;
294
+ /** Original file size in bytes */
295
+ readonly originalSize?: number;
296
+ /** Output file path relative to media output dir */
297
+ readonly outputPath: string;
298
+ /** Responsive size variants */
299
+ readonly sizes: readonly CachedMediaSizeVariant[];
300
+ }
301
+ /**
302
+ * Cached size variant for responsive images
303
+ */
304
+ interface CachedMediaSizeVariant {
305
+ /** Size suffix (xs, sm, md, lg, xl) */
306
+ readonly suffix: string;
307
+ /** Output file path relative to media output dir */
308
+ readonly outputPath: string;
309
+ /** Width of this variant */
310
+ readonly width: number;
311
+ /** Height of this variant */
312
+ readonly height: number;
313
+ /** File size in bytes */
314
+ readonly size: number;
315
+ }
316
+ /**
317
+ * Cache context passed to the processor for incremental builds.
318
+ * All caches are keyed by content hash (SHA-256).
319
+ */
320
+ interface CacheContext {
321
+ /**
322
+ * Cached media metadata keyed by content hash.
323
+ * When a media file's hash matches a cached entry, processing can be skipped
324
+ * and the cached metadata used for HTML rendering (dimensions, paths).
325
+ */
326
+ readonly media?: ReadonlyMap<string, CachedMediaMetadata>;
327
+ /**
328
+ * Cached text embeddings keyed by post content hash.
329
+ * When a post's hash matches a cached entry, embedding generation
330
+ * can be skipped and the cached vector used directly.
331
+ */
332
+ readonly textEmbeddings?: ReadonlyMap<string, readonly number[]>;
333
+ /**
334
+ * Cached image embeddings keyed by media content hash.
335
+ * When a media file's hash matches a cached entry, CLIP embedding
336
+ * generation can be skipped and the cached vector used directly.
337
+ */
338
+ readonly imageEmbeddings?: ReadonlyMap<string, readonly number[]>;
339
+ }
340
+ /**
341
+ * Statistics about cache usage during processing
342
+ */
343
+ interface CacheStats {
344
+ /** Number of media files that used cached metadata */
345
+ readonly mediaCacheHits: number;
346
+ /** Number of media files that were processed fresh */
347
+ readonly mediaCacheMisses: number;
348
+ /** Number of posts that used cached text embeddings */
349
+ readonly textEmbeddingCacheHits: number;
350
+ /** Number of posts that required fresh text embedding generation */
351
+ readonly textEmbeddingCacheMisses: number;
352
+ /** Number of media files that used cached image embeddings */
353
+ readonly imageEmbeddingCacheHits: number;
354
+ /** Number of media files that required fresh image embedding generation */
355
+ readonly imageEmbeddingCacheMisses: number;
356
+ }
357
+ /**
358
+ * Create empty cache statistics
359
+ */
360
+ declare const createEmptyCacheStats: () => CacheStats;
361
+ /**
362
+ * Build a media cache from a medias.json file structure
363
+ */
364
+ declare function buildMediaCacheFromManifest(medias: readonly {
365
+ metadata?: MediaMetadata;
366
+ outputPath: string;
367
+ sizes?: readonly MediaSizeVariant[];
368
+ }[]): Map<string, CachedMediaMetadata>;
369
+ /**
370
+ * Build an embedding cache from an embedding hash map file structure
371
+ */
372
+ declare function buildEmbeddingCacheFromManifest(embeddingMap: Record<string, readonly number[]>): Map<string, readonly number[]>;
373
+
374
+ /**
375
+ * Output types for @repo-md/processor-core
376
+ */
377
+
378
+ interface TocItem {
379
+ readonly text: string;
380
+ readonly depth: number;
381
+ readonly slug: string;
382
+ }
383
+ interface PostMetadata {
384
+ readonly createdAt: string;
385
+ readonly modifiedAt: string;
386
+ readonly processedAt: string;
387
+ readonly gitCreatedAt?: string;
388
+ readonly gitModifiedAt?: string;
389
+ }
390
+ interface PostCoverSize {
391
+ /** Size suffix (xs, sm, md, lg, xl) */
392
+ readonly suffix: string;
393
+ /** Output file path relative to output dir */
394
+ readonly path: string;
395
+ /** Full URL if domain configured */
396
+ readonly url?: string;
397
+ /** Width of this variant */
398
+ readonly width: number;
399
+ /** Height of this variant */
400
+ readonly height: number;
401
+ }
402
+ interface PostCover {
403
+ /** Original path from frontmatter */
404
+ readonly original: string;
405
+ /** Output file path relative to output dir */
406
+ readonly path: string;
407
+ /** Full URL if domain configured */
408
+ readonly url?: string;
409
+ /** Content hash */
410
+ readonly hash?: string;
411
+ /** Image width */
412
+ readonly width?: number;
413
+ /** Image height */
414
+ readonly height?: number;
415
+ /** Responsive image size variants */
416
+ readonly sizes?: readonly PostCoverSize[];
417
+ }
418
+ interface PostCoverError {
419
+ /** Original path from frontmatter */
420
+ readonly original: string;
421
+ /** Error message explaining why cover couldn't be resolved */
422
+ readonly error: string;
423
+ }
424
+ interface ProcessedPost {
425
+ /** Content hash for identification */
426
+ readonly hash: string;
427
+ /** URL-friendly slug */
428
+ readonly slug: string;
429
+ /** Post title (from frontmatter or filename) */
430
+ readonly title: string;
431
+ /** Original filename without extension */
432
+ readonly fileName: string;
433
+ /** Original file path relative to input directory */
434
+ readonly originalPath: string;
435
+ /** Rendered HTML content */
436
+ readonly content: string;
437
+ /** Original markdown content */
438
+ readonly markdown: string;
439
+ /** Plain text content (for search/embeddings) */
440
+ readonly plainText: string;
441
+ /** Excerpt/summary text */
442
+ readonly excerpt: string;
443
+ /** Word count */
444
+ readonly wordCount: number;
445
+ /** Table of contents */
446
+ readonly toc: readonly TocItem[];
447
+ /** Frontmatter data */
448
+ readonly frontmatter: Readonly<Record<string, unknown>>;
449
+ /** Timestamps and metadata */
450
+ readonly metadata: PostMetadata;
451
+ /** Cover image (resolved from frontmatter.cover) */
452
+ readonly cover?: PostCover | PostCoverError;
453
+ /** URL of first image (for cover) */
454
+ readonly firstImage?: string;
455
+ /** Hashes of posts this post links to */
456
+ readonly links?: readonly string[];
457
+ /** Text embedding vector */
458
+ readonly embedding?: readonly number[];
459
+ }
460
+ interface MediaMetadata {
461
+ readonly width?: number;
462
+ readonly height?: number;
463
+ readonly format?: string;
464
+ readonly size?: number;
465
+ readonly originalSize?: number;
466
+ readonly hash?: string;
467
+ }
468
+ interface MediaSizeVariant {
469
+ /** Size suffix (xs, sm, md, lg, xl) */
470
+ readonly suffix: string;
471
+ /** Output file path relative to output dir */
472
+ readonly outputPath: string;
473
+ /** Width of this variant */
474
+ readonly width: number;
475
+ /** Height of this variant */
476
+ readonly height: number;
477
+ /** File size in bytes */
478
+ readonly size: number;
479
+ }
480
+ interface ProcessedMedia {
481
+ /** Original file path relative to input */
482
+ readonly originalPath: string;
483
+ /** Output file path relative to output dir */
484
+ readonly outputPath: string;
485
+ /** Original filename */
486
+ readonly fileName: string;
487
+ /** Media type */
488
+ readonly type: 'image' | 'video' | 'audio' | 'media';
489
+ /** File metadata */
490
+ readonly metadata?: MediaMetadata;
491
+ /** Responsive image size variants */
492
+ readonly sizes?: readonly MediaSizeVariant[];
493
+ /** Image embedding vector */
494
+ readonly embedding?: readonly number[];
495
+ }
496
+ type RelationshipType = 'POST_LINKS_TO_POST' | 'POST_USE_IMAGE';
497
+ interface GraphNode {
498
+ readonly id: string;
499
+ readonly type: 'post' | 'media';
500
+ readonly label: string;
501
+ }
502
+ interface GraphEdge {
503
+ readonly source: string;
504
+ readonly target: string;
505
+ readonly type: RelationshipType;
506
+ }
507
+ interface GraphData {
508
+ readonly nodes: readonly GraphNode[];
509
+ readonly edges: readonly GraphEdge[];
510
+ }
511
+ /** Maps original paths to optimized public paths */
512
+ type MediaPathMap = Readonly<Record<string, string>>;
513
+ /** Maps original paths to content hashes */
514
+ type PathHashMap = Readonly<Record<string, string>>;
515
+ /** Maps slugs to post hashes */
516
+ type SlugHashMap = Readonly<Record<string, string>>;
517
+ /** Maps hashes to embedding vectors */
518
+ type EmbeddingMap = ReadonlyMap<string, readonly number[]>;
519
+ interface OutputFiles {
520
+ readonly posts: string;
521
+ readonly media: string;
522
+ readonly slugMap: string;
523
+ readonly pathMap: string;
524
+ readonly issues: string;
525
+ readonly graph?: string;
526
+ readonly similarity?: string;
527
+ readonly database?: string;
528
+ }
529
+ interface ProcessResult {
530
+ /** Processed posts */
531
+ readonly posts: readonly ProcessedPost[];
532
+ /** Processed media files */
533
+ readonly media: readonly ProcessedMedia[];
534
+ /** Output directory path */
535
+ readonly outputDir: string;
536
+ /** Output file paths */
537
+ readonly outputFiles: OutputFiles;
538
+ /** Processing issues report */
539
+ readonly issues: IssueReport;
540
+ /** Graph data (if trackRelationships enabled) */
541
+ readonly graph?: GraphData;
542
+ /** Cache statistics (if cache was provided) */
543
+ readonly cacheStats?: CacheStats;
544
+ }
545
+ declare const OUTPUT_FILES: {
546
+ readonly POSTS: "posts.json";
547
+ readonly POSTS_SLUG_MAP: "posts-slug-map.json";
548
+ readonly POSTS_PATH_MAP: "posts-path-map.json";
549
+ readonly MEDIAS: "media.json";
550
+ readonly MEDIA_PATH_MAP: "media-path-map.json";
551
+ readonly GRAPH: "graph.json";
552
+ readonly TEXT_EMBEDDINGS: "posts-embedding-hash-map.json";
553
+ readonly IMAGE_EMBEDDINGS: "media-embedding-hash-map.json";
554
+ readonly SIMILARITY: "similarity.json";
555
+ readonly DATABASE: "repo.db";
556
+ readonly ISSUES: "processor-issues.json";
557
+ };
558
+
559
+ /**
560
+ * Plugin system types for @repo-md/processor-core
561
+ *
562
+ * Plugins extend the processor with optional functionality like:
563
+ * - Image optimization (Sharp, Jimp, etc.)
564
+ * - Text embeddings (HuggingFace, OpenAI, Cloudflare)
565
+ * - Image embeddings (CLIP)
566
+ * - Database generation (SQLite)
567
+ * - Diagram rendering (Mermaid)
568
+ */
569
+
570
+ /**
571
+ * Context provided to plugins during initialization
572
+ */
573
+ interface PluginContext {
574
+ /** Output directory for generated files */
575
+ readonly outputDir: string;
576
+ /** Issue collector for reporting problems */
577
+ readonly issues: IssueCollector;
578
+ /** Logger function */
579
+ readonly log: (message: string, level?: LogLevel) => void;
580
+ /** Access to other initialized plugins */
581
+ readonly getPlugin: <T extends Plugin>(name: string) => T | undefined;
582
+ /** Current processor configuration */
583
+ readonly config: ProcessConfig;
584
+ }
585
+ type LogLevel = 'debug' | 'info' | 'warn' | 'error';
586
+ /**
587
+ * Base interface for all plugins
588
+ */
589
+ interface Plugin {
590
+ /** Unique plugin identifier */
591
+ readonly name: string;
592
+ /**
593
+ * Names of plugins this plugin depends on.
594
+ * Dependencies are initialized before this plugin.
595
+ */
596
+ readonly requires?: readonly string[];
597
+ /** Initialize the plugin with context */
598
+ initialize(context: PluginContext): Promise<void>;
599
+ /** Check if plugin is ready to use */
600
+ isReady(): boolean;
601
+ /** Optional cleanup method */
602
+ dispose?(): Promise<void>;
603
+ }
604
+ interface ImageMetadata {
605
+ readonly width: number;
606
+ readonly height: number;
607
+ readonly format: string;
608
+ }
609
+ interface ImageProcessOptions {
610
+ readonly width?: number;
611
+ readonly height?: number;
612
+ readonly format: 'webp' | 'avif' | 'jpeg' | 'png';
613
+ readonly quality?: number;
614
+ }
615
+ interface ImageProcessResult {
616
+ readonly outputPath: string;
617
+ readonly width: number;
618
+ readonly height: number;
619
+ readonly format: string;
620
+ readonly size: number;
621
+ }
622
+ /**
623
+ * Plugin for processing and optimizing images
624
+ */
625
+ interface ImageProcessorPlugin extends Plugin {
626
+ readonly name: 'imageProcessor';
627
+ /** Check if this processor can handle the file type */
628
+ canProcess(filePath: string): boolean;
629
+ /** Get image metadata without processing */
630
+ getMetadata(filePath: string): Promise<ImageMetadata>;
631
+ /** Process/optimize an image */
632
+ process(inputPath: string, outputPath: string, options: ImageProcessOptions): Promise<ImageProcessResult>;
633
+ /** Copy file without processing */
634
+ copy(inputPath: string, outputPath: string): Promise<void>;
635
+ }
636
+ /**
637
+ * Plugin for generating text embeddings
638
+ */
639
+ interface TextEmbeddingPlugin extends Plugin {
640
+ readonly name: 'textEmbedder';
641
+ /** Model identifier (e.g., "Xenova/all-MiniLM-L6-v2") */
642
+ readonly model: string;
643
+ /** Embedding vector dimensions */
644
+ readonly dimensions: number;
645
+ /** Generate embedding for a single text */
646
+ embed(text: string): Promise<readonly number[]>;
647
+ /** Generate embeddings for multiple texts */
648
+ batchEmbed(texts: readonly string[]): Promise<readonly (readonly number[])[]>;
649
+ }
650
+ /**
651
+ * Plugin for generating image embeddings (e.g., CLIP)
652
+ */
653
+ interface ImageEmbeddingPlugin extends Plugin {
654
+ readonly name: 'imageEmbedder';
655
+ /** Model identifier */
656
+ readonly model: string;
657
+ /** Embedding vector dimensions */
658
+ readonly dimensions: number;
659
+ /** Generate embedding from image file path */
660
+ embedFile(filePath: string): Promise<readonly number[]>;
661
+ /** Generate embedding from image buffer */
662
+ embedBuffer(buffer: Buffer, mimeType: string): Promise<readonly number[]>;
663
+ }
664
+ interface SimilarityResult {
665
+ /** Map of "hash1-hash2" -> similarity score */
666
+ readonly pairwiseScores: ReadonlyMap<string, number>;
667
+ /** Map of hash -> array of similar hashes (sorted by similarity) */
668
+ readonly similarPosts: ReadonlyMap<string, readonly string[]>;
669
+ /** Metadata about the computation */
670
+ readonly metadata: {
671
+ readonly computedAt: string;
672
+ readonly postCount: number;
673
+ readonly pairCount: number;
674
+ };
675
+ }
676
+ /**
677
+ * Plugin for computing post similarity
678
+ * Requires: textEmbedder
679
+ */
680
+ interface SimilarityPlugin extends Plugin {
681
+ readonly name: 'similarity';
682
+ readonly requires: readonly ['textEmbedder'];
683
+ /** Compute cosine similarity between two embedding vectors */
684
+ computeSimilarity(a: readonly number[], b: readonly number[]): number;
685
+ /** Generate similarity data for all posts */
686
+ generateSimilarityMap(posts: readonly ProcessedPost[]): Promise<SimilarityResult>;
687
+ }
688
+ interface DatabaseBuildInput {
689
+ readonly posts: readonly ProcessedPost[];
690
+ readonly media: readonly ProcessedMedia[];
691
+ readonly embeddings?: ReadonlyMap<string, readonly number[]>;
692
+ readonly imageEmbeddings?: ReadonlyMap<string, readonly number[]>;
693
+ }
694
+ interface DatabaseResult {
695
+ readonly databasePath: string;
696
+ readonly tables: readonly string[];
697
+ readonly rowCounts: Readonly<Record<string, number>>;
698
+ readonly hasVectorSearch: boolean;
699
+ }
700
+ /**
701
+ * Plugin for building a database from processed content
702
+ */
703
+ interface DatabasePlugin extends Plugin {
704
+ readonly name: 'database';
705
+ /** Build database from processed data */
706
+ build(input: DatabaseBuildInput): Promise<DatabaseResult>;
707
+ }
708
+ type MermaidStrategy = 'img-png' | 'img-svg' | 'inline-svg' | 'pre-mermaid';
709
+ interface MermaidRenderOptions {
710
+ readonly strategy: MermaidStrategy;
711
+ readonly dark?: boolean;
712
+ }
713
+ interface MermaidResult {
714
+ /** Rendered output (SVG string, base64 PNG, or original code) */
715
+ readonly output: string;
716
+ /** Strategy that was actually used */
717
+ readonly strategy: MermaidStrategy;
718
+ }
719
+ /**
720
+ * Plugin for rendering Mermaid diagrams
721
+ */
722
+ interface MermaidRendererPlugin extends Plugin {
723
+ readonly name: 'mermaidRenderer';
724
+ /** Render mermaid code to specified format */
725
+ render(code: string, options: MermaidRenderOptions): Promise<MermaidResult>;
726
+ /** Check if renderer is available (e.g., has browser) */
727
+ isAvailable(): Promise<boolean>;
728
+ }
729
+ /**
730
+ * Type-safe plugin configuration for ProcessConfig
731
+ */
732
+ interface PluginConfig {
733
+ /** Image processor plugin */
734
+ imageProcessor?: ImageProcessorPlugin;
735
+ /** Text embedding plugin */
736
+ textEmbedder?: TextEmbeddingPlugin;
737
+ /** Image embedding plugin */
738
+ imageEmbedder?: ImageEmbeddingPlugin;
739
+ /** Similarity computation plugin */
740
+ similarity?: SimilarityPlugin;
741
+ /** Database generation plugin */
742
+ database?: DatabasePlugin;
743
+ /** Mermaid rendering plugin */
744
+ mermaidRenderer?: MermaidRendererPlugin;
745
+ }
746
+ /**
747
+ * Union type of all plugin names
748
+ */
749
+ type PluginName = keyof PluginConfig;
750
+ /**
751
+ * Get plugin type by name
752
+ */
753
+ type PluginByName<N extends PluginName> = NonNullable<PluginConfig[N]>;
754
+
755
+ /**
756
+ * Configuration types for @repo-md/processor-core
757
+ */
758
+
759
+ interface ImageSizeConfig {
760
+ readonly width: number | null;
761
+ readonly height: number | null;
762
+ readonly suffix: string;
763
+ }
764
+ /** Default image sizes for responsive images */
765
+ declare const DEFAULT_IMAGE_SIZES: readonly ImageSizeConfig[];
766
+ interface DirectoryConfig {
767
+ /** Base directory for resolving relative paths (default: cwd) */
768
+ readonly base?: string;
769
+ /** Input directory */
770
+ readonly input: string;
771
+ /** Output directory for generated files (default: input + '/dist') */
772
+ readonly output?: string;
773
+ /** Media output subdirectory (default: '_media') */
774
+ readonly mediaOutput?: string;
775
+ /** Posts output subdirectory for individual post JSON files */
776
+ readonly postsOutput?: string;
777
+ }
778
+ interface MediaConfig {
779
+ /** Skip media processing entirely */
780
+ readonly skip?: boolean;
781
+ /** Whether to optimize images (default: true if imageProcessor plugin available) */
782
+ readonly optimize?: boolean;
783
+ /** Image sizes to generate */
784
+ readonly sizes?: readonly ImageSizeConfig[];
785
+ /** Output format for optimized images (default: 'webp') */
786
+ readonly format?: 'webp' | 'avif' | 'jpeg' | 'png';
787
+ /** Quality for lossy formats (default: 80) */
788
+ readonly quality?: number;
789
+ /** Whether to use content hash for filenames (default: true) */
790
+ readonly useHash?: boolean;
791
+ /** Whether to shard hashed files by first 2 chars (default: false) */
792
+ readonly useSharding?: boolean;
793
+ /** Domain for absolute URLs */
794
+ readonly domain?: string;
795
+ /** Asset path prefix (default: '/_media') */
796
+ readonly pathPrefix?: string;
797
+ }
798
+ interface ContentConfig {
799
+ /** URL prefix for notes (default: '/content') */
800
+ readonly notePathPrefix?: string;
801
+ /** Whether to process all files regardless of 'public' frontmatter */
802
+ readonly processAllFiles?: boolean;
803
+ /** Files to ignore during processing */
804
+ readonly ignoreFiles?: readonly string[];
805
+ /** Whether to export individual post JSON files */
806
+ readonly exportPosts?: boolean;
807
+ /** Whether to track relationships between posts */
808
+ readonly trackRelationships?: boolean;
809
+ /** Include slug tracking information in output */
810
+ readonly includeSlugTracking?: boolean;
811
+ /** Strategy for resolving slug conflicts */
812
+ readonly slugConflictStrategy?: 'number' | 'hash';
813
+ /** Scope for slug deduplication: 'global' (default) or 'top-folder' (per top-level directory) */
814
+ readonly slugScope?: 'global' | 'top-folder';
815
+ }
816
+ interface MermaidConfig {
817
+ /** Whether mermaid rendering is enabled (default: true) */
818
+ readonly enabled?: boolean;
819
+ /** Rendering strategy (default: 'inline-svg') */
820
+ readonly strategy?: 'img-png' | 'img-svg' | 'inline-svg' | 'pre-mermaid';
821
+ /** Enable dark mode support */
822
+ readonly dark?: boolean;
823
+ /** Custom mermaid configuration */
824
+ readonly mermaidConfig?: Readonly<Record<string, unknown>>;
825
+ }
826
+ interface PipelineConfig {
827
+ /** Enable GitHub Flavored Markdown (default: true) */
828
+ readonly gfm?: boolean;
829
+ /** Allow raw HTML in markdown (default: true) */
830
+ readonly allowRawHtml?: boolean;
831
+ /** Enable syntax highlighting for code blocks (default: true) */
832
+ readonly syntaxHighlighting?: boolean;
833
+ /** Enable LaTeX formula parsing (default: false) */
834
+ readonly parseFormulas?: boolean;
835
+ /** Remove broken/dead links instead of keeping them (default: false) */
836
+ readonly removeDeadLinks?: boolean;
837
+ /** Enable wiki-link resolution ([[Page Name]] → <a href="/slug">) (default: true) */
838
+ readonly wikiLinks?: boolean;
839
+ }
840
+ interface DebugConfig {
841
+ /** Debug level (0=off, 1=basic, 2=verbose) */
842
+ readonly level?: number;
843
+ /** Log timing information */
844
+ readonly timing?: boolean;
845
+ }
846
+ interface ProcessConfig {
847
+ /** Directory configuration */
848
+ readonly dir: DirectoryConfig;
849
+ /** Plugin configuration */
850
+ readonly plugins?: PluginConfig;
851
+ /** Media processing configuration */
852
+ readonly media?: MediaConfig;
853
+ /** Content processing configuration */
854
+ readonly content?: ContentConfig;
855
+ /** Mermaid rendering configuration */
856
+ readonly mermaid?: MermaidConfig;
857
+ /** Markdown pipeline configuration */
858
+ readonly pipeline?: PipelineConfig;
859
+ /** Debug configuration */
860
+ readonly debug?: DebugConfig;
861
+ /**
862
+ * Cache context for incremental builds.
863
+ * When provided, the processor will skip processing files
864
+ * whose content hash matches a cached entry and use cached metadata instead.
865
+ */
866
+ readonly cache?: CacheContext;
867
+ }
868
+ /**
869
+ * ProcessConfig with all fields required except cache (which remains optional)
870
+ */
871
+ type ProcessConfigWithDefaults = Required<Omit<ProcessConfig, 'cache'>> & {
872
+ cache?: CacheContext;
873
+ };
874
+ /**
875
+ * Merge configuration with defaults
876
+ */
877
+ declare const withDefaults: (config: ProcessConfig) => ProcessConfigWithDefaults;
878
+ /**
879
+ * Get output directory from config
880
+ */
881
+ declare const getOutputDir: (config: ProcessConfig) => string;
882
+ /**
883
+ * Get media output directory from config
884
+ */
885
+ declare const getMediaOutputDir: (config: ProcessConfig) => string;
886
+
887
+ export { type PluginName as $, type MediaPathMap as A, type BrokenLinkIssue as B, type CacheContext as C, DEFAULT_IMAGE_SIZES as D, type EmbeddingErrorIssue as E, type MediaProcessingIssue as F, type GraphData as G, type MediaSizeVariant as H, type ImageEmbeddingPlugin as I, type MermaidConfig as J, type MermaidErrorIssue as K, type LogLevel as L, type MediaConfig as M, type MermaidRenderOptions as N, type MermaidRendererPlugin as O, type MermaidResult as P, type MermaidStrategy as Q, type MissingMediaIssue as R, OUTPUT_FILES as S, type OutputFiles as T, type PathHashMap as U, type PipelineConfig as V, type Plugin as W, type PluginByName as X, type PluginConfig as Y, type PluginContext as Z, type PluginErrorIssue as _, type CacheStats as a, type PostCover as a0, type PostCoverError as a1, type PostCoverSize as a2, type PostMetadata as a3, type ProcessConfig as a4, type ProcessConfigWithDefaults as a5, type ProcessResult as a6, type ProcessedMedia as a7, type ProcessedPost as a8, type ProcessingIssue as a9, type RelationshipType as aa, type SimilarityPlugin as ab, type SimilarityResult as ac, type SlugConflictIssue as ad, type SlugHashMap as ae, type TextEmbeddingPlugin as af, type TocItem as ag, buildEmbeddingCacheFromManifest as ah, buildMediaCacheFromManifest as ai, calculateSummary as aj, createEmptyCacheStats as ak, filterIssues as al, generateIssueReport as am, getMediaOutputDir as an, getOutputDir as ao, isBrokenLinkIssue as ap, isEmbeddingErrorIssue as aq, isMediaProcessingIssue as ar, isMermaidErrorIssue as as, isMissingMediaIssue as at, isPluginErrorIssue as au, isSlugConflictIssue as av, withDefaults as aw, type CachedMediaMetadata as b, type CachedMediaSizeVariant as c, type ContentConfig as d, type DatabaseBuildInput as e, type DatabasePlugin as f, type DatabaseResult as g, type DebugConfig as h, type DirectoryConfig as i, type EmbeddingMap as j, type GraphEdge as k, type GraphNode as l, type ImageMetadata as m, type ImageProcessOptions as n, type ImageProcessResult as o, type ImageProcessorPlugin as p, type ImageSizeConfig as q, type IssueCategory as r, IssueCollector as s, type IssueCollectorState as t, type IssueFilterOptions as u, type IssueModule as v, type IssueReport as w, type IssueSeverity as x, type IssueSummary as y, type MediaMetadata as z };