@riotprompt/riotprompt 0.0.2 → 0.0.4

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 (53) hide show
  1. package/.cursor/rules/focus-on-prompt.mdc +5 -0
  2. package/README.md +65 -492
  3. package/dist/builder.d.ts +3 -3
  4. package/dist/builder.js +9 -4
  5. package/dist/builder.js.map +1 -1
  6. package/dist/chat.js.map +1 -1
  7. package/dist/constants.js.map +1 -1
  8. package/dist/formatter.js.map +1 -1
  9. package/dist/items/content.js.map +1 -1
  10. package/dist/items/context.js.map +1 -1
  11. package/dist/items/instruction.js.map +1 -1
  12. package/dist/items/parameters.js.map +1 -1
  13. package/dist/items/section.js.map +1 -1
  14. package/dist/items/trait.js.map +1 -1
  15. package/dist/items/weighted.js.map +1 -1
  16. package/dist/loader.js +1 -0
  17. package/dist/loader.js.map +1 -1
  18. package/dist/logger.js.map +1 -1
  19. package/dist/override.d.ts +5 -5
  20. package/dist/override.js +47 -30
  21. package/dist/override.js.map +1 -1
  22. package/dist/parse/markdown.d.ts +1 -1
  23. package/dist/parse/markdown.js +3 -2
  24. package/dist/parse/markdown.js.map +1 -1
  25. package/dist/parse/text.js.map +1 -1
  26. package/dist/parser.d.ts +1 -1
  27. package/dist/parser.js +3 -3
  28. package/dist/parser.js.map +1 -1
  29. package/dist/prompt.js.map +1 -1
  30. package/dist/recipes.d.ts +373 -0
  31. package/dist/recipes.js +279 -0
  32. package/dist/recipes.js.map +1 -0
  33. package/dist/riotprompt.cjs +340 -40
  34. package/dist/riotprompt.cjs.map +1 -1
  35. package/dist/riotprompt.d.ts +3 -0
  36. package/dist/riotprompt.js +3 -0
  37. package/dist/riotprompt.js.map +1 -1
  38. package/dist/util/general.js.map +1 -1
  39. package/dist/util/markdown.js.map +1 -1
  40. package/dist/util/storage.js.map +1 -1
  41. package/dist/util/text.js.map +1 -1
  42. package/package.json +29 -24
  43. package/.gitcarve/config.yaml +0 -10
  44. package/.gitcarve/context/content.md +0 -11
  45. package/.markdown-doctest-setup.mjs +0 -23
  46. package/.nvmrc +0 -1
  47. package/docs/loader.md +0 -237
  48. package/docs/override.md +0 -323
  49. package/docs/parser.md +0 -130
  50. package/eslint.config.mjs +0 -82
  51. package/nodemon.json +0 -14
  52. package/vite.config.ts +0 -114
  53. package/vitest.config.ts +0 -25
@@ -5,7 +5,6 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
5
5
  const zod = require('zod');
6
6
  const fs = require('fs/promises');
7
7
  const path = require('path');
8
- const marked = require('marked');
9
8
  const fs$1 = require('fs');
10
9
  const glob = require('glob');
11
10
  const crypto = require('crypto');
@@ -495,7 +494,9 @@ const formatter = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty(
495
494
  create: create$5
496
495
  }, Symbol.toStringTag, { value: 'Module' }));
497
496
 
498
- const parseMarkdown = (input, options = {})=>{
497
+ const parseMarkdown = async (input, options = {})=>{
498
+ // Dynamic import for marked (ES module)
499
+ const { marked } = await import('marked');
499
500
  let markdownContent;
500
501
  if (typeof input === 'string') {
501
502
  markdownContent = input;
@@ -504,7 +505,7 @@ const parseMarkdown = (input, options = {})=>{
504
505
  }
505
506
  const sectionOptions = SectionOptionsSchema.parse(options);
506
507
  // Use marked.lexer to get tokens without full parsing/rendering
507
- const tokens = marked.marked.lexer(markdownContent);
508
+ const tokens = marked.lexer(markdownContent);
508
509
  // Create the main section (with a Title from the options)
509
510
  const mainSection = create$8(sectionOptions);
510
511
  // Track sections at each depth level
@@ -788,7 +789,7 @@ const create$4 = (parserOptions)=>{
788
789
  const content = await fs__namespace.readFile(filePath, 'utf-8');
789
790
  // Only use the filename as title if no title was explicitly provided
790
791
  const fileName = path__namespace.basename(filePath, path__namespace.extname(filePath));
791
- return parse(content, {
792
+ return await parse(content, {
792
793
  ...currentOptions,
793
794
  title: (currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.title) || fileName
794
795
  });
@@ -808,11 +809,11 @@ const create$4 = (parserOptions)=>{
808
809
  *
809
810
  * @param content The content to parse
810
811
  * @returns A Section containing all content in a hierarchical structure
811
- */ const parse = (content, options = {})=>{
812
+ */ const parse = async (content, options = {})=>{
812
813
  const currentOptions = loadOptions(options);
813
814
  let mainSection;
814
815
  if (isMarkdown(content)) {
815
- mainSection = parseMarkdown(content, currentOptions);
816
+ mainSection = await parseMarkdown(content, currentOptions);
816
817
  } else if (isText(content)) {
817
818
  mainSection = parseText(content, currentOptions);
818
819
  } else {
@@ -1111,7 +1112,9 @@ const loader = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
1111
1112
 
1112
1113
  const OptionsSchema = zod.z.object({
1113
1114
  logger: zod.z.any().optional().default(DEFAULT_LOGGER),
1114
- configDir: zod.z.string().default('./overrides'),
1115
+ configDirs: zod.z.array(zod.z.string()).default([
1116
+ './overrides'
1117
+ ]),
1115
1118
  overrides: zod.z.boolean().default(false),
1116
1119
  parameters: ParametersSchema.optional().default({})
1117
1120
  });
@@ -1134,42 +1137,54 @@ const create$1 = (overrideOptions = {})=>{
1134
1137
  };
1135
1138
  const override = async (overrideFile, section, sectionOptions = {})=>{
1136
1139
  const currentSectionOptions = loadOptions(sectionOptions);
1137
- const baseFile = path.join(options.configDir, overrideFile);
1138
- const preFile = baseFile.replace('.md', '-pre.md');
1139
- const postFile = baseFile.replace('.md', '-post.md');
1140
- const response = {};
1141
- if (await storage.exists(preFile)) {
1142
- logger.silly('Found pre file %s', preFile);
1143
- const parser$1 = create$4({
1144
- logger
1145
- });
1146
- response.prepend = await parser$1.parseFile(preFile, currentSectionOptions);
1147
- }
1148
- if (await storage.exists(postFile)) {
1149
- logger.silly('Found post file %s', postFile);
1150
- const parser$1 = create$4({
1151
- logger
1152
- });
1153
- response.append = await parser$1.parseFile(postFile, currentSectionOptions);
1154
- }
1155
- if (await storage.exists(baseFile)) {
1156
- logger.silly('Found base file %s', baseFile);
1157
- if (options.overrides) {
1158
- logger.warn('WARNING: Core directives are being overwritten by custom configuration');
1140
+ const response = {
1141
+ prepends: [],
1142
+ appends: []
1143
+ };
1144
+ // Process directories in order (closest to furthest)
1145
+ for(let i = 0; i < options.configDirs.length; i++){
1146
+ const configDir = options.configDirs[i];
1147
+ const baseFile = path.join(configDir, overrideFile);
1148
+ const preFile = baseFile.replace('.md', '-pre.md');
1149
+ const postFile = baseFile.replace('.md', '-post.md');
1150
+ // Check for prepend files (-pre.md)
1151
+ if (await storage.exists(preFile)) {
1152
+ logger.silly('Found pre file %s (layer %d)', preFile, i + 1);
1159
1153
  const parser$1 = create$4({
1160
1154
  logger
1161
1155
  });
1162
- response.override = await parser$1.parseFile(baseFile, currentSectionOptions);
1163
- } else {
1164
- logger.error('ERROR: Core directives are being overwritten by custom configuration');
1165
- throw new Error('Core directives are being overwritten by custom configuration, but overrides are not enabled. Please enable --overrides to use this feature.');
1156
+ const prependSection = await parser$1.parseFile(preFile, currentSectionOptions);
1157
+ response.prepends.push(prependSection);
1158
+ }
1159
+ // Check for append files (-post.md)
1160
+ if (await storage.exists(postFile)) {
1161
+ logger.silly('Found post file %s (layer %d)', postFile, i + 1);
1162
+ const parser$1 = create$4({
1163
+ logger
1164
+ });
1165
+ const appendSection = await parser$1.parseFile(postFile, currentSectionOptions);
1166
+ response.appends.push(appendSection);
1167
+ }
1168
+ // Check for complete override files - use the first (closest) one found
1169
+ if (!response.override && await storage.exists(baseFile)) {
1170
+ logger.silly('Found base file %s (layer %d)', baseFile, i + 1);
1171
+ if (options.overrides) {
1172
+ logger.warn('WARNING: Core directives are being overwritten by custom configuration at layer %d', i + 1);
1173
+ const parser$1 = create$4({
1174
+ logger
1175
+ });
1176
+ response.override = await parser$1.parseFile(baseFile, currentSectionOptions);
1177
+ } else {
1178
+ logger.error('ERROR: Core directives are being overwritten by custom configuration');
1179
+ throw new Error('Core directives are being overwritten by custom configuration, but overrides are not enabled. Please enable --overrides to use this feature.');
1180
+ }
1166
1181
  }
1167
1182
  }
1168
1183
  return response;
1169
1184
  };
1170
1185
  const customize = async (overrideFile, section, sectionOptions = {})=>{
1171
1186
  const currentSectionOptions = loadOptions(sectionOptions);
1172
- const { overrideContent, prepend, append } = await override(overrideFile, section, currentSectionOptions);
1187
+ const { override: overrideContent, prepends, appends } = await override(overrideFile, section, currentSectionOptions);
1173
1188
  let finalSection = section;
1174
1189
  if (overrideContent) {
1175
1190
  if (options.overrides) {
@@ -1180,11 +1195,13 @@ const create$1 = (overrideOptions = {})=>{
1180
1195
  throw new Error('Core directives are being overwritten by custom configuration, but overrides are not enabled. Please enable --overrides to use this feature.');
1181
1196
  }
1182
1197
  }
1183
- if (prepend) {
1198
+ // Apply prepends in order (closest layer first)
1199
+ for (const prepend of prepends){
1184
1200
  logger.silly('Prepend found, adding to content from file %s', prepend);
1185
1201
  finalSection = finalSection.prepend(prepend);
1186
1202
  }
1187
- if (append) {
1203
+ // Apply appends in reverse order (furthest layers first, then closest)
1204
+ for (const append of appends.reverse()){
1188
1205
  logger.silly('Append found, adding to content from file %s', append);
1189
1206
  finalSection = finalSection.append(append);
1190
1207
  }
@@ -1208,7 +1225,9 @@ const override = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
1208
1225
  const OptionSchema = zod.z.object({
1209
1226
  logger: zod.z.any().optional().default(DEFAULT_LOGGER),
1210
1227
  basePath: zod.z.string(),
1211
- overridePath: zod.z.string().optional().default("./"),
1228
+ overridePaths: zod.z.array(zod.z.string()).optional().default([
1229
+ "./"
1230
+ ]),
1212
1231
  overrides: zod.z.boolean().optional().default(false),
1213
1232
  parameters: ParametersSchema.optional().default({})
1214
1233
  });
@@ -1220,7 +1239,9 @@ const create = (builderOptions)=>{
1220
1239
  });
1221
1240
  const override$1 = create$1({
1222
1241
  logger,
1223
- configDir: options.overridePath || "./",
1242
+ configDirs: options.overridePaths || [
1243
+ "./"
1244
+ ],
1224
1245
  overrides: options.overrides || false
1225
1246
  });
1226
1247
  const loader$1 = create$2({
@@ -1312,7 +1333,7 @@ const create = (builderOptions)=>{
1312
1333
  const addContent = async (content, sectionOptions = {})=>{
1313
1334
  logger.debug("Adding content", typeof content);
1314
1335
  const currentOptions = loadOptions(sectionOptions);
1315
- const parsedContentSection = parser$1.parse(content, currentOptions);
1336
+ const parsedContentSection = await parser$1.parse(content, currentOptions);
1316
1337
  contentSection.add(parsedContentSection);
1317
1338
  return instance;
1318
1339
  };
@@ -1320,7 +1341,7 @@ const create = (builderOptions)=>{
1320
1341
  const addContext = async (context, sectionOptions = {})=>{
1321
1342
  logger.debug("Adding context", typeof context);
1322
1343
  const currentOptions = loadOptions(sectionOptions);
1323
- const parsedContextSection = parser$1.parse(context, currentOptions);
1344
+ const parsedContextSection = await parser$1.parse(context, currentOptions);
1324
1345
  contextSection.add(parsedContextSection);
1325
1346
  return instance;
1326
1347
  };
@@ -1344,12 +1365,288 @@ const builder = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
1344
1365
  create
1345
1366
  }, Symbol.toStringTag, { value: 'Module' }));
1346
1367
 
1368
+ // ===== CONFIGURATION SCHEMAS =====
1369
+ const ContentItemSchema = zod.z.union([
1370
+ zod.z.string(),
1371
+ zod.z.object({
1372
+ content: zod.z.string(),
1373
+ title: zod.z.string().optional(),
1374
+ weight: zod.z.number().optional()
1375
+ }),
1376
+ zod.z.object({
1377
+ path: zod.z.string(),
1378
+ title: zod.z.string().optional(),
1379
+ weight: zod.z.number().optional()
1380
+ }),
1381
+ zod.z.object({
1382
+ directories: zod.z.array(zod.z.string()),
1383
+ title: zod.z.string().optional(),
1384
+ weight: zod.z.number().optional()
1385
+ })
1386
+ ]);
1387
+ const RecipeConfigSchema = zod.z.object({
1388
+ // Core settings
1389
+ basePath: zod.z.string(),
1390
+ logger: zod.z.any().optional().default(DEFAULT_LOGGER),
1391
+ overridePaths: zod.z.array(zod.z.string()).optional().default([
1392
+ "./"
1393
+ ]),
1394
+ overrides: zod.z.boolean().optional().default(false),
1395
+ parameters: ParametersSchema.optional().default({}),
1396
+ // Content sections
1397
+ persona: ContentItemSchema.optional(),
1398
+ instructions: zod.z.array(ContentItemSchema).optional().default([]),
1399
+ content: zod.z.array(ContentItemSchema).optional().default([]),
1400
+ context: zod.z.array(ContentItemSchema).optional().default([]),
1401
+ // Templates and inheritance
1402
+ extends: zod.z.string().optional(),
1403
+ template: zod.z.string().optional()
1404
+ });
1405
+ // User-customizable template registry
1406
+ let TEMPLATES = {};
1407
+ /**
1408
+ * Register custom templates with the recipes system
1409
+ *
1410
+ * @example
1411
+ * ```typescript
1412
+ * // Register your own templates
1413
+ * registerTemplates({
1414
+ * myWorkflow: {
1415
+ * persona: { path: "personas/my-persona.md" },
1416
+ * instructions: [{ path: "instructions/my-instructions.md" }]
1417
+ * },
1418
+ * anotherTemplate: {
1419
+ * persona: { content: "You are a helpful assistant" },
1420
+ * instructions: [{ content: "Follow these steps..." }]
1421
+ * }
1422
+ * });
1423
+ * ```
1424
+ */ const registerTemplates = (templates)=>{
1425
+ TEMPLATES = {
1426
+ ...TEMPLATES,
1427
+ ...templates
1428
+ };
1429
+ };
1430
+ /**
1431
+ * Get currently registered templates
1432
+ */ const getTemplates = ()=>({
1433
+ ...TEMPLATES
1434
+ });
1435
+ /**
1436
+ * Clear all registered templates
1437
+ */ const clearTemplates = ()=>{
1438
+ TEMPLATES = {};
1439
+ };
1440
+ // ===== CORE RECIPE ENGINE =====
1441
+ const cook = async (config)=>{
1442
+ // Parse and validate configuration with defaults
1443
+ const validatedConfig = RecipeConfigSchema.parse({
1444
+ overridePaths: [
1445
+ "./"
1446
+ ],
1447
+ overrides: false,
1448
+ parameters: {},
1449
+ instructions: [],
1450
+ content: [],
1451
+ context: [],
1452
+ ...config
1453
+ });
1454
+ // Handle template inheritance
1455
+ let finalConfig = {
1456
+ ...validatedConfig
1457
+ };
1458
+ if (validatedConfig.template) {
1459
+ const template = TEMPLATES[validatedConfig.template];
1460
+ if (template) {
1461
+ finalConfig = {
1462
+ ...validatedConfig,
1463
+ persona: validatedConfig.persona || template.persona,
1464
+ instructions: [
1465
+ ...template.instructions || [],
1466
+ ...validatedConfig.instructions || []
1467
+ ],
1468
+ content: [
1469
+ ...template.content || [],
1470
+ ...validatedConfig.content || []
1471
+ ],
1472
+ context: [
1473
+ ...template.context || [],
1474
+ ...validatedConfig.context || []
1475
+ ]
1476
+ };
1477
+ }
1478
+ }
1479
+ // Setup internal services
1480
+ const logger = wrapLogger(finalConfig.logger, 'Recipe');
1481
+ const parser$1 = create$4({
1482
+ logger
1483
+ });
1484
+ const override$1 = create$1({
1485
+ logger,
1486
+ configDirs: finalConfig.overridePaths || [
1487
+ "./"
1488
+ ],
1489
+ overrides: finalConfig.overrides || false
1490
+ });
1491
+ const loader$1 = create$2({
1492
+ logger
1493
+ });
1494
+ // Create sections
1495
+ const personaSection = create$8({
1496
+ title: "Persona"
1497
+ });
1498
+ const instructionSection = create$8({
1499
+ title: "Instruction"
1500
+ });
1501
+ const contentSection = create$8({
1502
+ title: "Content"
1503
+ });
1504
+ const contextSection = create$8({
1505
+ title: "Context"
1506
+ });
1507
+ // Process persona
1508
+ if (finalConfig.persona) {
1509
+ await processContentItem(finalConfig.persona, personaSection, 'persona', {
1510
+ basePath: finalConfig.basePath,
1511
+ parser: parser$1,
1512
+ override: override$1,
1513
+ loader: loader$1,
1514
+ parameters: finalConfig.parameters});
1515
+ }
1516
+ // Process instructions
1517
+ for (const item of finalConfig.instructions || []){
1518
+ await processContentItem(item, instructionSection, 'instruction', {
1519
+ basePath: finalConfig.basePath,
1520
+ parser: parser$1,
1521
+ override: override$1,
1522
+ loader: loader$1,
1523
+ parameters: finalConfig.parameters});
1524
+ }
1525
+ // Process content
1526
+ for (const item of finalConfig.content || []){
1527
+ await processContentItem(item, contentSection, 'content', {
1528
+ basePath: finalConfig.basePath,
1529
+ parser: parser$1,
1530
+ override: override$1,
1531
+ loader: loader$1,
1532
+ parameters: finalConfig.parameters});
1533
+ }
1534
+ // Process context
1535
+ for (const item of finalConfig.context || []){
1536
+ await processContentItem(item, contextSection, 'context', {
1537
+ basePath: finalConfig.basePath,
1538
+ parser: parser$1,
1539
+ override: override$1,
1540
+ loader: loader$1,
1541
+ parameters: finalConfig.parameters});
1542
+ }
1543
+ // Build and return prompt
1544
+ return create$6({
1545
+ persona: personaSection,
1546
+ instructions: instructionSection,
1547
+ contents: contentSection,
1548
+ contexts: contextSection
1549
+ });
1550
+ };
1551
+ const processContentItem = async (item, section, type, ctx)=>{
1552
+ const sectionOptions = {
1553
+ parameters: ctx.parameters
1554
+ };
1555
+ if (typeof item === 'string') {
1556
+ // Simple string content
1557
+ const parsedSection = ctx.parser.parse(item, sectionOptions);
1558
+ section.add(parsedSection);
1559
+ } else if ('content' in item) {
1560
+ // Inline content with options
1561
+ const parsedSection = ctx.parser.parse(item.content, {
1562
+ ...sectionOptions,
1563
+ title: item.title,
1564
+ weight: item.weight
1565
+ });
1566
+ section.add(parsedSection);
1567
+ } else if ('path' in item) {
1568
+ // File path
1569
+ const fullPath = path.join(ctx.basePath, item.path);
1570
+ const parsedSection = await ctx.parser.parseFile(fullPath, {
1571
+ ...sectionOptions,
1572
+ title: item.title,
1573
+ weight: item.weight
1574
+ });
1575
+ const overrideSection = await ctx.override.customize(item.path, parsedSection, sectionOptions);
1576
+ section.add(overrideSection);
1577
+ } else if ('directories' in item) {
1578
+ // Directory loading
1579
+ const sections = await ctx.loader.load(item.directories, {
1580
+ ...sectionOptions,
1581
+ title: item.title,
1582
+ weight: item.weight
1583
+ });
1584
+ section.add(sections);
1585
+ }
1586
+ };
1587
+ // ===== FLUENT RECIPE BUILDER =====
1588
+ const recipe = (basePath)=>({
1589
+ template: (name)=>({
1590
+ with: (config)=>cook({
1591
+ basePath,
1592
+ template: name,
1593
+ ...config
1594
+ })
1595
+ }),
1596
+ persona: (persona)=>({
1597
+ instructions: (...instructions)=>({
1598
+ content: (...content)=>({
1599
+ context: (...context)=>({
1600
+ cook: ()=>cook({
1601
+ basePath,
1602
+ persona,
1603
+ instructions,
1604
+ content,
1605
+ context
1606
+ })
1607
+ }),
1608
+ cook: ()=>cook({
1609
+ basePath,
1610
+ persona,
1611
+ instructions,
1612
+ content
1613
+ })
1614
+ }),
1615
+ cook: ()=>cook({
1616
+ basePath,
1617
+ persona,
1618
+ instructions
1619
+ })
1620
+ }),
1621
+ cook: ()=>cook({
1622
+ basePath,
1623
+ persona
1624
+ })
1625
+ }),
1626
+ cook: (config)=>cook({
1627
+ basePath,
1628
+ ...config
1629
+ })
1630
+ });
1631
+
1632
+ const recipes = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
1633
+ __proto__: null,
1634
+ clearTemplates,
1635
+ cook,
1636
+ getTemplates,
1637
+ recipe,
1638
+ registerTemplates
1639
+ }, Symbol.toStringTag, { value: 'Module' }));
1640
+
1347
1641
  exports.Builder = builder;
1348
1642
  exports.Chat = chat;
1349
1643
  exports.Formatter = formatter;
1350
1644
  exports.Loader = loader;
1351
1645
  exports.Override = override;
1352
1646
  exports.Parser = parser;
1647
+ exports.Recipes = recipes;
1648
+ exports.clearTemplates = clearTemplates;
1649
+ exports.cook = cook;
1353
1650
  exports.createContent = create$b;
1354
1651
  exports.createContext = create$a;
1355
1652
  exports.createInstruction = create$9;
@@ -1358,4 +1655,7 @@ exports.createPrompt = create$6;
1358
1655
  exports.createSection = create$8;
1359
1656
  exports.createTrait = create$7;
1360
1657
  exports.createWeighted = create$c;
1658
+ exports.getTemplates = getTemplates;
1659
+ exports.recipe = recipe;
1660
+ exports.registerTemplates = registerTemplates;
1361
1661
  //# sourceMappingURL=riotprompt.cjs.map