docs-ready 0.2.0 → 0.3.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,338 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/generate/key-pages.ts
4
+ var PATH_KEYWORDS = [
5
+ "getting-started",
6
+ "quickstart",
7
+ "quick-start",
8
+ "setup",
9
+ "install",
10
+ "tutorial",
11
+ "overview",
12
+ "introduction",
13
+ "api",
14
+ "sdk",
15
+ "reference",
16
+ "config",
17
+ "configuration",
18
+ "network",
19
+ "deploy",
20
+ "migration"
21
+ ];
22
+ var TITLE_KEYWORDS = [
23
+ "getting started",
24
+ "quickstart",
25
+ "quick start",
26
+ "setup",
27
+ "install",
28
+ "tutorial",
29
+ "overview",
30
+ "introduction",
31
+ "api reference",
32
+ "sdk",
33
+ "reference",
34
+ "config",
35
+ "configuration",
36
+ "network",
37
+ "deploy",
38
+ "migration"
39
+ ];
40
+ var CONTENT_PATTERNS = [
41
+ { pattern: /0x[a-fA-F0-9]{40}/, label: "contract-address" },
42
+ { pattern: /chain\s*id/i, label: "chain-id" },
43
+ { pattern: /rpc\s*(url|endpoint)/i, label: "rpc-url" },
44
+ { pattern: /npm install\s+\S+/, label: "npm-install" },
45
+ { pattern: /go get\s+\S+/, label: "go-get" },
46
+ { pattern: /pip install\s+\S+/, label: "pip-install" }
47
+ ];
48
+ function detectKeyPages(pages) {
49
+ const results = [];
50
+ for (const page of pages) {
51
+ const reasons = [];
52
+ const pathLower = page.relativePath.toLowerCase();
53
+ const titleLower = page.title.toLowerCase();
54
+ if (PATH_KEYWORDS.some((kw) => pathLower.includes(kw))) {
55
+ reasons.push("path-keyword");
56
+ }
57
+ if (TITLE_KEYWORDS.some((kw) => titleLower.includes(kw))) {
58
+ reasons.push("title-keyword");
59
+ }
60
+ if (CONTENT_PATTERNS.some((cp) => cp.pattern.test(page.content))) {
61
+ reasons.push("content-pattern");
62
+ }
63
+ if (reasons.length > 0) {
64
+ results.push({ page, reasons });
65
+ }
66
+ }
67
+ return results;
68
+ }
69
+
70
+ // src/generate/extractors.ts
71
+ function extractContractAddresses(content) {
72
+ const regex = /0x[a-fA-F0-9]{40}/g;
73
+ const matches = content.match(regex);
74
+ return matches ?? [];
75
+ }
76
+ function extractCodeBlocks(content) {
77
+ const blocks = /* @__PURE__ */ new Map();
78
+ const regex = /```(\w+)\n([\s\S]*?)```/g;
79
+ let match;
80
+ while ((match = regex.exec(content)) !== null) {
81
+ const lang = match[1];
82
+ const code = match[2].trim();
83
+ if (!blocks.has(lang)) {
84
+ blocks.set(lang, []);
85
+ }
86
+ blocks.get(lang).push(code);
87
+ }
88
+ return blocks;
89
+ }
90
+ function extractTables(content) {
91
+ const tables = [];
92
+ const lines = content.split("\n");
93
+ let current = [];
94
+ let inTable = false;
95
+ for (const line of lines) {
96
+ const trimmed = line.trim();
97
+ if (trimmed.startsWith("|") && trimmed.endsWith("|")) {
98
+ inTable = true;
99
+ current.push(line);
100
+ } else {
101
+ if (inTable && current.length >= 2) {
102
+ tables.push(current.join("\n"));
103
+ }
104
+ current = [];
105
+ inTable = false;
106
+ }
107
+ }
108
+ if (inTable && current.length >= 2) {
109
+ tables.push(current.join("\n"));
110
+ }
111
+ return tables;
112
+ }
113
+ function extractLinks(content) {
114
+ const links = [];
115
+ const regex = /\[([^\]]+)\]\((https?:\/\/[^)]+)\)/g;
116
+ let match;
117
+ while ((match = regex.exec(content)) !== null) {
118
+ const text = match[1];
119
+ const url = match[2];
120
+ let category = "external";
121
+ if (url.includes("github.com")) {
122
+ category = "github";
123
+ } else if (url.includes("npmjs.com") || url.includes("npm.im")) {
124
+ category = "npm";
125
+ }
126
+ links.push({ text, url, category });
127
+ }
128
+ return links;
129
+ }
130
+ function deduplicateBlocks(blocks) {
131
+ const result = /* @__PURE__ */ new Map();
132
+ for (const [lang, codeList] of blocks) {
133
+ result.set(lang, [...new Set(codeList)]);
134
+ }
135
+ return result;
136
+ }
137
+
138
+ // src/generate/ai-context.ts
139
+ var NETWORK_PATTERNS = [/chain\s*id/i, /rpc\s*(url|endpoint)/i];
140
+ var QUICKSTART_PATH_KEYWORDS = [
141
+ "getting-started",
142
+ "quickstart",
143
+ "quick-start",
144
+ "setup",
145
+ "install",
146
+ "sdk"
147
+ ];
148
+ function generateAiContext(pages, config) {
149
+ const keyPages = resolveKeyPages(pages, config);
150
+ const sections = [];
151
+ sections.push(
152
+ "<!-- Auto-generated by docs-ready. Review and customize. -->"
153
+ );
154
+ sections.push("");
155
+ sections.push(`# ${config.title} \u2014 AI Context`);
156
+ sections.push("");
157
+ sections.push("## Overview");
158
+ sections.push("");
159
+ sections.push(config.description);
160
+ const networkSection = buildNetworkSection(keyPages);
161
+ if (networkSection) {
162
+ sections.push("");
163
+ sections.push("## Network Configuration");
164
+ sections.push("");
165
+ sections.push(networkSection);
166
+ }
167
+ const contractSection = buildContractSection(keyPages);
168
+ if (contractSection) {
169
+ sections.push("");
170
+ sections.push("## Contract Addresses");
171
+ sections.push("");
172
+ sections.push(contractSection);
173
+ }
174
+ const quickStartSection = buildQuickStartSection(keyPages);
175
+ if (quickStartSection) {
176
+ sections.push("");
177
+ sections.push("## Quick Start");
178
+ sections.push("");
179
+ sections.push(quickStartSection);
180
+ }
181
+ const linksSection = buildLinksSection(keyPages);
182
+ if (linksSection) {
183
+ sections.push("");
184
+ sections.push("## Links & Resources");
185
+ sections.push("");
186
+ sections.push(linksSection);
187
+ }
188
+ if (config.aiContextConfig?.extra_sections) {
189
+ for (const extra of config.aiContextConfig.extra_sections) {
190
+ sections.push("");
191
+ sections.push(`## ${extra.title}`);
192
+ sections.push("");
193
+ sections.push(extra.content);
194
+ }
195
+ }
196
+ return sections.join("\n") + "\n";
197
+ }
198
+ function resolveKeyPages(pages, config) {
199
+ if (config.aiContextConfig?.key_pages?.length) {
200
+ const manual = [];
201
+ for (const kp of config.aiContextConfig.key_pages) {
202
+ const match = pages.find(
203
+ (p) => p.relativePath === kp.path || p.relativePath === kp.path.replace(/\\/g, "/")
204
+ );
205
+ if (match) {
206
+ manual.push(match);
207
+ }
208
+ }
209
+ if (manual.length > 0) {
210
+ return manual;
211
+ }
212
+ }
213
+ const detected = detectKeyPages(pages);
214
+ if (detected.length > 0) {
215
+ return detected.map((d) => d.page);
216
+ }
217
+ return pages;
218
+ }
219
+ function buildNetworkSection(pages) {
220
+ const networkTables = [];
221
+ for (const page of pages) {
222
+ const hasNetworkContent = NETWORK_PATTERNS.some(
223
+ (p) => p.test(page.content)
224
+ );
225
+ if (!hasNetworkContent) continue;
226
+ const tables = extractTables(page.content);
227
+ for (const table of tables) {
228
+ if (NETWORK_PATTERNS.some((p) => p.test(table))) {
229
+ networkTables.push(`### ${page.title}
230
+
231
+ ${table}`);
232
+ }
233
+ }
234
+ }
235
+ if (networkTables.length === 0) return null;
236
+ return networkTables.join("\n\n");
237
+ }
238
+ function buildContractSection(pages) {
239
+ const addressTables = [];
240
+ const looseAddresses = [];
241
+ for (const page of pages) {
242
+ const addresses = extractContractAddresses(page.content);
243
+ if (addresses.length === 0) continue;
244
+ const tables = extractTables(page.content);
245
+ const tablesWithAddresses = tables.filter(
246
+ (t) => addresses.some((addr) => t.includes(addr))
247
+ );
248
+ if (tablesWithAddresses.length > 0) {
249
+ for (const table of tablesWithAddresses) {
250
+ addressTables.push(`### ${page.title}
251
+
252
+ ${table}`);
253
+ }
254
+ } else {
255
+ for (const addr of addresses) {
256
+ looseAddresses.push(`- \`${addr}\``);
257
+ }
258
+ }
259
+ }
260
+ if (addressTables.length === 0 && looseAddresses.length === 0) return null;
261
+ const parts = [];
262
+ if (addressTables.length > 0) {
263
+ parts.push(addressTables.join("\n\n"));
264
+ }
265
+ if (looseAddresses.length > 0) {
266
+ parts.push([...new Set(looseAddresses)].join("\n"));
267
+ }
268
+ return parts.join("\n\n");
269
+ }
270
+ function buildQuickStartSection(pages) {
271
+ const allBlocks = /* @__PURE__ */ new Map();
272
+ for (const page of pages) {
273
+ const pathLower = page.relativePath.toLowerCase();
274
+ const titleLower = page.title.toLowerCase();
275
+ const isQuickstartPage = QUICKSTART_PATH_KEYWORDS.some((kw) => pathLower.includes(kw)) || QUICKSTART_PATH_KEYWORDS.some((kw) => titleLower.includes(kw));
276
+ if (!isQuickstartPage) continue;
277
+ const blocks = extractCodeBlocks(page.content);
278
+ for (const [lang, codeList] of blocks) {
279
+ if (!allBlocks.has(lang)) {
280
+ allBlocks.set(lang, []);
281
+ }
282
+ allBlocks.get(lang).push(...codeList);
283
+ }
284
+ }
285
+ if (allBlocks.size === 0) return null;
286
+ const deduplicated = deduplicateBlocks(allBlocks);
287
+ const parts = [];
288
+ for (const [lang, codeList] of deduplicated) {
289
+ for (const code of codeList) {
290
+ parts.push(`\`\`\`${lang}
291
+ ${code}
292
+ \`\`\``);
293
+ }
294
+ }
295
+ return parts.join("\n\n");
296
+ }
297
+ function buildLinksSection(pages) {
298
+ const allLinks = [];
299
+ for (const page of pages) {
300
+ const links = extractLinks(page.content);
301
+ allLinks.push(...links);
302
+ }
303
+ if (allLinks.length === 0) return null;
304
+ const seen = /* @__PURE__ */ new Set();
305
+ const unique = [];
306
+ for (const link of allLinks) {
307
+ if (!seen.has(link.url)) {
308
+ seen.add(link.url);
309
+ unique.push(link);
310
+ }
311
+ }
312
+ const github = unique.filter((l) => l.category === "github");
313
+ const npm = unique.filter((l) => l.category === "npm");
314
+ const external = unique.filter((l) => l.category === "external");
315
+ const parts = [];
316
+ if (github.length > 0) {
317
+ parts.push("### GitHub");
318
+ parts.push("");
319
+ parts.push(...github.map((l) => `- [${l.text}](${l.url})`));
320
+ }
321
+ if (npm.length > 0) {
322
+ parts.push("");
323
+ parts.push("### npm");
324
+ parts.push("");
325
+ parts.push(...npm.map((l) => `- [${l.text}](${l.url})`));
326
+ }
327
+ if (external.length > 0) {
328
+ parts.push("");
329
+ parts.push("### External");
330
+ parts.push("");
331
+ parts.push(...external.map((l) => `- [${l.text}](${l.url})`));
332
+ }
333
+ return parts.join("\n");
334
+ }
335
+ export {
336
+ generateAiContext
337
+ };
338
+ //# sourceMappingURL=ai-context-QVGQK3GD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/generate/key-pages.ts","../src/generate/extractors.ts","../src/generate/ai-context.ts"],"sourcesContent":["import type { ScannedPage } from \"../core/scanner.js\";\n\nexport interface KeyPageResult {\n page: ScannedPage;\n reasons: string[];\n}\n\nconst PATH_KEYWORDS = [\n \"getting-started\", \"quickstart\", \"quick-start\", \"setup\", \"install\",\n \"tutorial\", \"overview\", \"introduction\", \"api\", \"sdk\", \"reference\",\n \"config\", \"configuration\", \"network\", \"deploy\", \"migration\",\n];\n\nconst TITLE_KEYWORDS = [\n \"getting started\", \"quickstart\", \"quick start\", \"setup\", \"install\",\n \"tutorial\", \"overview\", \"introduction\", \"api reference\", \"sdk\",\n \"reference\", \"config\", \"configuration\", \"network\", \"deploy\", \"migration\",\n];\n\nconst CONTENT_PATTERNS: Array<{ pattern: RegExp; label: string }> = [\n { pattern: /0x[a-fA-F0-9]{40}/, label: \"contract-address\" },\n { pattern: /chain\\s*id/i, label: \"chain-id\" },\n { pattern: /rpc\\s*(url|endpoint)/i, label: \"rpc-url\" },\n { pattern: /npm install\\s+\\S+/, label: \"npm-install\" },\n { pattern: /go get\\s+\\S+/, label: \"go-get\" },\n { pattern: /pip install\\s+\\S+/, label: \"pip-install\" },\n];\n\nexport function detectKeyPages(pages: ScannedPage[]): KeyPageResult[] {\n const results: KeyPageResult[] = [];\n\n for (const page of pages) {\n const reasons: string[] = [];\n const pathLower = page.relativePath.toLowerCase();\n const titleLower = page.title.toLowerCase();\n\n if (PATH_KEYWORDS.some((kw) => pathLower.includes(kw))) {\n reasons.push(\"path-keyword\");\n }\n\n if (TITLE_KEYWORDS.some((kw) => titleLower.includes(kw))) {\n reasons.push(\"title-keyword\");\n }\n\n if (CONTENT_PATTERNS.some((cp) => cp.pattern.test(page.content))) {\n reasons.push(\"content-pattern\");\n }\n\n if (reasons.length > 0) {\n results.push({ page, reasons });\n }\n }\n\n return results;\n}\n","export function extractContractAddresses(content: string): string[] {\n const regex = /0x[a-fA-F0-9]{40}/g;\n const matches = content.match(regex);\n return matches ?? [];\n}\n\nexport function extractCodeBlocks(content: string): Map<string, string[]> {\n const blocks = new Map<string, string[]>();\n const regex = /```(\\w+)\\n([\\s\\S]*?)```/g;\n let match;\n\n while ((match = regex.exec(content)) !== null) {\n const lang = match[1];\n const code = match[2].trim();\n if (!blocks.has(lang)) {\n blocks.set(lang, []);\n }\n blocks.get(lang)!.push(code);\n }\n\n return blocks;\n}\n\nexport function extractTables(content: string): string[] {\n const tables: string[] = [];\n const lines = content.split(\"\\n\");\n let current: string[] = [];\n let inTable = false;\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed.startsWith(\"|\") && trimmed.endsWith(\"|\")) {\n inTable = true;\n current.push(line);\n } else {\n if (inTable && current.length >= 2) {\n tables.push(current.join(\"\\n\"));\n }\n current = [];\n inTable = false;\n }\n }\n\n if (inTable && current.length >= 2) {\n tables.push(current.join(\"\\n\"));\n }\n\n return tables;\n}\n\nexport interface ExtractedLink {\n text: string;\n url: string;\n category: \"github\" | \"npm\" | \"external\";\n}\n\nexport function extractLinks(content: string): ExtractedLink[] {\n const links: ExtractedLink[] = [];\n const regex = /\\[([^\\]]+)\\]\\((https?:\\/\\/[^)]+)\\)/g;\n let match;\n\n while ((match = regex.exec(content)) !== null) {\n const text = match[1];\n const url = match[2];\n let category: ExtractedLink[\"category\"] = \"external\";\n if (url.includes(\"github.com\")) {\n category = \"github\";\n } else if (url.includes(\"npmjs.com\") || url.includes(\"npm.im\")) {\n category = \"npm\";\n }\n links.push({ text, url, category });\n }\n\n return links;\n}\n\nexport function deduplicateBlocks(blocks: Map<string, string[]>): Map<string, string[]> {\n const result = new Map<string, string[]>();\n for (const [lang, codeList] of blocks) {\n result.set(lang, [...new Set(codeList)]);\n }\n return result;\n}\n","import type { ScannedPage } from \"../core/scanner.js\";\nimport { detectKeyPages } from \"./key-pages.js\";\nimport {\n extractContractAddresses,\n extractCodeBlocks,\n extractTables,\n extractLinks,\n deduplicateBlocks,\n type ExtractedLink,\n} from \"./extractors.js\";\n\nexport interface AiContextConfig {\n title: string;\n description: string;\n aiContextConfig?: {\n key_pages?: Array<{ path: string; section: string }>;\n extra_sections?: Array<{ title: string; content: string }>;\n };\n}\n\nconst NETWORK_PATTERNS = [/chain\\s*id/i, /rpc\\s*(url|endpoint)/i];\nconst QUICKSTART_PATH_KEYWORDS = [\n \"getting-started\",\n \"quickstart\",\n \"quick-start\",\n \"setup\",\n \"install\",\n \"sdk\",\n];\n\nexport function generateAiContext(\n pages: ScannedPage[],\n config: AiContextConfig,\n): string {\n const keyPages = resolveKeyPages(pages, config);\n const sections: string[] = [];\n\n // Header\n sections.push(\n \"<!-- Auto-generated by docs-ready. Review and customize. -->\",\n );\n sections.push(\"\");\n sections.push(`# ${config.title} — AI Context`);\n\n // Overview — always present\n sections.push(\"\");\n sections.push(\"## Overview\");\n sections.push(\"\");\n sections.push(config.description);\n\n // Network Configuration\n const networkSection = buildNetworkSection(keyPages);\n if (networkSection) {\n sections.push(\"\");\n sections.push(\"## Network Configuration\");\n sections.push(\"\");\n sections.push(networkSection);\n }\n\n // Contract Addresses\n const contractSection = buildContractSection(keyPages);\n if (contractSection) {\n sections.push(\"\");\n sections.push(\"## Contract Addresses\");\n sections.push(\"\");\n sections.push(contractSection);\n }\n\n // Quick Start\n const quickStartSection = buildQuickStartSection(keyPages);\n if (quickStartSection) {\n sections.push(\"\");\n sections.push(\"## Quick Start\");\n sections.push(\"\");\n sections.push(quickStartSection);\n }\n\n // Links & Resources\n const linksSection = buildLinksSection(keyPages);\n if (linksSection) {\n sections.push(\"\");\n sections.push(\"## Links & Resources\");\n sections.push(\"\");\n sections.push(linksSection);\n }\n\n // Extra sections from config\n if (config.aiContextConfig?.extra_sections) {\n for (const extra of config.aiContextConfig.extra_sections) {\n sections.push(\"\");\n sections.push(`## ${extra.title}`);\n sections.push(\"\");\n sections.push(extra.content);\n }\n }\n\n return sections.join(\"\\n\") + \"\\n\";\n}\n\nfunction resolveKeyPages(\n pages: ScannedPage[],\n config: AiContextConfig,\n): ScannedPage[] {\n // Manual override\n if (config.aiContextConfig?.key_pages?.length) {\n const manual: ScannedPage[] = [];\n for (const kp of config.aiContextConfig.key_pages) {\n const match = pages.find(\n (p) =>\n p.relativePath === kp.path ||\n p.relativePath === kp.path.replace(/\\\\/g, \"/\"),\n );\n if (match) {\n manual.push(match);\n }\n }\n // If manual pages resolved, return them; otherwise fall through\n if (manual.length > 0) {\n return manual;\n }\n }\n\n // Auto-detect\n const detected = detectKeyPages(pages);\n if (detected.length > 0) {\n return detected.map((d) => d.page);\n }\n\n // Fallback: all pages\n return pages;\n}\n\nfunction buildNetworkSection(pages: ScannedPage[]): string | null {\n const networkTables: string[] = [];\n\n for (const page of pages) {\n const hasNetworkContent = NETWORK_PATTERNS.some((p) =>\n p.test(page.content),\n );\n if (!hasNetworkContent) continue;\n\n const tables = extractTables(page.content);\n // Only include tables that contain network-related content\n for (const table of tables) {\n if (NETWORK_PATTERNS.some((p) => p.test(table))) {\n networkTables.push(`### ${page.title}\\n\\n${table}`);\n }\n }\n }\n\n if (networkTables.length === 0) return null;\n return networkTables.join(\"\\n\\n\");\n}\n\nfunction buildContractSection(pages: ScannedPage[]): string | null {\n const addressTables: string[] = [];\n const looseAddresses: string[] = [];\n\n for (const page of pages) {\n const addresses = extractContractAddresses(page.content);\n if (addresses.length === 0) continue;\n\n // Check if the addresses appear inside tables\n const tables = extractTables(page.content);\n const tablesWithAddresses = tables.filter((t) =>\n addresses.some((addr) => t.includes(addr)),\n );\n\n if (tablesWithAddresses.length > 0) {\n for (const table of tablesWithAddresses) {\n addressTables.push(`### ${page.title}\\n\\n${table}`);\n }\n } else {\n // Fallback: bullet list\n for (const addr of addresses) {\n looseAddresses.push(`- \\`${addr}\\``);\n }\n }\n }\n\n if (addressTables.length === 0 && looseAddresses.length === 0) return null;\n\n const parts: string[] = [];\n if (addressTables.length > 0) {\n parts.push(addressTables.join(\"\\n\\n\"));\n }\n if (looseAddresses.length > 0) {\n parts.push([...new Set(looseAddresses)].join(\"\\n\"));\n }\n return parts.join(\"\\n\\n\");\n}\n\nfunction buildQuickStartSection(pages: ScannedPage[]): string | null {\n const allBlocks = new Map<string, string[]>();\n\n for (const page of pages) {\n const pathLower = page.relativePath.toLowerCase();\n const titleLower = page.title.toLowerCase();\n const isQuickstartPage =\n QUICKSTART_PATH_KEYWORDS.some((kw) => pathLower.includes(kw)) ||\n QUICKSTART_PATH_KEYWORDS.some((kw) => titleLower.includes(kw));\n\n if (!isQuickstartPage) continue;\n\n const blocks = extractCodeBlocks(page.content);\n for (const [lang, codeList] of blocks) {\n if (!allBlocks.has(lang)) {\n allBlocks.set(lang, []);\n }\n allBlocks.get(lang)!.push(...codeList);\n }\n }\n\n if (allBlocks.size === 0) return null;\n\n const deduplicated = deduplicateBlocks(allBlocks);\n const parts: string[] = [];\n\n for (const [lang, codeList] of deduplicated) {\n for (const code of codeList) {\n parts.push(`\\`\\`\\`${lang}\\n${code}\\n\\`\\`\\``);\n }\n }\n\n return parts.join(\"\\n\\n\");\n}\n\nfunction buildLinksSection(pages: ScannedPage[]): string | null {\n const allLinks: ExtractedLink[] = [];\n\n for (const page of pages) {\n const links = extractLinks(page.content);\n allLinks.push(...links);\n }\n\n if (allLinks.length === 0) return null;\n\n // Deduplicate by URL\n const seen = new Set<string>();\n const unique: ExtractedLink[] = [];\n for (const link of allLinks) {\n if (!seen.has(link.url)) {\n seen.add(link.url);\n unique.push(link);\n }\n }\n\n // Categorize\n const github = unique.filter((l) => l.category === \"github\");\n const npm = unique.filter((l) => l.category === \"npm\");\n const external = unique.filter((l) => l.category === \"external\");\n\n const parts: string[] = [];\n\n if (github.length > 0) {\n parts.push(\"### GitHub\");\n parts.push(\"\");\n parts.push(...github.map((l) => `- [${l.text}](${l.url})`));\n }\n\n if (npm.length > 0) {\n parts.push(\"\");\n parts.push(\"### npm\");\n parts.push(\"\");\n parts.push(...npm.map((l) => `- [${l.text}](${l.url})`));\n }\n\n if (external.length > 0) {\n parts.push(\"\");\n parts.push(\"### External\");\n parts.push(\"\");\n parts.push(...external.map((l) => `- [${l.text}](${l.url})`));\n }\n\n return parts.join(\"\\n\");\n}\n"],"mappings":";;;AAOA,IAAM,gBAAgB;AAAA,EACpB;AAAA,EAAmB;AAAA,EAAc;AAAA,EAAe;AAAA,EAAS;AAAA,EACzD;AAAA,EAAY;AAAA,EAAY;AAAA,EAAgB;AAAA,EAAO;AAAA,EAAO;AAAA,EACtD;AAAA,EAAU;AAAA,EAAiB;AAAA,EAAW;AAAA,EAAU;AAClD;AAEA,IAAM,iBAAiB;AAAA,EACrB;AAAA,EAAmB;AAAA,EAAc;AAAA,EAAe;AAAA,EAAS;AAAA,EACzD;AAAA,EAAY;AAAA,EAAY;AAAA,EAAgB;AAAA,EAAiB;AAAA,EACzD;AAAA,EAAa;AAAA,EAAU;AAAA,EAAiB;AAAA,EAAW;AAAA,EAAU;AAC/D;AAEA,IAAM,mBAA8D;AAAA,EAClE,EAAE,SAAS,qBAAqB,OAAO,mBAAmB;AAAA,EAC1D,EAAE,SAAS,eAAe,OAAO,WAAW;AAAA,EAC5C,EAAE,SAAS,yBAAyB,OAAO,UAAU;AAAA,EACrD,EAAE,SAAS,qBAAqB,OAAO,cAAc;AAAA,EACrD,EAAE,SAAS,gBAAgB,OAAO,SAAS;AAAA,EAC3C,EAAE,SAAS,qBAAqB,OAAO,cAAc;AACvD;AAEO,SAAS,eAAe,OAAuC;AACpE,QAAM,UAA2B,CAAC;AAElC,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAoB,CAAC;AAC3B,UAAM,YAAY,KAAK,aAAa,YAAY;AAChD,UAAM,aAAa,KAAK,MAAM,YAAY;AAE1C,QAAI,cAAc,KAAK,CAAC,OAAO,UAAU,SAAS,EAAE,CAAC,GAAG;AACtD,cAAQ,KAAK,cAAc;AAAA,IAC7B;AAEA,QAAI,eAAe,KAAK,CAAC,OAAO,WAAW,SAAS,EAAE,CAAC,GAAG;AACxD,cAAQ,KAAK,eAAe;AAAA,IAC9B;AAEA,QAAI,iBAAiB,KAAK,CAAC,OAAO,GAAG,QAAQ,KAAK,KAAK,OAAO,CAAC,GAAG;AAChE,cAAQ,KAAK,iBAAiB;AAAA,IAChC;AAEA,QAAI,QAAQ,SAAS,GAAG;AACtB,cAAQ,KAAK,EAAE,MAAM,QAAQ,CAAC;AAAA,IAChC;AAAA,EACF;AAEA,SAAO;AACT;;;ACtDO,SAAS,yBAAyB,SAA2B;AAClE,QAAM,QAAQ;AACd,QAAM,UAAU,QAAQ,MAAM,KAAK;AACnC,SAAO,WAAW,CAAC;AACrB;AAEO,SAAS,kBAAkB,SAAwC;AACxE,QAAM,SAAS,oBAAI,IAAsB;AACzC,QAAM,QAAQ;AACd,MAAI;AAEJ,UAAQ,QAAQ,MAAM,KAAK,OAAO,OAAO,MAAM;AAC7C,UAAM,OAAO,MAAM,CAAC;AACpB,UAAM,OAAO,MAAM,CAAC,EAAE,KAAK;AAC3B,QAAI,CAAC,OAAO,IAAI,IAAI,GAAG;AACrB,aAAO,IAAI,MAAM,CAAC,CAAC;AAAA,IACrB;AACA,WAAO,IAAI,IAAI,EAAG,KAAK,IAAI;AAAA,EAC7B;AAEA,SAAO;AACT;AAEO,SAAS,cAAc,SAA2B;AACvD,QAAM,SAAmB,CAAC;AAC1B,QAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,MAAI,UAAoB,CAAC;AACzB,MAAI,UAAU;AAEd,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI,QAAQ,WAAW,GAAG,KAAK,QAAQ,SAAS,GAAG,GAAG;AACpD,gBAAU;AACV,cAAQ,KAAK,IAAI;AAAA,IACnB,OAAO;AACL,UAAI,WAAW,QAAQ,UAAU,GAAG;AAClC,eAAO,KAAK,QAAQ,KAAK,IAAI,CAAC;AAAA,MAChC;AACA,gBAAU,CAAC;AACX,gBAAU;AAAA,IACZ;AAAA,EACF;AAEA,MAAI,WAAW,QAAQ,UAAU,GAAG;AAClC,WAAO,KAAK,QAAQ,KAAK,IAAI,CAAC;AAAA,EAChC;AAEA,SAAO;AACT;AAQO,SAAS,aAAa,SAAkC;AAC7D,QAAM,QAAyB,CAAC;AAChC,QAAM,QAAQ;AACd,MAAI;AAEJ,UAAQ,QAAQ,MAAM,KAAK,OAAO,OAAO,MAAM;AAC7C,UAAM,OAAO,MAAM,CAAC;AACpB,UAAM,MAAM,MAAM,CAAC;AACnB,QAAI,WAAsC;AAC1C,QAAI,IAAI,SAAS,YAAY,GAAG;AAC9B,iBAAW;AAAA,IACb,WAAW,IAAI,SAAS,WAAW,KAAK,IAAI,SAAS,QAAQ,GAAG;AAC9D,iBAAW;AAAA,IACb;AACA,UAAM,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;AAAA,EACpC;AAEA,SAAO;AACT;AAEO,SAAS,kBAAkB,QAAsD;AACtF,QAAM,SAAS,oBAAI,IAAsB;AACzC,aAAW,CAAC,MAAM,QAAQ,KAAK,QAAQ;AACrC,WAAO,IAAI,MAAM,CAAC,GAAG,IAAI,IAAI,QAAQ,CAAC,CAAC;AAAA,EACzC;AACA,SAAO;AACT;;;AC9DA,IAAM,mBAAmB,CAAC,eAAe,uBAAuB;AAChE,IAAM,2BAA2B;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,kBACd,OACA,QACQ;AACR,QAAM,WAAW,gBAAgB,OAAO,MAAM;AAC9C,QAAM,WAAqB,CAAC;AAG5B,WAAS;AAAA,IACP;AAAA,EACF;AACA,WAAS,KAAK,EAAE;AAChB,WAAS,KAAK,KAAK,OAAO,KAAK,oBAAe;AAG9C,WAAS,KAAK,EAAE;AAChB,WAAS,KAAK,aAAa;AAC3B,WAAS,KAAK,EAAE;AAChB,WAAS,KAAK,OAAO,WAAW;AAGhC,QAAM,iBAAiB,oBAAoB,QAAQ;AACnD,MAAI,gBAAgB;AAClB,aAAS,KAAK,EAAE;AAChB,aAAS,KAAK,0BAA0B;AACxC,aAAS,KAAK,EAAE;AAChB,aAAS,KAAK,cAAc;AAAA,EAC9B;AAGA,QAAM,kBAAkB,qBAAqB,QAAQ;AACrD,MAAI,iBAAiB;AACnB,aAAS,KAAK,EAAE;AAChB,aAAS,KAAK,uBAAuB;AACrC,aAAS,KAAK,EAAE;AAChB,aAAS,KAAK,eAAe;AAAA,EAC/B;AAGA,QAAM,oBAAoB,uBAAuB,QAAQ;AACzD,MAAI,mBAAmB;AACrB,aAAS,KAAK,EAAE;AAChB,aAAS,KAAK,gBAAgB;AAC9B,aAAS,KAAK,EAAE;AAChB,aAAS,KAAK,iBAAiB;AAAA,EACjC;AAGA,QAAM,eAAe,kBAAkB,QAAQ;AAC/C,MAAI,cAAc;AAChB,aAAS,KAAK,EAAE;AAChB,aAAS,KAAK,sBAAsB;AACpC,aAAS,KAAK,EAAE;AAChB,aAAS,KAAK,YAAY;AAAA,EAC5B;AAGA,MAAI,OAAO,iBAAiB,gBAAgB;AAC1C,eAAW,SAAS,OAAO,gBAAgB,gBAAgB;AACzD,eAAS,KAAK,EAAE;AAChB,eAAS,KAAK,MAAM,MAAM,KAAK,EAAE;AACjC,eAAS,KAAK,EAAE;AAChB,eAAS,KAAK,MAAM,OAAO;AAAA,IAC7B;AAAA,EACF;AAEA,SAAO,SAAS,KAAK,IAAI,IAAI;AAC/B;AAEA,SAAS,gBACP,OACA,QACe;AAEf,MAAI,OAAO,iBAAiB,WAAW,QAAQ;AAC7C,UAAM,SAAwB,CAAC;AAC/B,eAAW,MAAM,OAAO,gBAAgB,WAAW;AACjD,YAAM,QAAQ,MAAM;AAAA,QAClB,CAAC,MACC,EAAE,iBAAiB,GAAG,QACtB,EAAE,iBAAiB,GAAG,KAAK,QAAQ,OAAO,GAAG;AAAA,MACjD;AACA,UAAI,OAAO;AACT,eAAO,KAAK,KAAK;AAAA,MACnB;AAAA,IACF;AAEA,QAAI,OAAO,SAAS,GAAG;AACrB,aAAO;AAAA,IACT;AAAA,EACF;AAGA,QAAM,WAAW,eAAe,KAAK;AACrC,MAAI,SAAS,SAAS,GAAG;AACvB,WAAO,SAAS,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,EACnC;AAGA,SAAO;AACT;AAEA,SAAS,oBAAoB,OAAqC;AAChE,QAAM,gBAA0B,CAAC;AAEjC,aAAW,QAAQ,OAAO;AACxB,UAAM,oBAAoB,iBAAiB;AAAA,MAAK,CAAC,MAC/C,EAAE,KAAK,KAAK,OAAO;AAAA,IACrB;AACA,QAAI,CAAC,kBAAmB;AAExB,UAAM,SAAS,cAAc,KAAK,OAAO;AAEzC,eAAW,SAAS,QAAQ;AAC1B,UAAI,iBAAiB,KAAK,CAAC,MAAM,EAAE,KAAK,KAAK,CAAC,GAAG;AAC/C,sBAAc,KAAK,OAAO,KAAK,KAAK;AAAA;AAAA,EAAO,KAAK,EAAE;AAAA,MACpD;AAAA,IACF;AAAA,EACF;AAEA,MAAI,cAAc,WAAW,EAAG,QAAO;AACvC,SAAO,cAAc,KAAK,MAAM;AAClC;AAEA,SAAS,qBAAqB,OAAqC;AACjE,QAAM,gBAA0B,CAAC;AACjC,QAAM,iBAA2B,CAAC;AAElC,aAAW,QAAQ,OAAO;AACxB,UAAM,YAAY,yBAAyB,KAAK,OAAO;AACvD,QAAI,UAAU,WAAW,EAAG;AAG5B,UAAM,SAAS,cAAc,KAAK,OAAO;AACzC,UAAM,sBAAsB,OAAO;AAAA,MAAO,CAAC,MACzC,UAAU,KAAK,CAAC,SAAS,EAAE,SAAS,IAAI,CAAC;AAAA,IAC3C;AAEA,QAAI,oBAAoB,SAAS,GAAG;AAClC,iBAAW,SAAS,qBAAqB;AACvC,sBAAc,KAAK,OAAO,KAAK,KAAK;AAAA;AAAA,EAAO,KAAK,EAAE;AAAA,MACpD;AAAA,IACF,OAAO;AAEL,iBAAW,QAAQ,WAAW;AAC5B,uBAAe,KAAK,OAAO,IAAI,IAAI;AAAA,MACrC;AAAA,IACF;AAAA,EACF;AAEA,MAAI,cAAc,WAAW,KAAK,eAAe,WAAW,EAAG,QAAO;AAEtE,QAAM,QAAkB,CAAC;AACzB,MAAI,cAAc,SAAS,GAAG;AAC5B,UAAM,KAAK,cAAc,KAAK,MAAM,CAAC;AAAA,EACvC;AACA,MAAI,eAAe,SAAS,GAAG;AAC7B,UAAM,KAAK,CAAC,GAAG,IAAI,IAAI,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;AAAA,EACpD;AACA,SAAO,MAAM,KAAK,MAAM;AAC1B;AAEA,SAAS,uBAAuB,OAAqC;AACnE,QAAM,YAAY,oBAAI,IAAsB;AAE5C,aAAW,QAAQ,OAAO;AACxB,UAAM,YAAY,KAAK,aAAa,YAAY;AAChD,UAAM,aAAa,KAAK,MAAM,YAAY;AAC1C,UAAM,mBACJ,yBAAyB,KAAK,CAAC,OAAO,UAAU,SAAS,EAAE,CAAC,KAC5D,yBAAyB,KAAK,CAAC,OAAO,WAAW,SAAS,EAAE,CAAC;AAE/D,QAAI,CAAC,iBAAkB;AAEvB,UAAM,SAAS,kBAAkB,KAAK,OAAO;AAC7C,eAAW,CAAC,MAAM,QAAQ,KAAK,QAAQ;AACrC,UAAI,CAAC,UAAU,IAAI,IAAI,GAAG;AACxB,kBAAU,IAAI,MAAM,CAAC,CAAC;AAAA,MACxB;AACA,gBAAU,IAAI,IAAI,EAAG,KAAK,GAAG,QAAQ;AAAA,IACvC;AAAA,EACF;AAEA,MAAI,UAAU,SAAS,EAAG,QAAO;AAEjC,QAAM,eAAe,kBAAkB,SAAS;AAChD,QAAM,QAAkB,CAAC;AAEzB,aAAW,CAAC,MAAM,QAAQ,KAAK,cAAc;AAC3C,eAAW,QAAQ,UAAU;AAC3B,YAAM,KAAK,SAAS,IAAI;AAAA,EAAK,IAAI;AAAA,OAAU;AAAA,IAC7C;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,MAAM;AAC1B;AAEA,SAAS,kBAAkB,OAAqC;AAC9D,QAAM,WAA4B,CAAC;AAEnC,aAAW,QAAQ,OAAO;AACxB,UAAM,QAAQ,aAAa,KAAK,OAAO;AACvC,aAAS,KAAK,GAAG,KAAK;AAAA,EACxB;AAEA,MAAI,SAAS,WAAW,EAAG,QAAO;AAGlC,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,SAA0B,CAAC;AACjC,aAAW,QAAQ,UAAU;AAC3B,QAAI,CAAC,KAAK,IAAI,KAAK,GAAG,GAAG;AACvB,WAAK,IAAI,KAAK,GAAG;AACjB,aAAO,KAAK,IAAI;AAAA,IAClB;AAAA,EACF;AAGA,QAAM,SAAS,OAAO,OAAO,CAAC,MAAM,EAAE,aAAa,QAAQ;AAC3D,QAAM,MAAM,OAAO,OAAO,CAAC,MAAM,EAAE,aAAa,KAAK;AACrD,QAAM,WAAW,OAAO,OAAO,CAAC,MAAM,EAAE,aAAa,UAAU;AAE/D,QAAM,QAAkB,CAAC;AAEzB,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,KAAK,YAAY;AACvB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,GAAG,OAAO,IAAI,CAAC,MAAM,MAAM,EAAE,IAAI,KAAK,EAAE,GAAG,GAAG,CAAC;AAAA,EAC5D;AAEA,MAAI,IAAI,SAAS,GAAG;AAClB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,SAAS;AACpB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,GAAG,IAAI,IAAI,CAAC,MAAM,MAAM,EAAE,IAAI,KAAK,EAAE,GAAG,GAAG,CAAC;AAAA,EACzD;AAEA,MAAI,SAAS,SAAS,GAAG;AACvB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,cAAc;AACzB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,GAAG,SAAS,IAAI,CAAC,MAAM,MAAM,EAAE,IAAI,KAAK,EAAE,GAAG,GAAG,CAAC;AAAA,EAC9D;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
@@ -2186,8 +2186,30 @@ async function generateCommand(options = {}) {
2186
2186
  log.success(`Generated llms-full.txt (${formatTokens(estimateTokens(llmsFullTxt))})`);
2187
2187
  }
2188
2188
  }
2189
+ if (config.generate.ai_context && options.only !== "llms-txt" && options.only !== "llms-full") {
2190
+ const { generateAiContext } = await import("./ai-context-QVGQK3GD.js");
2191
+ const aiContext = generateAiContext(pages, {
2192
+ title: config.title,
2193
+ description: config.description,
2194
+ aiContextConfig: config.generate.ai_context_config ? {
2195
+ key_pages: config.generate.ai_context_config.key_pages,
2196
+ extra_sections: config.generate.ai_context_config.extra_sections?.map((s) => ({
2197
+ title: s.title,
2198
+ content: s.source ?? ""
2199
+ }))
2200
+ } : void 0
2201
+ });
2202
+ if (options.dryRun) {
2203
+ log.info("[dry-run] Would write ai-context.md");
2204
+ log.dim(` ${aiContext.length} chars, ${formatTokens(estimateTokens(aiContext))}`);
2205
+ } else {
2206
+ await fs3.mkdir(outputDir, { recursive: true });
2207
+ await fs3.writeFile(path5.join(outputDir, "ai-context.md"), aiContext, "utf-8");
2208
+ log.success(`Generated ai-context.md (${formatTokens(estimateTokens(aiContext))})`);
2209
+ }
2210
+ }
2189
2211
  }
2190
2212
  export {
2191
2213
  generateCommand
2192
2214
  };
2193
- //# sourceMappingURL=generate-56HFRN5I.js.map
2215
+ //# sourceMappingURL=generate-LDVEG2WV.js.map