promptopskit 0.3.9 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/README.md +91 -7
  2. package/SKILL.md +69 -6
  3. package/dist/chunk-5AAYDOPU.js +60 -0
  4. package/dist/chunk-5AAYDOPU.js.map +1 -0
  5. package/dist/{chunk-YNIAA4ZJ.js → chunk-7MRMN3SW.js} +5 -3
  6. package/dist/chunk-7MRMN3SW.js.map +1 -0
  7. package/dist/{chunk-4LEPCCSA.js → chunk-JKBWC5WJ.js} +176 -4
  8. package/dist/chunk-JKBWC5WJ.js.map +1 -0
  9. package/dist/{chunk-AN3OR7YC.js → chunk-MI3M6KDD.js} +7 -5
  10. package/dist/chunk-MI3M6KDD.js.map +1 -0
  11. package/dist/{chunk-LMURMZUA.js → chunk-XL76NHZR.js} +5 -3
  12. package/dist/chunk-XL76NHZR.js.map +1 -0
  13. package/dist/{chunk-V7QY7MRM.js → chunk-YI4LILPY.js} +50 -3
  14. package/dist/chunk-YI4LILPY.js.map +1 -0
  15. package/dist/{chunk-O6RQZYS4.js → chunk-Z4IPWEUU.js} +16 -5
  16. package/dist/chunk-Z4IPWEUU.js.map +1 -0
  17. package/dist/cli/index.js +440 -52
  18. package/dist/cli/index.js.map +1 -1
  19. package/dist/index.cjs +430 -17
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +4 -4
  22. package/dist/index.d.ts +4 -4
  23. package/dist/index.js +162 -10
  24. package/dist/index.js.map +1 -1
  25. package/dist/providers/anthropic.cjs +232 -6
  26. package/dist/providers/anthropic.cjs.map +1 -1
  27. package/dist/providers/anthropic.d.cts +2 -2
  28. package/dist/providers/anthropic.d.ts +2 -2
  29. package/dist/providers/anthropic.js +3 -3
  30. package/dist/providers/gemini.cjs +223 -6
  31. package/dist/providers/gemini.cjs.map +1 -1
  32. package/dist/providers/gemini.d.cts +2 -2
  33. package/dist/providers/gemini.d.ts +2 -2
  34. package/dist/providers/gemini.js +3 -3
  35. package/dist/providers/openai-responses.cjs +221 -4
  36. package/dist/providers/openai-responses.cjs.map +1 -1
  37. package/dist/providers/openai-responses.d.cts +2 -2
  38. package/dist/providers/openai-responses.d.ts +2 -2
  39. package/dist/providers/openai-responses.js +3 -3
  40. package/dist/providers/openai.cjs +221 -4
  41. package/dist/providers/openai.cjs.map +1 -1
  42. package/dist/providers/openai.d.cts +2 -2
  43. package/dist/providers/openai.d.ts +2 -2
  44. package/dist/providers/openai.js +3 -3
  45. package/dist/providers/openrouter.cjs +256 -7
  46. package/dist/providers/openrouter.cjs.map +1 -1
  47. package/dist/providers/openrouter.d.cts +2 -2
  48. package/dist/providers/openrouter.d.ts +2 -2
  49. package/dist/providers/openrouter.js +4 -4
  50. package/dist/{schema-BKkg93rL.d.cts → schema-B9A1zLRk.d.cts} +482 -2
  51. package/dist/{schema-BKkg93rL.d.ts → schema-B9A1zLRk.d.ts} +482 -2
  52. package/dist/testing.cjs +217 -4
  53. package/dist/testing.cjs.map +1 -1
  54. package/dist/testing.d.cts +59 -2
  55. package/dist/testing.d.ts +59 -2
  56. package/dist/testing.js +70 -2
  57. package/dist/testing.js.map +1 -1
  58. package/dist/{types-CsQ8tON_.d.ts → types-DjGAwJxC.d.ts} +1 -1
  59. package/dist/{types-7cC17GWp.d.cts → types-DpbzzZO2.d.cts} +1 -1
  60. package/dist/usagetap/index.d.cts +2 -2
  61. package/dist/usagetap/index.d.ts +2 -2
  62. package/package.json +2 -2
  63. package/dist/chunk-4LEPCCSA.js.map +0 -1
  64. package/dist/chunk-AN3OR7YC.js.map +0 -1
  65. package/dist/chunk-LMURMZUA.js.map +0 -1
  66. package/dist/chunk-O6RQZYS4.js.map +0 -1
  67. package/dist/chunk-V7QY7MRM.js.map +0 -1
  68. package/dist/chunk-YAD6COQX.js +0 -26
  69. package/dist/chunk-YAD6COQX.js.map +0 -1
  70. package/dist/chunk-YNIAA4ZJ.js.map +0 -1
@@ -103,6 +103,29 @@ function mergeOverride(base, override) {
103
103
  if (override.response !== void 0) {
104
104
  result.response = { ...result.response, ...override.response };
105
105
  }
106
+ if (override.cache !== void 0) {
107
+ result.cache = {
108
+ ...result.cache,
109
+ ...override.cache,
110
+ openai: mergeRecordBlock(result.cache?.openai, override.cache.openai),
111
+ anthropic: mergeRecordBlock(result.cache?.anthropic, override.cache.anthropic),
112
+ gemini: mergeRecordBlock(result.cache?.gemini, override.cache.gemini),
113
+ google: mergeRecordBlock(result.cache?.google, override.cache.google)
114
+ };
115
+ }
116
+ if (override.raw !== void 0) {
117
+ result.raw = {
118
+ ...result.raw,
119
+ ...override.raw,
120
+ openai: mergeRecordBlock(result.raw?.openai, override.raw.openai),
121
+ "openai-responses": mergeRecordBlock(result.raw?.["openai-responses"], override.raw["openai-responses"]),
122
+ openai_responses: mergeRecordBlock(result.raw?.openai_responses, override.raw.openai_responses),
123
+ anthropic: mergeRecordBlock(result.raw?.anthropic, override.raw.anthropic),
124
+ gemini: mergeRecordBlock(result.raw?.gemini, override.raw.gemini),
125
+ google: mergeRecordBlock(result.raw?.google, override.raw.google),
126
+ openrouter: mergeRecordBlock(result.raw?.openrouter, override.raw.openrouter)
127
+ };
128
+ }
106
129
  if (override.provider_options !== void 0) {
107
130
  result.provider_options = {
108
131
  ...result.provider_options,
@@ -114,11 +137,19 @@ function mergeOverride(base, override) {
114
137
  gemini: {
115
138
  ...result.provider_options?.gemini,
116
139
  ...override.provider_options.gemini
140
+ },
141
+ openrouter: {
142
+ ...result.provider_options?.openrouter,
143
+ ...override.provider_options.openrouter
117
144
  }
118
145
  };
119
146
  }
120
147
  return result;
121
148
  }
149
+ function mergeRecordBlock(base, override) {
150
+ if (override === void 0) return base;
151
+ return { ...base, ...override };
152
+ }
122
153
 
123
154
  // src/providers/resolve-asset.ts
124
155
  function resolveAssetForProvider(asset, runtime = {}) {
@@ -222,23 +253,42 @@ var ResponseSchema = import_zod.z.object({
222
253
  stream: import_zod.z.boolean().optional(),
223
254
  schema: import_zod.z.record(import_zod.z.unknown()).optional(),
224
255
  schema_name: import_zod.z.string().optional(),
256
+ schema_description: import_zod.z.string().optional(),
225
257
  schema_strict: import_zod.z.boolean().optional()
226
258
  });
227
259
  var AnthropicProviderOptionsSchema = import_zod.z.object({
228
260
  top_k: import_zod.z.number().int().min(0).optional(),
229
- tool_choice: import_zod.z.record(import_zod.z.unknown()).optional()
261
+ tool_choice: import_zod.z.record(import_zod.z.unknown()).optional(),
262
+ output_config: import_zod.z.record(import_zod.z.unknown()).optional()
230
263
  });
231
264
  var GeminiProviderOptionsSchema = import_zod.z.object({
232
265
  candidate_count: import_zod.z.number().int().positive().optional(),
233
266
  top_k: import_zod.z.number().int().min(0).optional(),
234
267
  seed: import_zod.z.number().int().optional(),
235
268
  response_schema: import_zod.z.record(import_zod.z.unknown()).optional(),
269
+ response_json_schema: import_zod.z.record(import_zod.z.unknown()).optional(),
236
270
  response_modalities: import_zod.z.array(import_zod.z.string()).optional(),
237
271
  thinking_budget_tokens: import_zod.z.number().int().positive().optional()
238
272
  });
273
+ var OpenRouterProviderOptionsSchema = import_zod.z.object({
274
+ provider: import_zod.z.record(import_zod.z.unknown()).optional(),
275
+ transforms: import_zod.z.array(import_zod.z.string()).optional(),
276
+ plugins: import_zod.z.array(import_zod.z.record(import_zod.z.unknown())).optional(),
277
+ models: import_zod.z.array(import_zod.z.string()).optional()
278
+ });
239
279
  var ProviderOptionsSchema = import_zod.z.object({
240
280
  anthropic: AnthropicProviderOptionsSchema.optional(),
241
- gemini: GeminiProviderOptionsSchema.optional()
281
+ gemini: GeminiProviderOptionsSchema.optional(),
282
+ openrouter: OpenRouterProviderOptionsSchema.optional()
283
+ });
284
+ var RawProviderBodySchema = import_zod.z.object({
285
+ openai: import_zod.z.record(import_zod.z.unknown()).optional(),
286
+ "openai-responses": import_zod.z.record(import_zod.z.unknown()).optional(),
287
+ openai_responses: import_zod.z.record(import_zod.z.unknown()).optional(),
288
+ anthropic: import_zod.z.record(import_zod.z.unknown()).optional(),
289
+ gemini: import_zod.z.record(import_zod.z.unknown()).optional(),
290
+ google: import_zod.z.record(import_zod.z.unknown()).optional(),
291
+ openrouter: import_zod.z.record(import_zod.z.unknown()).optional()
242
292
  });
243
293
  var OpenAICacheSchema = import_zod.z.object({
244
294
  prompt_cache_key: import_zod.z.string().min(1).optional(),
@@ -311,6 +361,7 @@ var PromptAssetOverridesSchema = import_zod.z.object({
311
361
  sampling: SamplingSchema.optional(),
312
362
  response: ResponseSchema.optional(),
313
363
  cache: CacheSchema.optional(),
364
+ raw: RawProviderBodySchema.optional(),
314
365
  tools: import_zod.z.array(ToolRefSchema).optional(),
315
366
  provider_options: ProviderOptionsSchema.optional()
316
367
  });
@@ -343,6 +394,7 @@ var PromptAssetSchema = import_zod.z.object({
343
394
  sampling: SamplingSchema.optional(),
344
395
  response: ResponseSchema.optional(),
345
396
  cache: CacheSchema.optional(),
397
+ raw: RawProviderBodySchema.optional(),
346
398
  tools: import_zod.z.array(ToolRefSchema).optional(),
347
399
  provider_options: ProviderOptionsSchema.optional(),
348
400
  mcp: MCPSchema.optional(),
@@ -356,6 +408,123 @@ var PromptAssetSchema = import_zod.z.object({
356
408
  source: SourceSchema.optional()
357
409
  });
358
410
 
411
+ // src/parser/frontmatter-guard.ts
412
+ var FRONT_MATTER_DELIMITER = /^---[ \t]*$/;
413
+ var REGEX_FIELD = /^(?<indent>\s*)(?<field>allow_regex|deny_regex)\s*:\s*(?<value>.*)$/;
414
+ var PATTERN_FIELD = /^(?<indent>\s*)pattern\s*:\s*(?<value>.*)$/;
415
+ var INLINE_PATTERN_FIELD = /(?:^|[{,]\s*)pattern\s*:\s*(?<value>"(?:\\.|[^"\\])*")/;
416
+ function assertRegexFrontMatterQuoting(content, filePath) {
417
+ const frontMatter = extractFrontMatter(content);
418
+ if (!frontMatter) {
419
+ return;
420
+ }
421
+ let pendingRegex;
422
+ for (const [index, line] of frontMatter.lines.entries()) {
423
+ const lineNumber = frontMatter.startLine + index;
424
+ const regexMatch = line.match(REGEX_FIELD);
425
+ if (regexMatch?.groups) {
426
+ const field = regexMatch.groups.field;
427
+ const indent2 = regexMatch.groups.indent.length;
428
+ const value = regexMatch.groups.value.trim();
429
+ pendingRegex = value === "" ? { field, indent: indent2 } : void 0;
430
+ assertNoUnescapedBackslashInDoubleQuotedRegex(value, field, filePath, lineNumber);
431
+ assertNoUnescapedBackslashInInlinePattern(value, field, filePath, lineNumber);
432
+ continue;
433
+ }
434
+ if (!pendingRegex) {
435
+ continue;
436
+ }
437
+ if (line.trim() === "" || line.trimStart().startsWith("#")) {
438
+ continue;
439
+ }
440
+ const indent = line.match(/^\s*/)?.[0].length ?? 0;
441
+ if (indent <= pendingRegex.indent) {
442
+ pendingRegex = void 0;
443
+ continue;
444
+ }
445
+ const patternMatch = line.match(PATTERN_FIELD);
446
+ if (!patternMatch?.groups) {
447
+ continue;
448
+ }
449
+ assertNoUnescapedBackslashInDoubleQuotedRegex(
450
+ patternMatch.groups.value.trim(),
451
+ `${pendingRegex.field}.pattern`,
452
+ filePath,
453
+ lineNumber
454
+ );
455
+ }
456
+ }
457
+ function assertNoUnescapedBackslashInInlinePattern(value, field, filePath, lineNumber) {
458
+ const match = value.match(INLINE_PATTERN_FIELD);
459
+ const pattern = match?.groups?.value;
460
+ if (!pattern) {
461
+ return;
462
+ }
463
+ assertNoUnescapedBackslashInDoubleQuotedRegex(pattern, `${field}.pattern`, filePath, lineNumber);
464
+ }
465
+ function extractFrontMatter(content) {
466
+ const lines = content.split(/\r?\n/);
467
+ if (!FRONT_MATTER_DELIMITER.test(lines[0] ?? "")) {
468
+ return void 0;
469
+ }
470
+ for (let index = 1; index < lines.length; index += 1) {
471
+ if (FRONT_MATTER_DELIMITER.test(lines[index] ?? "")) {
472
+ return {
473
+ lines: lines.slice(1, index),
474
+ startLine: 2
475
+ };
476
+ }
477
+ }
478
+ return void 0;
479
+ }
480
+ function assertNoUnescapedBackslashInDoubleQuotedRegex(value, field, filePath, lineNumber) {
481
+ if (!value.startsWith('"')) {
482
+ return;
483
+ }
484
+ const quoted = readDoubleQuotedScalar(value);
485
+ if (!quoted) {
486
+ return;
487
+ }
488
+ if (!hasUnescapedBackslash(quoted)) {
489
+ return;
490
+ }
491
+ const location = filePath ? `${filePath}:${lineNumber}` : `line ${lineNumber}`;
492
+ throw new Error(
493
+ `POK013: Invalid context regex YAML at ${location}, field "${field}": double-quoted regex strings treat backslashes as YAML escapes. Use unquoted /pattern/i literal form, single quotes, or double each backslash.`
494
+ );
495
+ }
496
+ function readDoubleQuotedScalar(value) {
497
+ let result = "";
498
+ for (let index = 1; index < value.length; index += 1) {
499
+ const char = value[index];
500
+ if (char === '"') {
501
+ return result;
502
+ }
503
+ result += char;
504
+ if (char === "\\" && index + 1 < value.length) {
505
+ index += 1;
506
+ result += value[index];
507
+ }
508
+ }
509
+ return void 0;
510
+ }
511
+ function hasUnescapedBackslash(value) {
512
+ for (let index = 0; index < value.length; index += 1) {
513
+ if (value[index] !== "\\") {
514
+ continue;
515
+ }
516
+ let count = 1;
517
+ while (value[index + count] === "\\") {
518
+ count += 1;
519
+ }
520
+ if (count % 2 === 1) {
521
+ return true;
522
+ }
523
+ index += count - 1;
524
+ }
525
+ return false;
526
+ }
527
+
359
528
  // src/parser/sections.ts
360
529
  var SECTION_MAP = {
361
530
  "system instructions": "system_instructions",
@@ -396,6 +565,7 @@ function extractSections(body) {
396
565
 
397
566
  // src/parser/parser.ts
398
567
  function parsePrompt(content, filePath) {
568
+ assertRegexFrontMatterQuoting(content, filePath);
399
569
  const { data: frontMatter, content: body } = (0, import_gray_matter.default)(content);
400
570
  const sections = extractSections(body);
401
571
  const raw = {
@@ -473,6 +643,7 @@ function mergeDefaults(base, local) {
473
643
  return {
474
644
  provider: local.provider ?? base.provider,
475
645
  model: local.model ?? base.model,
646
+ cache: mergeCache(base.cache, local.cache),
476
647
  metadata: {
477
648
  ...base.metadata ?? {},
478
649
  ...local.metadata ?? {}
@@ -484,10 +655,12 @@ function mergeDefaults(base, local) {
484
655
  };
485
656
  }
486
657
  function applyDefaults(asset, defaults) {
658
+ const cache = mergeCache(defaults.cache, asset.cache);
487
659
  const hasDefaultMetadata = defaults.metadata && Object.keys(defaults.metadata).length > 0;
488
660
  const hasDefaultSystem = !!defaults.sections?.system_instructions;
489
661
  const hasDefaultScalars = defaults.provider !== void 0 || defaults.model !== void 0;
490
- if (!hasDefaultMetadata && !hasDefaultSystem && !hasDefaultScalars) {
662
+ const hasDefaultCache = cache !== void 0;
663
+ if (!hasDefaultMetadata && !hasDefaultSystem && !hasDefaultScalars && !hasDefaultCache) {
491
664
  return asset;
492
665
  }
493
666
  const mergedMetadata = {
@@ -501,10 +674,38 @@ function applyDefaults(asset, defaults) {
501
674
  ...asset,
502
675
  provider: asset.provider ?? defaults.provider,
503
676
  model: asset.model ?? defaults.model,
677
+ cache,
504
678
  metadata,
505
679
  sections
506
680
  };
507
681
  }
682
+ function mergeCache(base, local) {
683
+ const merged = {
684
+ ...base ?? {},
685
+ ...local ?? {},
686
+ openai: {
687
+ ...base?.openai ?? {},
688
+ ...local?.openai ?? {}
689
+ },
690
+ anthropic: {
691
+ ...base?.anthropic ?? {},
692
+ ...local?.anthropic ?? {}
693
+ },
694
+ gemini: {
695
+ ...base?.gemini ?? {},
696
+ ...local?.gemini ?? {}
697
+ },
698
+ google: {
699
+ ...base?.google ?? {},
700
+ ...local?.google ?? {}
701
+ }
702
+ };
703
+ if (merged.openai && Object.keys(merged.openai).length === 0) delete merged.openai;
704
+ if (merged.anthropic && Object.keys(merged.anthropic).length === 0) delete merged.anthropic;
705
+ if (merged.gemini && Object.keys(merged.gemini).length === 0) delete merged.gemini;
706
+ if (merged.google && Object.keys(merged.google).length === 0) delete merged.google;
707
+ return Object.keys(merged).length > 0 ? merged : void 0;
708
+ }
508
709
 
509
710
  // src/composition/resolve-includes.ts
510
711
  async function resolveIncludes(asset, basePath, visited = /* @__PURE__ */ new Set()) {
@@ -952,6 +1153,21 @@ function withPromptInputSupport(adapter) {
952
1153
  };
953
1154
  }
954
1155
 
1156
+ // src/providers/raw.ts
1157
+ function applyRawProviderBody(body, asset, provider) {
1158
+ const raw = getRawProviderBody(asset, provider);
1159
+ return raw ? { ...body, ...raw } : body;
1160
+ }
1161
+ function getRawProviderBody(asset, provider) {
1162
+ if (provider === "openai-responses") {
1163
+ return asset.raw?.["openai-responses"] ?? asset.raw?.openai_responses;
1164
+ }
1165
+ if (provider === "gemini") {
1166
+ return asset.raw?.gemini ?? asset.raw?.google;
1167
+ }
1168
+ return asset.raw?.[provider];
1169
+ }
1170
+
955
1171
  // src/providers/openai-responses.ts
956
1172
  var openaiResponsesAdapter = withPromptInputSupport({
957
1173
  name: "openai-responses",
@@ -1012,6 +1228,7 @@ var openaiResponsesAdapter = withPromptInputSupport({
1012
1228
  format: {
1013
1229
  type: "json_schema",
1014
1230
  name: resolvedAsset.response.schema_name ?? `${resolvedAsset.id}_response`,
1231
+ ...resolvedAsset.response.schema_description ? { description: resolvedAsset.response.schema_description } : {},
1015
1232
  schema: resolvedAsset.response.schema,
1016
1233
  strict: resolvedAsset.response.schema_strict ?? true
1017
1234
  }
@@ -1046,7 +1263,7 @@ var openaiResponsesAdapter = withPromptInputSupport({
1046
1263
  if (responseOptions?.include !== void 0) body.include = responseOptions.include;
1047
1264
  if (responseOptions?.background !== void 0) body.background = responseOptions.background;
1048
1265
  return {
1049
- body,
1266
+ body: applyRawProviderBody(body, resolvedAsset, "openai-responses"),
1050
1267
  provider: "openai-responses",
1051
1268
  model: resolvedAsset.model ?? "unknown"
1052
1269
  };