@voicenter-team/nuxt-llms-generator 0.1.0 → 0.1.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.
- package/README.md +31 -23
- package/dist/chunks/llms-files-generator.mjs +107 -49
- package/dist/module.d.mts +4 -8
- package/dist/module.d.ts +4 -8
- package/dist/module.json +1 -1
- package/dist/module.mjs +1 -1
- package/dist/shared/{nuxt-llms-generator.dc009f50.mjs → nuxt-llms-generator.ab079b9f.mjs} +11 -10
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -63,9 +63,9 @@ flowchart TB
|
|
|
63
63
|
ENV2[🌐 Site 2<br/>SITE_ENV=partner]
|
|
64
64
|
ENV3[🌐 Site 3<br/>SITE_ENV=staging]
|
|
65
65
|
|
|
66
|
-
CACHE1[💾 .llms-
|
|
67
|
-
CACHE2[💾 .llms-
|
|
68
|
-
CACHE3[💾 .llms-
|
|
66
|
+
CACHE1[💾 .llms-templates/main/]
|
|
67
|
+
CACHE2[💾 .llms-templates/partner/]
|
|
68
|
+
CACHE3[💾 .llms-templates/staging/]
|
|
69
69
|
|
|
70
70
|
OUT1[📂 .output/llms/main/]
|
|
71
71
|
OUT2[📂 .output/llms/partner/]
|
|
@@ -140,9 +140,9 @@ flowchart TB
|
|
|
140
140
|
The system automatically adapts to different environments using the `SITE_ENV` variable:
|
|
141
141
|
|
|
142
142
|
```bash
|
|
143
|
-
SITE_ENV=main → UmbracoData-main.json → .llms-
|
|
144
|
-
SITE_ENV=partner → UmbracoData-partner.json → .llms-
|
|
145
|
-
SITE_ENV=staging → UmbracoData-staging.json → .llms-
|
|
143
|
+
SITE_ENV=main → UmbracoData-main.json → .llms-templates/main/ → .output/llms/main/
|
|
144
|
+
SITE_ENV=partner → UmbracoData-partner.json → .llms-templates/partner/ → .output/llms/partner/
|
|
145
|
+
SITE_ENV=staging → UmbracoData-staging.json → .llms-templates/staging/ → .output/llms/staging/
|
|
146
146
|
```
|
|
147
147
|
|
|
148
148
|
Each environment maintains its own isolated cache and output, preventing conflicts while sharing the same codebase and configuration logic.
|
|
@@ -231,18 +231,18 @@ npm run build
|
|
|
231
231
|
|----------------------|----------|----------|------------------|--------------------------------------------|
|
|
232
232
|
| `anthropicApiKey` | `string` | ✅ | - | Your Claude API key from Anthropic |
|
|
233
233
|
| `umbracoDataPath` | `string` | ✅ | - | Path to your UmbracoData.json file |
|
|
234
|
-
| `
|
|
234
|
+
| `templatesDir` | `string` | ❌ | `./.llms-templates` | Directory for templates and cache files |
|
|
235
235
|
| `finalOutputDir` | `string` | ❌ | `./.output/llms` | Output directory for final documentation |
|
|
236
|
-
| `cacheDir` | `string` | ❌ | `./.llms-cache` | Template cache directory |
|
|
237
236
|
|
|
238
237
|
### Generation Options
|
|
239
238
|
|
|
240
|
-
| Option
|
|
241
|
-
|
|
242
|
-
| `enableIndividualMd`
|
|
243
|
-
| `enableLLMSFullTxt`
|
|
244
|
-
| `
|
|
245
|
-
| `
|
|
239
|
+
| Option | Type | Default | Description |
|
|
240
|
+
|------------------------|-----------|------------------------------|------------------------------------------|
|
|
241
|
+
| `enableIndividualMd` | `boolean` | `true` | Generate individual .md files per page |
|
|
242
|
+
| `enableLLMSFullTxt` | `boolean` | `true` | Generate combined llms-full.txt file |
|
|
243
|
+
| `enableHtmlToMarkdown` | `boolean` | `true` | Convert HTML content to markdown using [node-html-markdown](https://www.npmjs.com/package/node-html-markdown) |
|
|
244
|
+
| `maxConcurrent` | `number` | `5` | Maximum concurrent API requests |
|
|
245
|
+
| `anthropicModel` | `string` | `claude-3-5-sonnet-20241022` | Claude model to use |
|
|
246
246
|
|
|
247
247
|
### Cleanup Options
|
|
248
248
|
|
|
@@ -271,9 +271,8 @@ export default defineNuxtConfig({
|
|
|
271
271
|
|
|
272
272
|
// Environment-specific paths
|
|
273
273
|
umbracoDataPath: `./public/UmbracoData-${siteEnv}.json`,
|
|
274
|
-
|
|
274
|
+
templatesDir: `./.llms-templates/${siteEnv}`,
|
|
275
275
|
finalOutputDir: `./.output/llms/${siteEnv}`,
|
|
276
|
-
templatesOutputDir: `./templates/${siteEnv}`,
|
|
277
276
|
|
|
278
277
|
// Shared settings
|
|
279
278
|
maxConcurrent: 5,
|
|
@@ -299,10 +298,10 @@ export default defineNuxtConfig({
|
|
|
299
298
|
|
|
300
299
|
```
|
|
301
300
|
project/
|
|
302
|
-
├── .llms-
|
|
303
|
-
│ ├── main/ # Main site cache
|
|
304
|
-
│ ├── partner/ # Partner site cache
|
|
305
|
-
│ └── staging/ # Staging site cache
|
|
301
|
+
├── .llms-templates/
|
|
302
|
+
│ ├── main/ # Main site templates & cache
|
|
303
|
+
│ ├── partner/ # Partner site templates & cache
|
|
304
|
+
│ └── staging/ # Staging site templates & cache
|
|
306
305
|
├── .output/
|
|
307
306
|
│ └── llms/
|
|
308
307
|
│ ├── main/ # Main site docs
|
|
@@ -518,7 +517,16 @@ ls -la public/UmbracoData.json
|
|
|
518
517
|
{
|
|
519
518
|
enableAutoCleanup: true,
|
|
520
519
|
cleanupOrphaned: true,
|
|
521
|
-
cleanupHidden: true
|
|
520
|
+
cleanupHidden: true,
|
|
521
|
+
enableHtmlToMarkdown: true // Clean HTML from CMS content
|
|
522
|
+
}
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
4. **HTML Content Processing**:
|
|
526
|
+
```typescript
|
|
527
|
+
{
|
|
528
|
+
enableHtmlToMarkdown: true, // Convert <p>, <h1>, etc. to clean markdown
|
|
529
|
+
enableHtmlToMarkdown: false // Keep HTML as-is (if AI already generates clean content)
|
|
522
530
|
}
|
|
523
531
|
```
|
|
524
532
|
|
|
@@ -559,13 +567,13 @@ interface LLMSConfig {
|
|
|
559
567
|
umbracoDataPath: string;
|
|
560
568
|
|
|
561
569
|
// Optional with defaults
|
|
562
|
-
|
|
570
|
+
templatesDir?: string; // './.llms-templates'
|
|
563
571
|
finalOutputDir?: string; // './.output/llms'
|
|
564
|
-
cacheDir?: string; // './.llms-cache'
|
|
565
572
|
anthropicModel?: string; // 'claude-3-5-sonnet-20241022'
|
|
566
573
|
maxConcurrent?: number; // 5
|
|
567
574
|
enableLLMSFullTxt?: boolean; // true
|
|
568
575
|
enableIndividualMd?: boolean; // true
|
|
576
|
+
enableHtmlToMarkdown?: boolean; // true
|
|
569
577
|
enableAutoCleanup?: boolean; // true
|
|
570
578
|
cleanupOrphaned?: boolean; // true
|
|
571
579
|
cleanupHidden?: boolean; // true
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
2
|
-
import { join, dirname } from 'path';
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from 'fs';
|
|
2
|
+
import { join, dirname, basename } from 'path';
|
|
3
3
|
import Mustache from 'mustache';
|
|
4
4
|
import Anthropic from '@anthropic-ai/sdk';
|
|
5
5
|
import { createHash } from 'crypto';
|
|
6
6
|
import { JSONPath } from 'jsonpath-plus';
|
|
7
|
-
import { T as TemplateError, E as ErrorCode, w as withErrorHandling } from '../shared/nuxt-llms-generator.
|
|
7
|
+
import { T as TemplateError, E as ErrorCode, w as withErrorHandling } from '../shared/nuxt-llms-generator.ab079b9f.mjs';
|
|
8
|
+
import { NodeHtmlMarkdown } from 'node-html-markdown';
|
|
8
9
|
import '@nuxt/kit';
|
|
9
10
|
import 'zod';
|
|
10
11
|
|
|
@@ -366,12 +367,14 @@ class PromptAnalyzer {
|
|
|
366
367
|
|
|
367
368
|
class LLMSCache {
|
|
368
369
|
cacheFilePath;
|
|
370
|
+
templatesDir;
|
|
369
371
|
cache = {};
|
|
370
|
-
constructor(
|
|
371
|
-
|
|
372
|
-
|
|
372
|
+
constructor(templatesDir) {
|
|
373
|
+
this.templatesDir = templatesDir;
|
|
374
|
+
if (!existsSync(templatesDir)) {
|
|
375
|
+
mkdirSync(templatesDir, { recursive: true });
|
|
373
376
|
}
|
|
374
|
-
this.cacheFilePath = join(
|
|
377
|
+
this.cacheFilePath = join(templatesDir, "cache.json");
|
|
375
378
|
this.loadCache();
|
|
376
379
|
}
|
|
377
380
|
loadCache() {
|
|
@@ -403,39 +406,95 @@ class LLMSCache {
|
|
|
403
406
|
const cached = this.cache[pageId];
|
|
404
407
|
if (!cached)
|
|
405
408
|
return null;
|
|
409
|
+
const templatePath = join(this.templatesDir, `${pageId}.mustache`);
|
|
410
|
+
let template = "";
|
|
411
|
+
try {
|
|
412
|
+
if (existsSync(templatePath)) {
|
|
413
|
+
template = readFileSync(templatePath, "utf-8");
|
|
414
|
+
} else {
|
|
415
|
+
console.warn(`Template file not found: ${templatePath}`);
|
|
416
|
+
return null;
|
|
417
|
+
}
|
|
418
|
+
} catch (error) {
|
|
419
|
+
console.warn(`Failed to read template file for ${pageId}:`, error);
|
|
420
|
+
return null;
|
|
421
|
+
}
|
|
406
422
|
return {
|
|
407
423
|
pageId,
|
|
408
|
-
templatePath
|
|
409
|
-
template
|
|
410
|
-
|
|
424
|
+
templatePath,
|
|
425
|
+
template,
|
|
426
|
+
structureHash: cached.structureHash,
|
|
427
|
+
metadata: {
|
|
428
|
+
url: cached.pageId,
|
|
429
|
+
// PageContentHash.pageId contains the URL
|
|
430
|
+
templateAlias: cached.templateAlias,
|
|
431
|
+
jpath: cached.jpath,
|
|
432
|
+
generatedAt: new Date(cached.lastUpdated)
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
getTemplateMetadata(pageId) {
|
|
437
|
+
const cached = this.cache[pageId];
|
|
438
|
+
if (!cached)
|
|
439
|
+
return null;
|
|
440
|
+
return {
|
|
441
|
+
structureHash: cached.structureHash,
|
|
411
442
|
metadata: {
|
|
412
|
-
url: cached.
|
|
413
|
-
//
|
|
414
|
-
templateAlias: cached.
|
|
415
|
-
jpath: cached.
|
|
416
|
-
generatedAt: new Date(cached.
|
|
443
|
+
url: cached.pageId,
|
|
444
|
+
// PageContentHash.pageId contains the URL
|
|
445
|
+
templateAlias: cached.templateAlias,
|
|
446
|
+
jpath: cached.jpath,
|
|
447
|
+
generatedAt: new Date(cached.lastUpdated)
|
|
417
448
|
}
|
|
418
449
|
};
|
|
419
450
|
}
|
|
451
|
+
getTemplatePath(pageId) {
|
|
452
|
+
return join(this.templatesDir, `${pageId}.mustache`);
|
|
453
|
+
}
|
|
420
454
|
getTemplateHash(pageId) {
|
|
421
|
-
return this.cache[pageId]?.
|
|
455
|
+
return this.cache[pageId]?.structureHash || null;
|
|
422
456
|
}
|
|
423
|
-
setTemplate(pageId, template,
|
|
457
|
+
setTemplate(pageId, template, structureHash, jpath, templateAlias, url) {
|
|
458
|
+
const templatePath = join(this.templatesDir, `${pageId}.mustache`);
|
|
459
|
+
try {
|
|
460
|
+
writeFileSync(templatePath, template, "utf-8");
|
|
461
|
+
} catch (error) {
|
|
462
|
+
console.error(`Failed to save template file for ${pageId}:`, error);
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
424
465
|
this.cache[pageId] = {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
466
|
+
pageId: url,
|
|
467
|
+
// Store URL in pageId field for backwards compatibility
|
|
468
|
+
jpath,
|
|
469
|
+
templateAlias,
|
|
470
|
+
structureHash,
|
|
471
|
+
lastUpdated: /* @__PURE__ */ new Date()
|
|
431
472
|
};
|
|
432
473
|
this.saveCache();
|
|
433
474
|
}
|
|
434
475
|
removeTemplate(pageId) {
|
|
476
|
+
const templatePath = join(this.templatesDir, `${pageId}.mustache`);
|
|
477
|
+
try {
|
|
478
|
+
if (existsSync(templatePath)) {
|
|
479
|
+
unlinkSync(templatePath);
|
|
480
|
+
}
|
|
481
|
+
} catch (error) {
|
|
482
|
+
console.warn(`Failed to remove template file for ${pageId}:`, error);
|
|
483
|
+
}
|
|
435
484
|
delete this.cache[pageId];
|
|
436
485
|
this.saveCache();
|
|
437
486
|
}
|
|
438
487
|
clearCache() {
|
|
488
|
+
for (const pageId of Object.keys(this.cache)) {
|
|
489
|
+
const templatePath = join(this.templatesDir, `${pageId}.mustache`);
|
|
490
|
+
try {
|
|
491
|
+
if (existsSync(templatePath)) {
|
|
492
|
+
unlinkSync(templatePath);
|
|
493
|
+
}
|
|
494
|
+
} catch (error) {
|
|
495
|
+
console.warn(`Failed to remove template file for ${pageId}:`, error);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
439
498
|
this.cache = {};
|
|
440
499
|
this.saveCache();
|
|
441
500
|
}
|
|
@@ -445,9 +504,9 @@ class LLMSCache {
|
|
|
445
504
|
let oldestTemplate = null;
|
|
446
505
|
let newestTemplate = null;
|
|
447
506
|
for (const template of templates) {
|
|
448
|
-
const alias = template.
|
|
507
|
+
const alias = template.templateAlias;
|
|
449
508
|
templatesByAlias[alias] = (templatesByAlias[alias] || 0) + 1;
|
|
450
|
-
const date = new Date(template.
|
|
509
|
+
const date = new Date(template.lastUpdated);
|
|
451
510
|
if (!oldestTemplate || date < oldestTemplate) {
|
|
452
511
|
oldestTemplate = date;
|
|
453
512
|
}
|
|
@@ -466,9 +525,9 @@ class LLMSCache {
|
|
|
466
525
|
const cutoffDate = new Date(Date.now() - maxAgeMs);
|
|
467
526
|
let removedCount = 0;
|
|
468
527
|
for (const [pageId, template] of Object.entries(this.cache)) {
|
|
469
|
-
const templateDate = new Date(template.
|
|
528
|
+
const templateDate = new Date(template.lastUpdated);
|
|
470
529
|
if (templateDate < cutoffDate) {
|
|
471
|
-
|
|
530
|
+
this.removeTemplate(pageId);
|
|
472
531
|
removedCount++;
|
|
473
532
|
}
|
|
474
533
|
}
|
|
@@ -650,8 +709,8 @@ function getPageVisibilityStats(umbracoData) {
|
|
|
650
709
|
|
|
651
710
|
class TemplateCleanup {
|
|
652
711
|
cache;
|
|
653
|
-
constructor(
|
|
654
|
-
this.cache = new LLMSCache(
|
|
712
|
+
constructor(templatesDir) {
|
|
713
|
+
this.cache = new LLMSCache(templatesDir);
|
|
655
714
|
}
|
|
656
715
|
/**
|
|
657
716
|
* Find templates that no longer have corresponding pages
|
|
@@ -1067,15 +1126,16 @@ class TemplateGenerator {
|
|
|
1067
1126
|
promptAnalyzer;
|
|
1068
1127
|
cache;
|
|
1069
1128
|
config;
|
|
1129
|
+
nhm = new NodeHtmlMarkdown(
|
|
1130
|
+
{},
|
|
1131
|
+
void 0,
|
|
1132
|
+
void 0
|
|
1133
|
+
);
|
|
1070
1134
|
constructor(config) {
|
|
1071
1135
|
this.config = config;
|
|
1072
1136
|
this.anthropicClient = new AnthropicClient(config);
|
|
1073
1137
|
this.promptAnalyzer = new PromptAnalyzer();
|
|
1074
|
-
|
|
1075
|
-
this.cache = new LLMSCache(config.cacheDir);
|
|
1076
|
-
} else {
|
|
1077
|
-
this.cache = new LLMSCache(".llms-cache");
|
|
1078
|
-
}
|
|
1138
|
+
this.cache = new LLMSCache(config.templatesDir || "./.llms-templates");
|
|
1079
1139
|
this.ensureOutputDirectories();
|
|
1080
1140
|
}
|
|
1081
1141
|
async generateTemplate(pageContent, urlItem) {
|
|
@@ -1094,7 +1154,7 @@ class TemplateGenerator {
|
|
|
1094
1154
|
async generateAllTemplates(umbracoData) {
|
|
1095
1155
|
const templates = [];
|
|
1096
1156
|
const maxConcurrent = this.config.maxConcurrent || 5;
|
|
1097
|
-
await performAutomaticCleanup(umbracoData, this.config.
|
|
1157
|
+
await performAutomaticCleanup(umbracoData, this.config.templatesDir || "./.llms-templates", {
|
|
1098
1158
|
enableAutoCleanup: this.config.enableAutoCleanup ?? true,
|
|
1099
1159
|
cleanupOrphaned: this.config.cleanupOrphaned ?? true,
|
|
1100
1160
|
cleanupHidden: this.config.cleanupHidden ?? true,
|
|
@@ -1183,7 +1243,7 @@ class TemplateGenerator {
|
|
|
1183
1243
|
const response = await this.anthropicClient.generateTemplate(request);
|
|
1184
1244
|
const currentHash = generatePageStructureHash(pageContent, { excludeChildren: true });
|
|
1185
1245
|
const templatePath = join(
|
|
1186
|
-
this.config.
|
|
1246
|
+
this.config.templatesDir,
|
|
1187
1247
|
`${pageId}.mustache`
|
|
1188
1248
|
);
|
|
1189
1249
|
this.saveTemplate(templatePath, response.template);
|
|
@@ -1191,7 +1251,7 @@ class TemplateGenerator {
|
|
|
1191
1251
|
pageId,
|
|
1192
1252
|
templatePath,
|
|
1193
1253
|
template: response.template,
|
|
1194
|
-
|
|
1254
|
+
structureHash: currentHash,
|
|
1195
1255
|
metadata: {
|
|
1196
1256
|
url: urlItem.url,
|
|
1197
1257
|
templateAlias: urlItem.TemplateAlias,
|
|
@@ -1199,19 +1259,17 @@ class TemplateGenerator {
|
|
|
1199
1259
|
generatedAt: /* @__PURE__ */ new Date()
|
|
1200
1260
|
}
|
|
1201
1261
|
};
|
|
1202
|
-
this.cache.setTemplate(pageId, response.template, currentHash,
|
|
1203
|
-
pageId: urlItem.url,
|
|
1204
|
-
// Store URL as pageId for cache lookup
|
|
1205
|
-
jpath: urlItem.Jpath,
|
|
1206
|
-
templateAlias: urlItem.TemplateAlias,
|
|
1207
|
-
structureHash: currentHash
|
|
1208
|
-
});
|
|
1262
|
+
this.cache.setTemplate(pageId, response.template, currentHash, urlItem.Jpath, urlItem.TemplateAlias, urlItem.url);
|
|
1209
1263
|
return generatedTemplate;
|
|
1210
1264
|
}
|
|
1211
1265
|
async renderTemplate(template, data) {
|
|
1212
1266
|
return withErrorHandling(async () => {
|
|
1213
1267
|
const validatedTemplate = await templateValidationPipeline.validateAndFix(template);
|
|
1214
|
-
|
|
1268
|
+
const renderedContent = Mustache.render(validatedTemplate, data);
|
|
1269
|
+
if (this.config.enableHtmlToMarkdown) {
|
|
1270
|
+
return this.nhm.translate(renderedContent);
|
|
1271
|
+
}
|
|
1272
|
+
return renderedContent;
|
|
1215
1273
|
}, {
|
|
1216
1274
|
template: template.substring(0, 200) + "...",
|
|
1217
1275
|
dataKeys: Object.keys(data)
|
|
@@ -1241,8 +1299,8 @@ class TemplateGenerator {
|
|
|
1241
1299
|
writeFileSync(templatePath, content, "utf-8");
|
|
1242
1300
|
}
|
|
1243
1301
|
ensureOutputDirectories() {
|
|
1244
|
-
if (!existsSync(this.config.
|
|
1245
|
-
mkdirSync(this.config.
|
|
1302
|
+
if (!existsSync(this.config.templatesDir || "./.llms-templates")) {
|
|
1303
|
+
mkdirSync(this.config.templatesDir || "./.llms-templates", { recursive: true });
|
|
1246
1304
|
}
|
|
1247
1305
|
if (this.config.finalOutputDir && !existsSync(this.config.finalOutputDir)) {
|
|
1248
1306
|
mkdirSync(this.config.finalOutputDir, { recursive: true });
|
|
@@ -1502,8 +1560,8 @@ class LLMSFilesGenerator {
|
|
|
1502
1560
|
return filename;
|
|
1503
1561
|
}
|
|
1504
1562
|
getLLMSFilePath(fullPath) {
|
|
1505
|
-
const filename = fullPath
|
|
1506
|
-
return
|
|
1563
|
+
const filename = basename(fullPath);
|
|
1564
|
+
return `/llms/${filename}`;
|
|
1507
1565
|
}
|
|
1508
1566
|
getOutputDir() {
|
|
1509
1567
|
return this.config.finalOutputDir || "dist";
|
package/dist/module.d.mts
CHANGED
|
@@ -3,9 +3,8 @@ import * as _nuxt_schema from '@nuxt/schema';
|
|
|
3
3
|
interface LLMSConfig {
|
|
4
4
|
anthropicApiKey: string;
|
|
5
5
|
umbracoDataPath: string;
|
|
6
|
-
|
|
6
|
+
templatesDir: string;
|
|
7
7
|
finalOutputDir: string;
|
|
8
|
-
cacheDir?: string;
|
|
9
8
|
anthropicModel?: string;
|
|
10
9
|
maxConcurrent?: number;
|
|
11
10
|
enableLLMSFullTxt?: boolean;
|
|
@@ -13,6 +12,7 @@ interface LLMSConfig {
|
|
|
13
12
|
enableAutoCleanup?: boolean;
|
|
14
13
|
cleanupOrphaned?: boolean;
|
|
15
14
|
cleanupHidden?: boolean;
|
|
15
|
+
enableHtmlToMarkdown?: boolean;
|
|
16
16
|
}
|
|
17
17
|
interface UmbracoUrlItem {
|
|
18
18
|
nodeID: number;
|
|
@@ -54,17 +54,13 @@ interface PageContentHash {
|
|
|
54
54
|
lastUpdated: Date;
|
|
55
55
|
}
|
|
56
56
|
interface TemplateCache {
|
|
57
|
-
[pageId: string]:
|
|
58
|
-
hash: string;
|
|
59
|
-
template: string;
|
|
60
|
-
metadata: PageContentHash;
|
|
61
|
-
};
|
|
57
|
+
[pageId: string]: PageContentHash;
|
|
62
58
|
}
|
|
63
59
|
interface GeneratedTemplate {
|
|
64
60
|
pageId: string;
|
|
65
61
|
templatePath: string;
|
|
66
62
|
template: string;
|
|
67
|
-
|
|
63
|
+
structureHash: string;
|
|
68
64
|
metadata: {
|
|
69
65
|
url: string;
|
|
70
66
|
templateAlias: string;
|
package/dist/module.d.ts
CHANGED
|
@@ -3,9 +3,8 @@ import * as _nuxt_schema from '@nuxt/schema';
|
|
|
3
3
|
interface LLMSConfig {
|
|
4
4
|
anthropicApiKey: string;
|
|
5
5
|
umbracoDataPath: string;
|
|
6
|
-
|
|
6
|
+
templatesDir: string;
|
|
7
7
|
finalOutputDir: string;
|
|
8
|
-
cacheDir?: string;
|
|
9
8
|
anthropicModel?: string;
|
|
10
9
|
maxConcurrent?: number;
|
|
11
10
|
enableLLMSFullTxt?: boolean;
|
|
@@ -13,6 +12,7 @@ interface LLMSConfig {
|
|
|
13
12
|
enableAutoCleanup?: boolean;
|
|
14
13
|
cleanupOrphaned?: boolean;
|
|
15
14
|
cleanupHidden?: boolean;
|
|
15
|
+
enableHtmlToMarkdown?: boolean;
|
|
16
16
|
}
|
|
17
17
|
interface UmbracoUrlItem {
|
|
18
18
|
nodeID: number;
|
|
@@ -54,17 +54,13 @@ interface PageContentHash {
|
|
|
54
54
|
lastUpdated: Date;
|
|
55
55
|
}
|
|
56
56
|
interface TemplateCache {
|
|
57
|
-
[pageId: string]:
|
|
58
|
-
hash: string;
|
|
59
|
-
template: string;
|
|
60
|
-
metadata: PageContentHash;
|
|
61
|
-
};
|
|
57
|
+
[pageId: string]: PageContentHash;
|
|
62
58
|
}
|
|
63
59
|
interface GeneratedTemplate {
|
|
64
60
|
pageId: string;
|
|
65
61
|
templatePath: string;
|
|
66
62
|
template: string;
|
|
67
|
-
|
|
63
|
+
structureHash: string;
|
|
68
64
|
metadata: {
|
|
69
65
|
url: string;
|
|
70
66
|
templateAlias: string;
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -10,16 +10,16 @@ const anthropicApiKey = z.string().min(10, "API key must be at least 10 characte
|
|
|
10
10
|
const LLMSConfigSchema = z.object({
|
|
11
11
|
anthropicApiKey,
|
|
12
12
|
umbracoDataPath: existingPath,
|
|
13
|
-
|
|
13
|
+
templatesDir: z.string().min(1, "Templates directory is required"),
|
|
14
14
|
finalOutputDir: z.string().optional().default("public"),
|
|
15
|
-
cacheDir: z.string().optional().default(".llms-cache"),
|
|
16
15
|
anthropicModel: z.string().optional(),
|
|
17
16
|
maxConcurrent: z.number().int().min(1, "maxConcurrent must be at least 1").max(10, "maxConcurrent should not exceed 10 to avoid rate limits").optional().default(3),
|
|
18
17
|
enableLLMSFullTxt: z.boolean().optional().default(true),
|
|
19
18
|
enableIndividualMd: z.boolean().optional().default(true),
|
|
20
19
|
enableAutoCleanup: z.boolean().optional().default(true),
|
|
21
20
|
cleanupOrphaned: z.boolean().optional().default(true),
|
|
22
|
-
cleanupHidden: z.boolean().optional().default(true)
|
|
21
|
+
cleanupHidden: z.boolean().optional().default(true),
|
|
22
|
+
enableHtmlToMarkdown: z.boolean().optional().default(true)
|
|
23
23
|
}).strict();
|
|
24
24
|
class SchemaValidator {
|
|
25
25
|
static validateConfig(config) {
|
|
@@ -206,11 +206,12 @@ const DEFAULT_OPTIONS = {
|
|
|
206
206
|
maxConcurrent: 5,
|
|
207
207
|
enableLLMSFullTxt: true,
|
|
208
208
|
enableIndividualMd: true,
|
|
209
|
-
|
|
209
|
+
templatesDir: ".llms-templates",
|
|
210
210
|
finalOutputDir: "public",
|
|
211
211
|
enableAutoCleanup: true,
|
|
212
212
|
cleanupOrphaned: true,
|
|
213
|
-
cleanupHidden: true
|
|
213
|
+
cleanupHidden: true,
|
|
214
|
+
enableHtmlToMarkdown: true
|
|
214
215
|
};
|
|
215
216
|
const llmsModule = defineNuxtModule({
|
|
216
217
|
meta: {
|
|
@@ -238,23 +239,23 @@ const llmsModule = defineNuxtModule({
|
|
|
238
239
|
logger.warn("No Umbraco data path provided. LLMS Generator will be disabled.");
|
|
239
240
|
return;
|
|
240
241
|
}
|
|
241
|
-
if (!options.
|
|
242
|
-
logger.warn("No templates
|
|
242
|
+
if (!options.templatesDir) {
|
|
243
|
+
logger.warn("No templates directory provided. LLMS Generator will be disabled.");
|
|
243
244
|
return;
|
|
244
245
|
}
|
|
245
246
|
const configForValidation = {
|
|
246
247
|
anthropicApiKey: options.anthropicApiKey,
|
|
247
248
|
umbracoDataPath: resolve(nuxt.options.rootDir, options.umbracoDataPath),
|
|
248
|
-
|
|
249
|
+
templatesDir: resolve(nuxt.options.rootDir, options.templatesDir),
|
|
249
250
|
finalOutputDir: resolve(nuxt.options.rootDir, options.finalOutputDir ?? "public"),
|
|
250
|
-
cacheDir: options.cacheDir ? resolve(nuxt.options.rootDir, options.cacheDir) : void 0,
|
|
251
251
|
anthropicModel: options.anthropicModel || DEFAULT_OPTIONS.anthropicModel,
|
|
252
252
|
maxConcurrent: options.maxConcurrent || DEFAULT_OPTIONS.maxConcurrent,
|
|
253
253
|
enableLLMSFullTxt: options.enableLLMSFullTxt ?? DEFAULT_OPTIONS.enableLLMSFullTxt,
|
|
254
254
|
enableIndividualMd: options.enableIndividualMd ?? DEFAULT_OPTIONS.enableIndividualMd,
|
|
255
255
|
enableAutoCleanup: options.enableAutoCleanup ?? DEFAULT_OPTIONS.enableAutoCleanup,
|
|
256
256
|
cleanupOrphaned: options.cleanupOrphaned ?? DEFAULT_OPTIONS.cleanupOrphaned,
|
|
257
|
-
cleanupHidden: options.cleanupHidden ?? DEFAULT_OPTIONS.cleanupHidden
|
|
257
|
+
cleanupHidden: options.cleanupHidden ?? DEFAULT_OPTIONS.cleanupHidden,
|
|
258
|
+
enableHtmlToMarkdown: options.enableHtmlToMarkdown ?? DEFAULT_OPTIONS.enableHtmlToMarkdown
|
|
258
259
|
};
|
|
259
260
|
let moduleOptions;
|
|
260
261
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voicenter-team/nuxt-llms-generator",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Nuxt 3 module for automatically generating AI-optimized documentation files (llms.txt, llms-full.txt, and individual .md files) from Umbraco CMS data using Anthropic's Claude API.",
|
|
5
5
|
"repository": "your-org/my-module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -42,8 +42,11 @@
|
|
|
42
42
|
"@anthropic-ai/sdk": "^0.30.0",
|
|
43
43
|
"@nuxt/kit": "^3.11.2",
|
|
44
44
|
"@voicenter-team/eslint-config-ts": "^1.0.22",
|
|
45
|
+
"i": "^0.3.7",
|
|
45
46
|
"jsonpath-plus": "^8.0.0",
|
|
46
47
|
"mustache": "^4.2.0",
|
|
48
|
+
"node-html-markdown": "^1.3.0",
|
|
49
|
+
"npm": "^11.6.0",
|
|
47
50
|
"zod": "^4.1.9"
|
|
48
51
|
},
|
|
49
52
|
"devDependencies": {
|