@x12i/docify-export 1.0.0 → 1.1.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,755 @@
1
+ import { mkdirSync, writeFileSync, existsSync, readFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ function ensureDir(p) {
4
+ mkdirSync(p, { recursive: true });
5
+ }
6
+ function write(path, body) {
7
+ ensureDir(dirname(path));
8
+ writeFileSync(path, body);
9
+ }
10
+ function fm(fields) {
11
+ const lines = ["---"];
12
+ for (const [k, v] of Object.entries(fields)) {
13
+ if (v === undefined || v === null)
14
+ continue;
15
+ if (Array.isArray(v)) {
16
+ if (!v.length)
17
+ continue;
18
+ lines.push(`${k}: [${v.map((x) => JSON.stringify(x)).join(", ")}]`);
19
+ }
20
+ else if (typeof v === "boolean" || typeof v === "number") {
21
+ lines.push(`${k}: ${v}`);
22
+ }
23
+ else {
24
+ const s = String(v);
25
+ lines.push(s.includes("\n") ? `${k}: |\n ${s.replace(/\n/g, "\n ")}` : `${k}: ${JSON.stringify(s)}`);
26
+ }
27
+ }
28
+ lines.push("---", "");
29
+ return lines.join("\n");
30
+ }
31
+ function conceptMd(c, body) {
32
+ return (fm({
33
+ id: c.id,
34
+ type: "concept",
35
+ title: c.title,
36
+ summary: c.summary,
37
+ problem: c.problem,
38
+ why: c.why,
39
+ mentalModel: c.mentalModel,
40
+ audiences: c.audiences,
41
+ prerequisites: c.prerequisites,
42
+ related: c.related,
43
+ next: c.next,
44
+ version: c.version,
45
+ }) +
46
+ `# ${c.title}\n\n` +
47
+ (body?.trim() ||
48
+ [
49
+ c.summary,
50
+ c.problem ? `## Problem\n\n${c.problem}` : "",
51
+ c.why ? `## Why\n\n${c.why}` : "",
52
+ c.mentalModel ? `## Mental model\n\n${c.mentalModel}` : "",
53
+ c.howItWorks ? `## How it works\n\n${c.howItWorks}` : "",
54
+ ]
55
+ .filter(Boolean)
56
+ .join("\n\n") + "\n"));
57
+ }
58
+ function guideMd(g, body) {
59
+ const steps = g.steps?.map((s, i) => `${i + 1}. **${s.title}**${s.expectedResult ? ` — ${s.expectedResult}` : ""}`).join("\n") ||
60
+ "";
61
+ return (fm({
62
+ id: g.id,
63
+ type: "guide",
64
+ title: g.title,
65
+ summary: g.summary,
66
+ why: g.why,
67
+ audiences: g.audiences,
68
+ prerequisites: g.prerequisites,
69
+ related: g.related,
70
+ invariants: g.invariants,
71
+ confirmationRequired: g.confirmationRequired,
72
+ version: g.version,
73
+ }) +
74
+ `# ${g.title}\n\n` +
75
+ (body?.trim() ||
76
+ [
77
+ g.summary,
78
+ g.why ? `## Why this path\n\n${g.why}` : "",
79
+ g.useWhen?.length ? `## Use this when\n\n${g.useWhen.map((x) => `- ${x}`).join("\n")}` : "",
80
+ g.doNotUseWhen?.length
81
+ ? `## Do not use this when\n\n${g.doNotUseWhen.map((x) => `- ${x}`).join("\n")}`
82
+ : "",
83
+ g.invariants?.length
84
+ ? `## Invariants\n\n${g.invariants.map((x) => `- ${x}`).join("\n")}`
85
+ : "",
86
+ steps ? `## Steps\n\n${steps}` : "",
87
+ g.verification?.length
88
+ ? `## Verification\n\n${g.verification.map((x) => `- ${x}`).join("\n")}`
89
+ : "",
90
+ ]
91
+ .filter(Boolean)
92
+ .join("\n\n") + "\n"));
93
+ }
94
+ function scenarioMd(s, body) {
95
+ const paths = s.paths
96
+ .map((p) => `### ${p.label}\n\n**When:** ${p.when}\n\n${p.rationale ? `${p.rationale}\n\n` : ""}Guides: ${(p.guideIds || []).map((g) => `\`${g}\``).join(", ") || "_none_"}`)
97
+ .join("\n\n");
98
+ return (fm({
99
+ id: s.id,
100
+ type: "scenario",
101
+ title: s.title,
102
+ summary: s.summary,
103
+ audiences: s.audiences,
104
+ invariants: s.invariants,
105
+ version: s.version,
106
+ }) +
107
+ `# ${s.title}\n\n` +
108
+ (body?.trim() ||
109
+ [
110
+ `## Situation\n\n${s.situation}`,
111
+ `## Decision\n\n${s.decisionQuestion}`,
112
+ s.signals?.length
113
+ ? `## Signals\n\n${s.signals.map((x) => `- ${x}`).join("\n")}`
114
+ : "",
115
+ `## Paths\n\n${paths}`,
116
+ s.escalation ? `## Escalation\n\n${s.escalation}` : "",
117
+ ]
118
+ .filter(Boolean)
119
+ .join("\n\n") + "\n"));
120
+ }
121
+ function diagramMd(d) {
122
+ const nodes = d.nodes
123
+ .map((n) => `- **${n.label}** (\`${n.id}\`)${n.description ? `: ${n.description}` : ""}`)
124
+ .join("\n");
125
+ const edges = d.edges
126
+ .map((e) => `- ${e.from} → ${e.to}${e.label ? ` (${e.label})` : ""}`)
127
+ .join("\n");
128
+ return (fm({
129
+ id: d.id,
130
+ type: "diagram",
131
+ title: d.title,
132
+ summary: d.summary,
133
+ why: d.why,
134
+ diagramType: d.type,
135
+ audiences: d.audiences,
136
+ related: d.related,
137
+ }) +
138
+ `# ${d.title}\n\n` +
139
+ [
140
+ d.summary,
141
+ `## Why\n\n${d.why}`,
142
+ `## How to read\n\n${d.howToRead}`,
143
+ `## Text alternative\n\n${d.textAlternative}`,
144
+ nodes ? `## Nodes\n\n${nodes}` : "",
145
+ edges ? `## Edges\n\n${edges}` : "",
146
+ d.keyTakeaways?.length
147
+ ? `## Key takeaways\n\n${d.keyTakeaways.map((x) => `- ${x}`).join("\n")}`
148
+ : "",
149
+ d.mermaid ? `## Mermaid source\n\n\`\`\`mermaid\n${d.mermaid}\n\`\`\`` : "",
150
+ ]
151
+ .filter(Boolean)
152
+ .join("\n\n") + "\n");
153
+ }
154
+ function packFiles(type, id, title, summary, markdownPath, related = []) {
155
+ const packJson = {
156
+ id: `${type}/${id}`,
157
+ type,
158
+ title,
159
+ summary,
160
+ markdownPath,
161
+ files: [markdownPath],
162
+ related,
163
+ };
164
+ const packMd = fm({
165
+ id: packJson.id,
166
+ type: "pack",
167
+ title,
168
+ summary,
169
+ }) +
170
+ `# Pack: ${title}\n\n` +
171
+ `${summary}\n\n` +
172
+ `Primary markdown: \`${markdownPath}\`\n`;
173
+ return { packMd, packJson };
174
+ }
175
+ /**
176
+ * Emit open Markdown trees, INDEX.md, SEARCH.json, per-type indexes, and packs.
177
+ * Same explicit source drives human site downloads and agent packages.
178
+ */
179
+ export function emitOpenKnowledge(opts) {
180
+ const agentRoot = opts.agentDir ?? join(opts.outDir, "agent");
181
+ ensureDir(agentRoot);
182
+ const records = [];
183
+ const packs = [];
184
+ const manifestExtras = {
185
+ concepts: [],
186
+ guides: [],
187
+ scenarios: [],
188
+ decisions: [],
189
+ glossary: [],
190
+ visuals: [],
191
+ diagrams: [],
192
+ relationships: opts.knowledge.relationships.map((r) => ({
193
+ id: r.id,
194
+ type: String(r.type),
195
+ from: r.from,
196
+ to: r.to,
197
+ })),
198
+ tutorials: [],
199
+ examples: [],
200
+ sampleData: [],
201
+ uiClients: [],
202
+ apis: [],
203
+ packs: [],
204
+ indexes: {
205
+ indexMd: "INDEX.md",
206
+ searchJson: "SEARCH.json",
207
+ },
208
+ };
209
+ const k = opts.knowledge;
210
+ for (const c of k.concepts) {
211
+ const rel = `concepts/${c.id}.md`;
212
+ const md = conceptMd(c, k.markdownBodies[`concept:${c.id}`]);
213
+ write(join(agentRoot, rel), md);
214
+ const { packMd, packJson } = packFiles("concept", c.id, c.title, c.summary, rel, c.related);
215
+ write(join(agentRoot, `packs/concept/${c.id}/PACK.md`), packMd);
216
+ write(join(agentRoot, `packs/concept/${c.id}/pack.json`), JSON.stringify(packJson, null, 2));
217
+ packs.push(packJson);
218
+ manifestExtras.concepts.push({ id: c.id, title: c.title, md: rel });
219
+ manifestExtras.packs.push({
220
+ id: packJson.id,
221
+ type: "concept",
222
+ path: `packs/concept/${c.id}`,
223
+ });
224
+ records.push({
225
+ id: c.id,
226
+ type: "concept",
227
+ title: c.title,
228
+ summary: c.summary,
229
+ aliases: c.technicalName ? [c.technicalName] : [],
230
+ audiences: c.audiences,
231
+ tags: c.tags,
232
+ goals: [],
233
+ path: rel,
234
+ webPath: `/concepts/${c.id}`,
235
+ prerequisites: c.prerequisites,
236
+ related: c.related,
237
+ packIds: [packJson.id],
238
+ });
239
+ }
240
+ for (const g of k.guides) {
241
+ const rel = `guides/${g.id}.md`;
242
+ write(join(agentRoot, rel), guideMd(g, k.markdownBodies[`guide:${g.id}`]));
243
+ const { packMd, packJson } = packFiles("guide", g.id, g.title, g.summary, rel, g.related);
244
+ write(join(agentRoot, `packs/guide/${g.id}/PACK.md`), packMd);
245
+ write(join(agentRoot, `packs/guide/${g.id}/pack.json`), JSON.stringify(packJson, null, 2));
246
+ packs.push(packJson);
247
+ manifestExtras.guides.push({ id: g.id, title: g.title, md: rel });
248
+ manifestExtras.packs.push({
249
+ id: packJson.id,
250
+ type: "guide",
251
+ path: `packs/guide/${g.id}`,
252
+ });
253
+ records.push({
254
+ id: g.id,
255
+ type: "guide",
256
+ title: g.title,
257
+ summary: g.summary,
258
+ aliases: [],
259
+ audiences: g.audiences,
260
+ tags: g.tags,
261
+ goals: g.outcome ? [g.outcome] : [],
262
+ path: rel,
263
+ webPath: `/guides/${g.id}`,
264
+ prerequisites: g.prerequisites,
265
+ related: g.related,
266
+ packIds: [packJson.id],
267
+ });
268
+ }
269
+ for (const s of k.scenarios) {
270
+ const rel = `scenarios/${s.id}.md`;
271
+ write(join(agentRoot, rel), scenarioMd(s, k.markdownBodies[`scenario:${s.id}`]));
272
+ const { packMd, packJson } = packFiles("scenario", s.id, s.title, s.summary, rel, s.related);
273
+ write(join(agentRoot, `packs/scenario/${s.id}/PACK.md`), packMd);
274
+ write(join(agentRoot, `packs/scenario/${s.id}/pack.json`), JSON.stringify(packJson, null, 2));
275
+ packs.push(packJson);
276
+ manifestExtras.scenarios.push({ id: s.id, title: s.title, md: rel });
277
+ manifestExtras.packs.push({
278
+ id: packJson.id,
279
+ type: "scenario",
280
+ path: `packs/scenario/${s.id}`,
281
+ });
282
+ records.push({
283
+ id: s.id,
284
+ type: "scenario",
285
+ title: s.title,
286
+ summary: s.summary,
287
+ aliases: [],
288
+ audiences: s.audiences,
289
+ tags: s.tags,
290
+ goals: [s.decisionQuestion],
291
+ path: rel,
292
+ webPath: `/scenarios/${s.id}`,
293
+ prerequisites: s.prerequisites,
294
+ related: s.related,
295
+ packIds: [packJson.id],
296
+ });
297
+ }
298
+ for (const d of k.decisions) {
299
+ const rel = `decisions/${d.id}.md`;
300
+ const md = fm({
301
+ id: d.id,
302
+ type: "decision",
303
+ title: d.title,
304
+ summary: d.summary,
305
+ audiences: d.audiences,
306
+ }) +
307
+ `# ${d.title}\n\n${d.summary}\n\n` +
308
+ (d.recommendedDefault
309
+ ? `## Recommended default\n\n${d.recommendedDefault}\n\n`
310
+ : "") +
311
+ d.options
312
+ .map((o) => `### ${o.label}${o.recommended ? " (recommended)" : ""}\n\n${o.summary}`)
313
+ .join("\n\n") +
314
+ "\n";
315
+ write(join(agentRoot, rel), md);
316
+ manifestExtras.decisions.push({ id: d.id, title: d.title, md: rel });
317
+ records.push({
318
+ id: d.id,
319
+ type: "decision",
320
+ title: d.title,
321
+ summary: d.summary,
322
+ aliases: [],
323
+ audiences: d.audiences,
324
+ tags: d.tags,
325
+ goals: [],
326
+ path: rel,
327
+ prerequisites: d.prerequisites,
328
+ related: d.related,
329
+ packIds: [],
330
+ });
331
+ }
332
+ for (const t of k.glossary) {
333
+ const rel = `glossary/${t.id}.md`;
334
+ const md = fm({
335
+ id: t.id,
336
+ type: "glossary-term",
337
+ title: t.term,
338
+ summary: t.meaning,
339
+ aliases: t.aliases,
340
+ }) + `# ${t.term}\n\n${t.meaning}\n`;
341
+ write(join(agentRoot, rel), md);
342
+ manifestExtras.glossary.push({ id: t.id, term: t.term, md: rel });
343
+ records.push({
344
+ id: t.id,
345
+ type: "glossary",
346
+ title: t.term,
347
+ summary: t.meaning,
348
+ aliases: t.aliases,
349
+ audiences: [],
350
+ tags: [],
351
+ goals: [],
352
+ path: rel,
353
+ prerequisites: [],
354
+ related: t.relatedConceptIds,
355
+ packIds: [],
356
+ });
357
+ }
358
+ for (const v of k.visuals) {
359
+ const rel = `visuals/${v.id}.md`;
360
+ const md = fm({
361
+ id: v.id,
362
+ type: "visual",
363
+ title: v.caption,
364
+ summary: v.whyItMatters,
365
+ }) +
366
+ `# ${v.caption}\n\n` +
367
+ `Alt: ${v.alt}\n\n` +
368
+ `## What to notice\n\n${v.whatToNotice.map((x) => `- ${x}`).join("\n")}\n\n` +
369
+ `## Why it matters\n\n${v.whyItMatters}\n`;
370
+ write(join(agentRoot, rel), md);
371
+ manifestExtras.visuals.push({ id: v.id, title: v.caption, md: rel });
372
+ records.push({
373
+ id: v.id,
374
+ type: "visual",
375
+ title: v.caption,
376
+ summary: v.whyItMatters,
377
+ aliases: [],
378
+ audiences: [],
379
+ tags: [],
380
+ goals: [],
381
+ path: rel,
382
+ prerequisites: [],
383
+ related: v.conceptIds,
384
+ packIds: [],
385
+ });
386
+ }
387
+ for (const d of k.diagrams) {
388
+ const rel = `diagrams/${d.id}.md`;
389
+ write(join(agentRoot, rel), diagramMd(d));
390
+ if (d.mermaid) {
391
+ write(join(agentRoot, `diagrams/sources/${d.id}.mmd`), d.mermaid);
392
+ }
393
+ else if (d.mermaidPath && existsSync(d.mermaidPath)) {
394
+ write(join(agentRoot, `diagrams/sources/${d.id}.mmd`), readFileSync(d.mermaidPath, "utf8"));
395
+ }
396
+ const source = d.mermaid || d.mermaidPath ? `diagrams/sources/${d.id}.mmd` : undefined;
397
+ manifestExtras.diagrams.push({
398
+ id: d.id,
399
+ title: d.title,
400
+ md: rel,
401
+ source,
402
+ });
403
+ records.push({
404
+ id: d.id,
405
+ type: "diagram",
406
+ title: d.title,
407
+ summary: d.summary,
408
+ aliases: [],
409
+ audiences: d.audiences,
410
+ tags: d.tags,
411
+ goals: [],
412
+ path: rel,
413
+ webPath: `/diagrams/${d.id}`,
414
+ prerequisites: [],
415
+ related: d.related,
416
+ packIds: [],
417
+ });
418
+ }
419
+ for (const t of k.tutorials) {
420
+ const rel = `tutorials/${t.id}.md`;
421
+ const md = fm({
422
+ id: t.id,
423
+ type: "tutorial",
424
+ title: t.title,
425
+ summary: t.summary,
426
+ audiences: t.audiences,
427
+ }) +
428
+ `# ${t.title}\n\n${t.summary}\n\n` +
429
+ t.steps
430
+ .map((s, i) => `## ${i + 1}. ${s.title}\n\n${s.body ?? s.command ?? ""}`)
431
+ .join("\n\n") +
432
+ "\n";
433
+ write(join(agentRoot, rel), md);
434
+ const { packMd, packJson } = packFiles("tutorial", t.id, t.title, t.summary, rel, t.related);
435
+ write(join(agentRoot, `packs/tutorial/${t.id}/PACK.md`), packMd);
436
+ write(join(agentRoot, `packs/tutorial/${t.id}/pack.json`), JSON.stringify(packJson, null, 2));
437
+ packs.push(packJson);
438
+ manifestExtras.tutorials.push({ id: t.id, title: t.title, md: rel });
439
+ manifestExtras.packs.push({
440
+ id: packJson.id,
441
+ type: "tutorial",
442
+ path: `packs/tutorial/${t.id}`,
443
+ });
444
+ records.push({
445
+ id: t.id,
446
+ type: "tutorial",
447
+ title: t.title,
448
+ summary: t.summary,
449
+ aliases: [],
450
+ audiences: t.audiences,
451
+ tags: t.tags,
452
+ goals: t.outcome ? [t.outcome] : [],
453
+ path: rel,
454
+ prerequisites: t.prerequisites,
455
+ related: t.related,
456
+ packIds: [packJson.id],
457
+ });
458
+ }
459
+ for (const e of k.examples) {
460
+ const rel = `examples/${e.id}.md`;
461
+ const md = fm({
462
+ id: e.id,
463
+ type: "example",
464
+ title: e.title,
465
+ summary: e.purpose,
466
+ }) + `# ${e.title}\n\n${e.purpose}\n\n${e.explanation ?? ""}\n`;
467
+ write(join(agentRoot, rel), md);
468
+ manifestExtras.examples.push({ id: e.id, title: e.title, md: rel });
469
+ records.push({
470
+ id: e.id,
471
+ type: "example",
472
+ title: e.title,
473
+ summary: e.purpose,
474
+ aliases: [],
475
+ audiences: e.audiences,
476
+ tags: [],
477
+ goals: [],
478
+ path: rel,
479
+ prerequisites: [],
480
+ related: e.conceptIds,
481
+ packIds: [],
482
+ });
483
+ }
484
+ for (const ds of k.sampleData) {
485
+ const rel = `sample-data/${ds.id}.md`;
486
+ const md = fm({
487
+ id: ds.id,
488
+ type: "sample-data",
489
+ title: ds.id,
490
+ summary: ds.purpose,
491
+ version: ds.version,
492
+ origin: ds.origin,
493
+ }) + `# Sample data: ${ds.id}\n\n${ds.purpose}\n\nOrigin: ${ds.origin}\n`;
494
+ write(join(agentRoot, rel), md);
495
+ manifestExtras.sampleData.push({
496
+ id: ds.id,
497
+ title: ds.id,
498
+ md: rel,
499
+ });
500
+ records.push({
501
+ id: ds.id,
502
+ type: "sample-data",
503
+ title: ds.id,
504
+ summary: ds.purpose,
505
+ aliases: [],
506
+ audiences: [],
507
+ tags: [],
508
+ goals: [],
509
+ path: rel,
510
+ prerequisites: [],
511
+ related: [],
512
+ packIds: [],
513
+ });
514
+ }
515
+ for (const client of k.uiClients) {
516
+ const rel = `ui/clients/${client.id}.md`;
517
+ const md = fm({
518
+ id: client.id,
519
+ type: "ui-client",
520
+ title: client.title,
521
+ summary: client.summary,
522
+ }) + `# ${client.title}\n\n${client.summary}\n`;
523
+ write(join(agentRoot, rel), md);
524
+ manifestExtras.uiClients.push({
525
+ id: client.id,
526
+ title: client.title,
527
+ md: rel,
528
+ });
529
+ records.push({
530
+ id: client.id,
531
+ type: "ui-client",
532
+ title: client.title,
533
+ summary: client.summary,
534
+ aliases: [],
535
+ audiences: client.audiences,
536
+ tags: [],
537
+ goals: [],
538
+ path: rel,
539
+ prerequisites: [],
540
+ related: [],
541
+ packIds: [],
542
+ });
543
+ }
544
+ for (const api of k.apis) {
545
+ const rel = `apis/${api.id}/overview.md`;
546
+ const md = fm({
547
+ id: api.id,
548
+ type: "api",
549
+ title: api.title,
550
+ summary: api.summary,
551
+ why: api.why,
552
+ }) +
553
+ `# ${api.title}\n\n${api.summary}\n\n` +
554
+ (api.why ? `## Why\n\n${api.why}\n\n` : "") +
555
+ api.operations
556
+ .map((op) => `## ${op.method} ${op.path}\n\n${op.summary}`)
557
+ .join("\n\n") +
558
+ "\n";
559
+ write(join(agentRoot, rel), md);
560
+ manifestExtras.apis.push({ id: api.id, title: api.title, md: rel });
561
+ records.push({
562
+ id: api.id,
563
+ type: "api",
564
+ title: api.title,
565
+ summary: api.summary,
566
+ aliases: [],
567
+ audiences: api.audiences,
568
+ tags: [],
569
+ goals: [],
570
+ path: rel,
571
+ prerequisites: [],
572
+ related: api.related,
573
+ packIds: [],
574
+ });
575
+ }
576
+ // Use cases into open tree
577
+ for (const uc of opts.useCases.useCases) {
578
+ records.push({
579
+ id: uc.id,
580
+ type: "use-case",
581
+ title: uc.title,
582
+ summary: uc.expectedOutcome ?? uc.goal,
583
+ aliases: [],
584
+ audiences: uc.audiences,
585
+ tags: uc.tags,
586
+ goals: [uc.goal],
587
+ path: `use-cases/${uc.id}.md`,
588
+ webPath: `/use-cases#${uc.id}`,
589
+ prerequisites: uc.prerequisites ?? [],
590
+ related: uc.alsoSee ?? [],
591
+ packIds: [`use-case/${uc.id}`],
592
+ });
593
+ }
594
+ for (const book of opts.catalog.books) {
595
+ records.push({
596
+ id: book.id,
597
+ type: "book",
598
+ title: book.title,
599
+ summary: book.blurb,
600
+ aliases: [book.kicker],
601
+ audiences: book.audiences,
602
+ tags: book.tags,
603
+ goals: [],
604
+ path: `books/${book.id}/`,
605
+ webPath: `/books/${book.id}`,
606
+ prerequisites: [],
607
+ related: [],
608
+ packIds: [],
609
+ });
610
+ }
611
+ const search = {
612
+ version: 1,
613
+ product: opts.site.product,
614
+ generatedAt: new Date().toISOString(),
615
+ records,
616
+ };
617
+ write(join(agentRoot, "SEARCH.json"), JSON.stringify(search, null, 2));
618
+ const indexLines = [
619
+ `# ${opts.site.product} — knowledge index`,
620
+ "",
621
+ `Package: \`${opts.site.knowledgePackage}\``,
622
+ "",
623
+ "## How to choose",
624
+ "",
625
+ "- **Concept** — what it is and why it exists",
626
+ "- **Guide** — bounded task procedure",
627
+ "- **Scenario** — state + evidence → which path",
628
+ "- **Use case** — end-to-end outcome",
629
+ "- **Tutorial** — learn by doing",
630
+ "- **Decision** — options and recommended default",
631
+ "- **Reference / API** — exact technical detail",
632
+ "",
633
+ "## Manifest and search",
634
+ "",
635
+ "- `agent-manifest.json`",
636
+ "- `SEARCH.json`",
637
+ "",
638
+ ];
639
+ const sections = [
640
+ [
641
+ "Concepts",
642
+ k.concepts.map((c) => ({
643
+ id: c.id,
644
+ title: c.title,
645
+ summary: c.summary,
646
+ path: `concepts/${c.id}.md`,
647
+ })),
648
+ ],
649
+ [
650
+ "Guides",
651
+ k.guides.map((g) => ({
652
+ id: g.id,
653
+ title: g.title,
654
+ summary: g.summary,
655
+ path: `guides/${g.id}.md`,
656
+ })),
657
+ ],
658
+ [
659
+ "Scenarios",
660
+ k.scenarios.map((s) => ({
661
+ id: s.id,
662
+ title: s.title,
663
+ summary: s.summary,
664
+ path: `scenarios/${s.id}.md`,
665
+ })),
666
+ ],
667
+ [
668
+ "Diagrams",
669
+ k.diagrams.map((d) => ({
670
+ id: d.id,
671
+ title: d.title,
672
+ summary: d.summary,
673
+ path: `diagrams/${d.id}.md`,
674
+ })),
675
+ ],
676
+ [
677
+ "Tutorials",
678
+ k.tutorials.map((t) => ({
679
+ id: t.id,
680
+ title: t.title,
681
+ summary: t.summary,
682
+ path: `tutorials/${t.id}.md`,
683
+ })),
684
+ ],
685
+ ];
686
+ for (const [heading, items] of sections) {
687
+ indexLines.push(`## ${heading}`, "");
688
+ if (!items.length) {
689
+ indexLines.push("_None authored yet._", "");
690
+ continue;
691
+ }
692
+ for (const item of items) {
693
+ indexLines.push(`- \`${item.id}\` — **${item.title}** — ${item.summary} — [${item.path}](${item.path})`);
694
+ }
695
+ indexLines.push("");
696
+ }
697
+ const indexMd = indexLines.join("\n");
698
+ write(join(agentRoot, "INDEX.md"), indexMd);
699
+ // Per-type indexes
700
+ const writeTypeIndex = (name, items) => {
701
+ write(join(agentRoot, "indexes", `${name}.json`), JSON.stringify({ version: 1, items }, null, 2));
702
+ write(join(agentRoot, "indexes", `${name}.md`), `# ${name}\n\n` +
703
+ items.map((i) => `- \`${i.id}\` — ${i.title} — ${i.summary}`).join("\n") +
704
+ "\n");
705
+ };
706
+ writeTypeIndex("concepts", k.concepts.map((c) => ({
707
+ id: c.id,
708
+ title: c.title,
709
+ summary: c.summary,
710
+ path: `concepts/${c.id}.md`,
711
+ })));
712
+ writeTypeIndex("guides", k.guides.map((g) => ({
713
+ id: g.id,
714
+ title: g.title,
715
+ summary: g.summary,
716
+ path: `guides/${g.id}.md`,
717
+ })));
718
+ writeTypeIndex("scenarios", k.scenarios.map((s) => ({
719
+ id: s.id,
720
+ title: s.title,
721
+ summary: s.summary,
722
+ path: `scenarios/${s.id}.md`,
723
+ })));
724
+ writeTypeIndex("diagrams", k.diagrams.map((d) => ({
725
+ id: d.id,
726
+ title: d.title,
727
+ summary: d.summary,
728
+ path: `diagrams/${d.id}.md`,
729
+ })));
730
+ writeTypeIndex("use-cases", opts.useCases.useCases.map((u) => ({
731
+ id: u.id,
732
+ title: u.title,
733
+ summary: u.goal,
734
+ path: `use-cases/${u.id}.md`,
735
+ })));
736
+ writeTypeIndex("tutorials", k.tutorials.map((t) => ({
737
+ id: t.id,
738
+ title: t.title,
739
+ summary: t.summary,
740
+ path: `tutorials/${t.id}.md`,
741
+ })));
742
+ writeTypeIndex("books", opts.catalog.books.map((b) => ({
743
+ id: b.id,
744
+ title: b.title,
745
+ summary: b.blurb,
746
+ path: `books/${b.id}/`,
747
+ })));
748
+ // Also expose INDEX/SEARCH at bundle root for web downloads
749
+ write(join(opts.outDir, "INDEX.md"), indexMd);
750
+ write(join(opts.outDir, "SEARCH.json"), JSON.stringify(search, null, 2));
751
+ write(join(opts.outDir, "agent", "INDEX.md"), indexMd);
752
+ // agent tree already under agentRoot; if agentRoot is outDir/agent we're good
753
+ return { search, indexMd, packs, manifestExtras };
754
+ }
755
+ //# sourceMappingURL=emit-knowledge.js.map