promptopskit 0.2.5 → 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.
Files changed (39) hide show
  1. package/README.md +86 -2
  2. package/SKILL.md +33 -6
  3. package/dist/{chunk-CX6KVBW4.js → chunk-2LK6IILW.js} +10 -2
  4. package/dist/chunk-2LK6IILW.js.map +1 -0
  5. package/dist/chunk-HWEVRBKZ.js +387 -0
  6. package/dist/chunk-HWEVRBKZ.js.map +1 -0
  7. package/dist/cli/index.js +50 -22
  8. package/dist/cli/index.js.map +1 -1
  9. package/dist/index.cjs +483 -6
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +9 -4
  12. package/dist/index.d.ts +9 -4
  13. package/dist/index.js +105 -5
  14. package/dist/index.js.map +1 -1
  15. package/dist/providers/anthropic.d.cts +2 -2
  16. package/dist/providers/anthropic.d.ts +2 -2
  17. package/dist/providers/gemini.d.cts +2 -2
  18. package/dist/providers/gemini.d.ts +2 -2
  19. package/dist/providers/openai.d.cts +2 -2
  20. package/dist/providers/openai.d.ts +2 -2
  21. package/dist/providers/openrouter.d.cts +2 -2
  22. package/dist/providers/openrouter.d.ts +2 -2
  23. package/dist/{schema-C6smABrt.d.cts → schema-DIOA4OiO.d.cts} +53 -32
  24. package/dist/{schema-C6smABrt.d.ts → schema-DIOA4OiO.d.ts} +53 -32
  25. package/dist/testing.cjs +9 -1
  26. package/dist/testing.cjs.map +1 -1
  27. package/dist/testing.d.cts +1 -1
  28. package/dist/testing.d.ts +1 -1
  29. package/dist/testing.js +1 -1
  30. package/dist/{types-S_c-ZEfK.d.cts → types-1zDDD-Ij.d.cts} +1 -1
  31. package/dist/{types-D7lW5IYT.d.ts → types-CQhlfAnR.d.ts} +1 -1
  32. package/dist/usagetap/index.cjs +425 -0
  33. package/dist/usagetap/index.cjs.map +1 -0
  34. package/dist/usagetap/index.d.cts +147 -0
  35. package/dist/usagetap/index.d.ts +147 -0
  36. package/dist/usagetap/index.js +31 -0
  37. package/dist/usagetap/index.js.map +1 -0
  38. package/package.json +11 -1
  39. package/dist/chunk-CX6KVBW4.js.map +0 -1
package/dist/index.js CHANGED
@@ -4,7 +4,22 @@ import {
4
4
  extractSections,
5
5
  loadPromptFile,
6
6
  parsePrompt
7
- } from "./chunk-CX6KVBW4.js";
7
+ } from "./chunk-2LK6IILW.js";
8
+ import {
9
+ applyUsageTapEntitlements,
10
+ beginUsageTapCall,
11
+ createUsageTapClient,
12
+ defaultUsageTapErrorMapper,
13
+ endUsageTapCall,
14
+ extractAnthropicUsage,
15
+ extractGeminiUsage,
16
+ extractOpenAIUsage,
17
+ runAnthropicWithUsageTap,
18
+ runGeminiWithUsageTap,
19
+ runOpenAIWithUsageTap,
20
+ runOpenRouterWithUsageTap,
21
+ withUsageTapCall
22
+ } from "./chunk-HWEVRBKZ.js";
8
23
  import {
9
24
  anthropicAdapter
10
25
  } from "./chunk-VYVEVJC3.js";
@@ -115,6 +130,48 @@ function getAdapter(provider) {
115
130
  return adapter;
116
131
  }
117
132
 
133
+ // src/context.ts
134
+ var textEncoder = new TextEncoder();
135
+ function getContextInputs(asset) {
136
+ return (asset.context?.inputs ?? []).map(normalizeContextInput);
137
+ }
138
+ function getContextInputNames(asset) {
139
+ return getContextInputs(asset).map((input) => input.name);
140
+ }
141
+ function normalizeContextInput(input) {
142
+ if (typeof input === "string") {
143
+ return { name: input };
144
+ }
145
+ return {
146
+ name: input.name,
147
+ max_size: input.max_size
148
+ };
149
+ }
150
+ function measureContextValueSize(value) {
151
+ return textEncoder.encode(value).length;
152
+ }
153
+ function collectContextSizeWarnings(asset, variables = {}) {
154
+ const warnings = [];
155
+ for (const input of getContextInputs(asset)) {
156
+ if (input.max_size === void 0) {
157
+ continue;
158
+ }
159
+ const value = variables[input.name];
160
+ if (value === void 0) {
161
+ continue;
162
+ }
163
+ const actualSize = measureContextValueSize(value);
164
+ if (actualSize > input.max_size) {
165
+ warnings.push({
166
+ variable: input.name,
167
+ maxSize: input.max_size,
168
+ actualSize
169
+ });
170
+ }
171
+ }
172
+ return warnings;
173
+ }
174
+
118
175
  // src/validation/levenshtein.ts
119
176
  function levenshtein(a, b) {
120
177
  const m = a.length;
@@ -196,7 +253,7 @@ function validateAsset(asset, frontMatterKeys, filePath) {
196
253
  }
197
254
  }
198
255
  }
199
- const declaredInputs = new Set(asset.context?.inputs ?? []);
256
+ const declaredInputs = new Set(getContextInputNames(asset));
200
257
  const usedVars = /* @__PURE__ */ new Set();
201
258
  if (asset.sections?.system_instructions) {
202
259
  for (const v of extractVariables(asset.sections.system_instructions)) {
@@ -306,6 +363,26 @@ var PromptCache = class {
306
363
  };
307
364
 
308
365
  // src/index.ts
366
+ function shouldIncludeContextWarningsInResult(policy) {
367
+ return policy === void 0 || policy === "auto" || policy === "result-only" || policy === "console-and-result";
368
+ }
369
+ function shouldLogContextWarnings(policy, options, mode) {
370
+ if (policy === "off" || policy === "result-only") {
371
+ return false;
372
+ }
373
+ if (policy === "console" || policy === "console-and-result") {
374
+ return true;
375
+ }
376
+ return Boolean(options.source || mode !== "compiled-only");
377
+ }
378
+ function formatContextSizeWarning(asset, warning) {
379
+ return [
380
+ "POK030:",
381
+ `Context variable "${warning.variable}" exceeded max_size`,
382
+ `for prompt "${asset.id}"`,
383
+ `(${warning.actualSize} bytes > ${warning.maxSize} bytes).`
384
+ ].join(" ");
385
+ }
309
386
  var PromptOpsKit = class {
310
387
  config;
311
388
  promptCache;
@@ -416,6 +493,15 @@ ${paths.map((p) => ` - ${p}`).join("\n")}`
416
493
  ` + validation.errors.map((e) => ` - ${e}`).join("\n")
417
494
  );
418
495
  }
496
+ const contextSizeWarnings = collectContextSizeWarnings(resolved, options.variables).map(
497
+ (warning) => formatContextSizeWarning(resolved, warning)
498
+ );
499
+ const contextWarningPolicy = this.config.warnings?.contextSize;
500
+ if (contextSizeWarnings.length > 0 && shouldLogContextWarnings(contextWarningPolicy, options, this.config.mode)) {
501
+ for (const warning of contextSizeWarnings) {
502
+ console.warn(`[promptopskit] Warning: ${warning}`);
503
+ }
504
+ }
419
505
  const request = adapter.render(resolved, {
420
506
  variables: options.variables,
421
507
  history: options.history,
@@ -425,7 +511,7 @@ ${paths.map((p) => ` - ${p}`).join("\n")}`
425
511
  return {
426
512
  resolved,
427
513
  request,
428
- warnings: validation.warnings
514
+ warnings: shouldIncludeContextWarningsInResult(contextWarningPolicy) ? [...validation.warnings, ...contextSizeWarnings] : validation.warnings
429
515
  };
430
516
  }
431
517
  /**
@@ -448,7 +534,8 @@ function createPromptOpsKit(config) {
448
534
  async function renderPrompt(options) {
449
535
  const kit = createPromptOpsKit({
450
536
  sourceDir: options.sourceDir ?? ".",
451
- cache: false
537
+ cache: false,
538
+ warnings: options.warnings
452
539
  });
453
540
  return kit.renderPrompt(options);
454
541
  }
@@ -458,7 +545,15 @@ export {
458
545
  PromptOpsKit,
459
546
  anthropicAdapter,
460
547
  applyOverrides,
548
+ applyUsageTapEntitlements,
549
+ beginUsageTapCall,
461
550
  createPromptOpsKit,
551
+ createUsageTapClient,
552
+ defaultUsageTapErrorMapper,
553
+ endUsageTapCall,
554
+ extractAnthropicUsage,
555
+ extractGeminiUsage,
556
+ extractOpenAIUsage,
462
557
  extractSections,
463
558
  extractVariables,
464
559
  geminiAdapter,
@@ -470,7 +565,12 @@ export {
470
565
  parsePrompt,
471
566
  renderPrompt,
472
567
  resolveIncludes,
568
+ runAnthropicWithUsageTap,
569
+ runGeminiWithUsageTap,
570
+ runOpenAIWithUsageTap,
571
+ runOpenRouterWithUsageTap,
473
572
  validateAsset,
474
- validateAssetWithIncludes
573
+ validateAssetWithIncludes,
574
+ withUsageTapCall
475
575
  };
476
576
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/composition/resolve-includes.ts","../src/overrides/apply-overrides.ts","../src/providers/index.ts","../src/validation/levenshtein.ts","../src/validation/validate.ts","../src/cache.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { existsSync, statSync } from 'node:fs';\nimport { resolve, join } from 'node:path';\n\nimport { parsePrompt, loadPromptFile } from './parser/index.js';\nimport { resolveIncludes } from './composition/index.js';\nimport { applyOverrides } from './overrides/index.js';\nimport { renderSections } from './renderer/index.js';\nimport { getAdapter } from './providers/index.js';\nimport { validateAsset } from './validation/index.js';\nimport { PromptCache } from './cache.js';\nimport type { PromptAsset, ResolvedPromptAsset } from './schema/index.js';\nimport type { ProviderRequest, RuntimeRenderOptions } from './providers/types.js';\nimport type { PromptValidationResult } from './validation/index.js';\n\n// --- Re-exports ---\nexport type { PromptAsset, ResolvedPromptAsset } from './schema/index.js';\nexport type { ProviderRequest, RuntimeRenderOptions, ProviderAdapter, ValidationResult } from './providers/types.js';\nexport type { PromptValidationResult, ValidationError } from './validation/index.js';\nexport type { RenderedSections, RenderOptions } from './renderer/index.js';\nexport type { ParseResult } from './parser/index.js';\nexport type { OverrideOptions } from './overrides/index.js';\n\nexport { parsePrompt, loadPromptFile, extractSections } from './parser/index.js';\nexport { interpolate, extractVariables } from './renderer/index.js';\nexport { resolveIncludes } from './composition/index.js';\nexport { applyOverrides } from './overrides/index.js';\nexport { validateAsset, validateAssetWithIncludes } from './validation/index.js';\nexport { getAdapter, openaiAdapter } from './providers/index.js';\nexport { anthropicAdapter } from './providers/anthropic.js';\nexport { geminiAdapter } from './providers/gemini.js';\nexport { openrouterAdapter } from './providers/openrouter.js';\nexport { PromptAssetSchema, PromptAssetOverridesSchema } from './schema/index.js';\n\n// --- Config ---\n\nexport interface PromptOpsKitConfig {\n sourceDir: string;\n compiledDir?: string;\n mode?: 'auto' | 'compiled-only' | 'source-only';\n cache?: boolean;\n}\n\n// --- Render options ---\n\nexport interface RenderPromptOptions {\n /** Prompt path (no extension), e.g. 'support/reply' */\n path?: string;\n /** Inline prompt source string (alternative to path) */\n source?: string;\n /** Provider name */\n provider: string;\n /** Environment override */\n environment?: string;\n /** Tier override */\n tier?: string;\n /** Variables for interpolation */\n variables?: Record<string, string>;\n /** Conversation history */\n history?: Array<{ role: string; content: string }>;\n /** Tool registry for resolving tool references */\n toolRegistry?: Record<string, unknown>;\n /** Strict mode — fail on missing variables */\n strict?: boolean;\n}\n\n// --- Result ---\n\nexport interface RenderResult {\n resolved: ResolvedPromptAsset;\n request: ProviderRequest;\n warnings: string[];\n}\n\n// --- Main class ---\n\nexport class PromptOpsKit {\n private config: Required<Pick<PromptOpsKitConfig, 'sourceDir' | 'mode'>> & PromptOpsKitConfig;\n private promptCache: PromptCache<PromptAsset>;\n\n constructor(config: PromptOpsKitConfig) {\n this.config = {\n ...config,\n mode: config.mode ?? 'auto',\n cache: config.cache ?? true,\n };\n this.promptCache = new PromptCache();\n }\n\n /**\n * Load a prompt asset from compiled or source, based on mode.\n */\n async loadPrompt(promptPath: string): Promise<PromptAsset> {\n const mode = this.config.mode;\n\n // Try compiled first (unless source-only)\n if (mode !== 'source-only' && this.config.compiledDir) {\n const compiledFile = resolve(this.config.compiledDir, promptPath + '.json');\n if (existsSync(compiledFile)) {\n // Check for stale artifact in auto mode\n if (mode === 'auto') {\n const sourceFile = resolve(this.config.sourceDir, promptPath + '.md');\n if (existsSync(sourceFile)) {\n const compiledMtime = statSync(compiledFile).mtimeMs;\n const sourceMtime = statSync(sourceFile).mtimeMs;\n if (sourceMtime > compiledMtime) {\n console.warn(\n `[promptopskit] Warning: compiled artifact for \"${promptPath}\" is older than source .md file.\\n` +\n ` Run \"promptopskit compile\" or switch to source-only mode.`,\n );\n }\n }\n }\n const content = await readFile(compiledFile, 'utf-8');\n return JSON.parse(content) as PromptAsset;\n }\n if (mode === 'compiled-only') {\n throw new Error(\n `Compiled artifact not found: ${compiledFile}\\n` +\n `Run \"promptopskit compile\" to generate it.`,\n );\n }\n }\n\n // Fall back to source\n if (mode !== 'compiled-only') {\n const sourceFile = resolve(this.config.sourceDir, promptPath + '.md');\n\n // Check cache\n if (this.config.cache) {\n const cached = this.promptCache.get(sourceFile);\n if (cached) return cached;\n }\n\n if (!existsSync(sourceFile)) {\n const paths = [sourceFile];\n if (this.config.compiledDir) {\n paths.unshift(resolve(this.config.compiledDir, promptPath + '.json'));\n }\n throw new Error(\n `Prompt not found: \"${promptPath}\"\\nSearched:\\n${paths.map((p) => ` - ${p}`).join('\\n')}`,\n );\n }\n\n const { asset } = await loadPromptFile(sourceFile, { defaultsRoot: this.config.sourceDir });\n\n if (this.config.cache) {\n this.promptCache.set(sourceFile, asset);\n }\n\n return asset;\n }\n\n throw new Error(`Prompt not found: \"${promptPath}\"`);\n }\n\n /**\n * Resolve a prompt: load, resolve includes, apply overrides.\n */\n async resolvePrompt(\n promptPath: string,\n options: { environment?: string; tier?: string } = {},\n ): Promise<ResolvedPromptAsset> {\n let asset = await this.loadPrompt(promptPath);\n\n // Resolve includes\n const sourceFile = resolve(this.config.sourceDir, promptPath + '.md');\n if (asset.includes && asset.includes.length > 0 && existsSync(sourceFile)) {\n asset = await resolveIncludes(asset, sourceFile);\n }\n\n // Apply overrides\n asset = applyOverrides(asset, {\n environment: options.environment,\n tier: options.tier,\n });\n\n return asset as ResolvedPromptAsset;\n }\n\n /**\n * Render a prompt for a specific provider.\n */\n async renderPrompt(options: RenderPromptOptions): Promise<RenderResult> {\n let resolved: ResolvedPromptAsset;\n\n if (options.source) {\n // Inline source mode\n const { asset } = parsePrompt(options.source);\n const overridden = applyOverrides(asset, {\n environment: options.environment,\n tier: options.tier,\n });\n resolved = overridden as ResolvedPromptAsset;\n } else if (options.path) {\n resolved = await this.resolvePrompt(options.path, {\n environment: options.environment,\n tier: options.tier,\n });\n } else {\n throw new Error('Either \"path\" or \"source\" must be provided to renderPrompt()');\n }\n\n const adapter = getAdapter(options.provider);\n const validation = adapter.validate(resolved);\n\n if (!validation.valid) {\n throw new Error(\n `Provider validation failed for \"${options.provider}\":\\n` +\n validation.errors.map((e) => ` - ${e}`).join('\\n'),\n );\n }\n\n const request = adapter.render(resolved, {\n variables: options.variables,\n history: options.history,\n toolRegistry: options.toolRegistry,\n strict: options.strict,\n });\n\n return {\n resolved,\n request,\n warnings: validation.warnings,\n };\n }\n\n /**\n * Validate a prompt file.\n */\n async validatePrompt(promptPath: string): Promise<PromptValidationResult> {\n const asset = await this.loadPrompt(promptPath);\n return validateAsset(asset, undefined, promptPath);\n }\n\n /**\n * Clear the internal cache.\n */\n clearCache(): void {\n this.promptCache.clear();\n }\n}\n\n// --- Factory ---\n\nexport function createPromptOpsKit(config: PromptOpsKitConfig): PromptOpsKit {\n return new PromptOpsKit(config);\n}\n\n// --- Standalone convenience ---\n\n/**\n * Standalone renderPrompt for quick usage without creating a PromptOpsKit instance.\n * Requires either `source` (inline) or `path` + implicit sourceDir of '.'.\n */\nexport async function renderPrompt(\n options: RenderPromptOptions & { sourceDir?: string },\n): Promise<RenderResult> {\n const kit = createPromptOpsKit({\n sourceDir: options.sourceDir ?? '.',\n cache: false,\n });\n return kit.renderPrompt(options);\n}\n","import { readFile } from 'node:fs/promises';\nimport { resolve, dirname } from 'node:path';\nimport { parsePrompt } from '../parser/index.js';\nimport type { PromptAsset } from '../schema/index.js';\n\n/**\n * Resolve includes for a prompt asset, inlining content from referenced files.\n * Detects and rejects circular includes.\n */\nexport async function resolveIncludes(\n asset: PromptAsset,\n basePath: string,\n visited: Set<string> = new Set(),\n): Promise<PromptAsset> {\n if (!asset.includes || asset.includes.length === 0) {\n return asset;\n }\n\n const baseDir = dirname(basePath);\n const resolvedPath = resolve(basePath);\n\n if (visited.has(resolvedPath)) {\n throw new Error(`Circular include detected: ${resolvedPath}`);\n }\n visited.add(resolvedPath);\n\n let mergedSystemInstructions = '';\n\n for (const includePath of asset.includes) {\n const fullPath = resolve(baseDir, includePath);\n\n if (visited.has(fullPath)) {\n throw new Error(`Circular include detected: ${fullPath} (included from ${basePath})`);\n }\n\n const content = await readFile(fullPath, 'utf-8');\n const { asset: includedAsset } = parsePrompt(content, fullPath);\n\n // Recursively resolve nested includes\n const resolved = await resolveIncludes(includedAsset, fullPath, new Set(visited));\n\n // Append included system instructions before local ones\n if (resolved.sections?.system_instructions) {\n mergedSystemInstructions += resolved.sections.system_instructions + '\\n\\n';\n }\n }\n\n // Prepend included system instructions before the local ones\n const localSystem = asset.sections?.system_instructions ?? '';\n const combinedSystem = (mergedSystemInstructions + localSystem).trim() || undefined;\n\n return {\n ...asset,\n sections: {\n ...asset.sections,\n system_instructions: combinedSystem,\n },\n // Drop includes from the resolved asset — they've been inlined\n includes: undefined,\n };\n}\n","import type { PromptAsset, PromptAssetOverrides } from '../schema/index.js';\n\nexport interface OverrideOptions {\n environment?: string;\n tier?: string;\n runtime?: Partial<PromptAssetOverrides>;\n}\n\n/**\n * Apply environment, tier, and runtime overrides to a prompt asset.\n *\n * Precedence: base → environment → tier → runtime\n * Scalars are replaced. Arrays are replaced (not concatenated).\n */\nexport function applyOverrides(\n asset: PromptAsset,\n options: OverrideOptions = {},\n): PromptAsset {\n let result = { ...asset };\n\n // Apply environment override\n if (options.environment && result.environments?.[options.environment]) {\n result = mergeOverride(result, result.environments[options.environment]);\n }\n\n // Apply tier override\n if (options.tier && result.tiers?.[options.tier]) {\n result = mergeOverride(result, result.tiers[options.tier]);\n }\n\n // Apply runtime overrides\n if (options.runtime) {\n result = mergeOverride(result, options.runtime);\n }\n\n return result;\n}\n\nfunction mergeOverride(\n base: PromptAsset,\n override: Partial<PromptAssetOverrides>,\n): PromptAsset {\n const result = { ...base };\n\n if (override.model !== undefined) result.model = override.model;\n if (override.fallback_models !== undefined) result.fallback_models = override.fallback_models;\n if (override.tools !== undefined) result.tools = override.tools;\n\n if (override.reasoning !== undefined) {\n result.reasoning = { ...result.reasoning, ...override.reasoning };\n }\n if (override.sampling !== undefined) {\n result.sampling = { ...result.sampling, ...override.sampling };\n }\n if (override.response !== undefined) {\n result.response = { ...result.response, ...override.response };\n }\n\n return result;\n}\n","export type { ProviderAdapter, ProviderRequest, ValidationResult, RuntimeRenderOptions } from './types.js';\nexport { openaiAdapter } from './openai.js';\nexport { anthropicAdapter } from './anthropic.js';\nexport { geminiAdapter } from './gemini.js';\nexport { openrouterAdapter } from './openrouter.js';\n\nimport type { ProviderAdapter } from './types.js';\nimport { openaiAdapter } from './openai.js';\nimport { anthropicAdapter } from './anthropic.js';\nimport { geminiAdapter } from './gemini.js';\nimport { openrouterAdapter } from './openrouter.js';\n\nconst adapters: Record<string, ProviderAdapter> = {\n openai: openaiAdapter,\n anthropic: anthropicAdapter,\n google: geminiAdapter,\n gemini: geminiAdapter,\n openrouter: openrouterAdapter,\n};\n\n/**\n * Get a provider adapter by name.\n */\nexport function getAdapter(provider: string): ProviderAdapter {\n const adapter = adapters[provider];\n if (!adapter) {\n throw new Error(\n `Unknown provider: \"${provider}\". Supported: ${Object.keys(adapters).join(', ')}`,\n );\n }\n return adapter;\n}\n","/**\n * Compute the Levenshtein distance between two strings.\n * Used for \"did you mean?\" suggestions on unknown fields.\n */\nexport function levenshtein(a: string, b: string): number {\n const m = a.length;\n const n = b.length;\n\n if (m === 0) return n;\n if (n === 0) return m;\n\n const dp: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0) as number[]);\n\n for (let i = 0; i <= m; i++) dp[i][0] = i;\n for (let j = 0; j <= n; j++) dp[0][j] = j;\n\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n dp[i][j] = Math.min(\n dp[i - 1][j] + 1,\n dp[i][j - 1] + 1,\n dp[i - 1][j - 1] + cost,\n );\n }\n }\n\n return dp[m][n];\n}\n","import { PromptAssetSchema } from '../schema/index.js';\nimport type { PromptAsset } from '../schema/index.js';\nimport { extractVariables } from '../renderer/index.js';\nimport { resolveIncludes } from '../composition/index.js';\nimport { levenshtein } from './levenshtein.js';\n\nexport interface ValidationError {\n code: string;\n message: string;\n filePath?: string;\n suggestion?: string;\n}\n\nexport interface PromptValidationResult {\n valid: boolean;\n errors: ValidationError[];\n warnings: ValidationError[];\n}\n\nconst KNOWN_FRONT_MATTER_KEYS = new Set([\n 'id', 'schema_version', 'description', 'provider', 'model', 'fallback_models',\n 'reasoning', 'sampling', 'response', 'tools', 'mcp', 'context', 'includes',\n 'environments', 'tiers', 'metadata',\n]);\n\n/**\n * Validate a parsed prompt asset, returning all errors and warnings.\n */\nexport function validateAsset(\n asset: PromptAsset,\n frontMatterKeys?: string[],\n filePath?: string,\n): PromptValidationResult {\n const errors: ValidationError[] = [];\n const warnings: ValidationError[] = [];\n\n // Schema validation\n const result = PromptAssetSchema.safeParse(asset);\n if (!result.success) {\n for (const issue of result.error.issues) {\n errors.push({\n code: 'POK001',\n message: `Schema error at ${issue.path.join('.')}: ${issue.message}`,\n filePath,\n });\n }\n }\n\n // Missing id\n if (!asset.id) {\n errors.push({\n code: 'POK002',\n message: 'Missing required field: \"id\"',\n filePath,\n });\n }\n\n // Missing body sections\n if (!asset.sections?.system_instructions && !asset.sections?.prompt_template) {\n errors.push({\n code: 'POK003',\n message: 'Prompt must have at least one body section (System instructions or Prompt template)',\n filePath,\n });\n }\n\n // Unknown front matter keys with \"did you mean?\"\n if (frontMatterKeys) {\n for (const key of frontMatterKeys) {\n if (!KNOWN_FRONT_MATTER_KEYS.has(key)) {\n const suggestion = findClosestMatch(key, KNOWN_FRONT_MATTER_KEYS);\n warnings.push({\n code: 'POK010',\n message: `Unknown front matter field: \"${key}\"`,\n filePath,\n suggestion: suggestion ? `Did you mean \"${suggestion}\"?` : undefined,\n });\n }\n }\n }\n\n // Variable validation: used but not declared\n const declaredInputs = new Set(asset.context?.inputs ?? []);\n const usedVars = new Set<string>();\n\n if (asset.sections?.system_instructions) {\n for (const v of extractVariables(asset.sections.system_instructions)) {\n usedVars.add(v);\n }\n }\n if (asset.sections?.prompt_template) {\n for (const v of extractVariables(asset.sections.prompt_template)) {\n usedVars.add(v);\n }\n }\n\n for (const v of usedVars) {\n if (!declaredInputs.has(v)) {\n warnings.push({\n code: 'POK011',\n message: `Variable \"{{ ${v} }}\" is used but not declared in context.inputs`,\n filePath,\n });\n }\n }\n\n // Declared but unused\n for (const v of declaredInputs) {\n if (!usedVars.has(v)) {\n warnings.push({\n code: 'POK012',\n message: `Variable \"${v}\" is declared in context.inputs but never used`,\n filePath,\n });\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n/**\n * Validate a prompt asset including its include graph.\n * Catches missing include files, circular includes, and parse errors in included files.\n */\nexport async function validateAssetWithIncludes(\n asset: PromptAsset,\n filePath: string,\n frontMatterKeys?: string[],\n): Promise<PromptValidationResult> {\n // Run standard validation first\n const result = validateAsset(asset, frontMatterKeys, filePath);\n\n // Validate includes\n if (asset.includes && asset.includes.length > 0) {\n try {\n await resolveIncludes(asset, filePath);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const isCircular = message.includes('Circular include');\n result.errors.push({\n code: isCircular ? 'POK021' : 'POK020',\n message: isCircular\n ? `Circular include detected: ${message}`\n : `Include resolution failed: ${message}`,\n filePath,\n });\n result.valid = false;\n }\n }\n\n return result;\n}\n\nfunction findClosestMatch(input: string, candidates: Set<string>): string | undefined {\n let best: string | undefined;\n let bestDist = Infinity;\n\n for (const candidate of candidates) {\n const dist = levenshtein(input.toLowerCase(), candidate.toLowerCase());\n if (dist < bestDist && dist <= 3) {\n bestDist = dist;\n best = candidate;\n }\n }\n\n return best;\n}\n","import { statSync } from 'node:fs';\n\ninterface CacheEntry<T> {\n value: T;\n mtime: number;\n}\n\n/**\n * Simple in-memory LRU cache keyed by file path + mtime.\n * Used to avoid re-parsing prompt files on every renderPrompt() call.\n */\nexport class PromptCache<T> {\n private cache = new Map<string, CacheEntry<T>>();\n private maxSize: number;\n\n constructor(maxSize = 100) {\n this.maxSize = maxSize;\n }\n\n get(filePath: string): T | undefined {\n const entry = this.cache.get(filePath);\n if (!entry) return undefined;\n\n try {\n const stat = statSync(filePath);\n if (stat.mtimeMs !== entry.mtime) {\n this.cache.delete(filePath);\n return undefined;\n }\n } catch {\n this.cache.delete(filePath);\n return undefined;\n }\n\n return entry.value;\n }\n\n set(filePath: string, value: T): void {\n // Evict oldest if at capacity\n if (this.cache.size >= this.maxSize) {\n const oldest = this.cache.keys().next().value;\n if (oldest) this.cache.delete(oldest);\n }\n\n try {\n const stat = statSync(filePath);\n this.cache.set(filePath, { value, mtime: stat.mtimeMs });\n } catch {\n // Can't stat the file — don't cache\n }\n }\n\n clear(): void {\n this.cache.clear();\n }\n\n get size(): number {\n return this.cache.size;\n }\n}\n"],"mappings":"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","names":["readFile","statSync","resolve","resolve","statSync","readFile"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/composition/resolve-includes.ts","../src/overrides/apply-overrides.ts","../src/providers/index.ts","../src/context.ts","../src/validation/levenshtein.ts","../src/validation/validate.ts","../src/cache.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { existsSync, statSync } from 'node:fs';\nimport { resolve, join } from 'node:path';\n\nimport { parsePrompt, loadPromptFile } from './parser/index.js';\nimport { resolveIncludes } from './composition/index.js';\nimport { applyOverrides } from './overrides/index.js';\nimport { renderSections } from './renderer/index.js';\nimport { getAdapter } from './providers/index.js';\nimport { validateAsset } from './validation/index.js';\nimport { PromptCache } from './cache.js';\nimport { collectContextSizeWarnings } from './context.js';\nimport type { PromptAsset, ResolvedPromptAsset } from './schema/index.js';\nimport type { ProviderRequest, RuntimeRenderOptions } from './providers/types.js';\nimport type { PromptValidationResult } from './validation/index.js';\n\n// --- Re-exports ---\nexport type { PromptAsset, ResolvedPromptAsset } from './schema/index.js';\nexport type { ProviderRequest, RuntimeRenderOptions, ProviderAdapter, ValidationResult } from './providers/types.js';\nexport type { PromptValidationResult, ValidationError } from './validation/index.js';\nexport type { RenderedSections, RenderOptions } from './renderer/index.js';\nexport type { ParseResult } from './parser/index.js';\nexport type { OverrideOptions } from './overrides/index.js';\nexport type {\n UsageTapAllowed,\n UsageTapAllowedCapability,\n UsageTapBeginRequest,\n UsageTapBeginResponse,\n UsageTapCallOptions,\n UsageTapCallResult,\n UsageTapClient,\n UsageTapClientConfig,\n UsageTapEndRequest,\n UsageTapEndResponse,\n UsageTapEndUsage,\n UsageTapEntitlementMode,\n UsageTapEntitlementOptions,\n UsageTapErrorPayload,\n UsageTapInvokeContext,\n UsageTapInvokeResult,\n UsageTapProviderRunOptions,\n UsageTapProviderRunResult,\n UsageTapReasoningLevel,\n} from './usagetap/index.js';\n\nexport { parsePrompt, loadPromptFile, extractSections } from './parser/index.js';\nexport { interpolate, extractVariables } from './renderer/index.js';\nexport { resolveIncludes } from './composition/index.js';\nexport { applyOverrides } from './overrides/index.js';\nexport { validateAsset, validateAssetWithIncludes } from './validation/index.js';\nexport { getAdapter, openaiAdapter } from './providers/index.js';\nexport { anthropicAdapter } from './providers/anthropic.js';\nexport { geminiAdapter } from './providers/gemini.js';\nexport { openrouterAdapter } from './providers/openrouter.js';\nexport { PromptAssetSchema, PromptAssetOverridesSchema } from './schema/index.js';\nexport {\n applyUsageTapEntitlements,\n beginUsageTapCall,\n createUsageTapClient,\n defaultUsageTapErrorMapper,\n endUsageTapCall,\n extractAnthropicUsage,\n extractGeminiUsage,\n extractOpenAIUsage,\n runAnthropicWithUsageTap,\n runGeminiWithUsageTap,\n runOpenAIWithUsageTap,\n runOpenRouterWithUsageTap,\n withUsageTapCall,\n} from './usagetap/index.js';\n\n// --- Config ---\n\nexport interface PromptOpsKitConfig {\n sourceDir: string;\n compiledDir?: string;\n mode?: 'auto' | 'compiled-only' | 'source-only';\n cache?: boolean;\n warnings?: {\n contextSize?: 'auto' | 'off' | 'result-only' | 'console' | 'console-and-result';\n };\n}\n\n// --- Render options ---\n\nexport interface RenderPromptOptions {\n /** Prompt path (no extension), e.g. 'support/reply' */\n path?: string;\n /** Inline prompt source string (alternative to path) */\n source?: string;\n /** Provider name */\n provider: string;\n /** Environment override */\n environment?: string;\n /** Tier override */\n tier?: string;\n /** Variables for interpolation */\n variables?: Record<string, string>;\n /** Conversation history */\n history?: Array<{ role: string; content: string }>;\n /** Tool registry for resolving tool references */\n toolRegistry?: Record<string, unknown>;\n /** Strict mode — fail on missing variables */\n strict?: boolean;\n}\n\n// --- Result ---\n\nexport interface RenderResult {\n resolved: ResolvedPromptAsset;\n request: ProviderRequest;\n warnings: string[];\n}\n\nfunction shouldIncludeContextWarningsInResult(\n policy: NonNullable<PromptOpsKitConfig['warnings']>['contextSize'] | undefined,\n): boolean {\n return policy === undefined\n || policy === 'auto'\n || policy === 'result-only'\n || policy === 'console-and-result';\n}\n\nfunction shouldLogContextWarnings(\n policy: NonNullable<PromptOpsKitConfig['warnings']>['contextSize'] | undefined,\n options: Pick<RenderPromptOptions, 'source'>,\n mode: PromptOpsKitConfig['mode'],\n): boolean {\n if (policy === 'off' || policy === 'result-only') {\n return false;\n }\n\n if (policy === 'console' || policy === 'console-and-result') {\n return true;\n }\n\n return Boolean(options.source || mode !== 'compiled-only');\n}\n\nfunction formatContextSizeWarning(\n asset: ResolvedPromptAsset,\n warning: { variable: string; maxSize: number; actualSize: number },\n): string {\n return [\n 'POK030:',\n `Context variable \"${warning.variable}\" exceeded max_size`,\n `for prompt \"${asset.id}\"`,\n `(${warning.actualSize} bytes > ${warning.maxSize} bytes).`,\n ].join(' ');\n}\n\n// --- Main class ---\n\nexport class PromptOpsKit {\n private config: Required<Pick<PromptOpsKitConfig, 'sourceDir' | 'mode'>> & PromptOpsKitConfig;\n private promptCache: PromptCache<PromptAsset>;\n\n constructor(config: PromptOpsKitConfig) {\n this.config = {\n ...config,\n mode: config.mode ?? 'auto',\n cache: config.cache ?? true,\n };\n this.promptCache = new PromptCache();\n }\n\n /**\n * Load a prompt asset from compiled or source, based on mode.\n */\n async loadPrompt(promptPath: string): Promise<PromptAsset> {\n const mode = this.config.mode;\n\n // Try compiled first (unless source-only)\n if (mode !== 'source-only' && this.config.compiledDir) {\n const compiledFile = resolve(this.config.compiledDir, promptPath + '.json');\n if (existsSync(compiledFile)) {\n // Check for stale artifact in auto mode\n if (mode === 'auto') {\n const sourceFile = resolve(this.config.sourceDir, promptPath + '.md');\n if (existsSync(sourceFile)) {\n const compiledMtime = statSync(compiledFile).mtimeMs;\n const sourceMtime = statSync(sourceFile).mtimeMs;\n if (sourceMtime > compiledMtime) {\n console.warn(\n `[promptopskit] Warning: compiled artifact for \"${promptPath}\" is older than source .md file.\\n` +\n ` Run \"promptopskit compile\" or switch to source-only mode.`,\n );\n }\n }\n }\n const content = await readFile(compiledFile, 'utf-8');\n return JSON.parse(content) as PromptAsset;\n }\n if (mode === 'compiled-only') {\n throw new Error(\n `Compiled artifact not found: ${compiledFile}\\n` +\n `Run \"promptopskit compile\" to generate it.`,\n );\n }\n }\n\n // Fall back to source\n if (mode !== 'compiled-only') {\n const sourceFile = resolve(this.config.sourceDir, promptPath + '.md');\n\n // Check cache\n if (this.config.cache) {\n const cached = this.promptCache.get(sourceFile);\n if (cached) return cached;\n }\n\n if (!existsSync(sourceFile)) {\n const paths = [sourceFile];\n if (this.config.compiledDir) {\n paths.unshift(resolve(this.config.compiledDir, promptPath + '.json'));\n }\n throw new Error(\n `Prompt not found: \"${promptPath}\"\\nSearched:\\n${paths.map((p) => ` - ${p}`).join('\\n')}`,\n );\n }\n\n const { asset } = await loadPromptFile(sourceFile, { defaultsRoot: this.config.sourceDir });\n\n if (this.config.cache) {\n this.promptCache.set(sourceFile, asset);\n }\n\n return asset;\n }\n\n throw new Error(`Prompt not found: \"${promptPath}\"`);\n }\n\n /**\n * Resolve a prompt: load, resolve includes, apply overrides.\n */\n async resolvePrompt(\n promptPath: string,\n options: { environment?: string; tier?: string } = {},\n ): Promise<ResolvedPromptAsset> {\n let asset = await this.loadPrompt(promptPath);\n\n // Resolve includes\n const sourceFile = resolve(this.config.sourceDir, promptPath + '.md');\n if (asset.includes && asset.includes.length > 0 && existsSync(sourceFile)) {\n asset = await resolveIncludes(asset, sourceFile);\n }\n\n // Apply overrides\n asset = applyOverrides(asset, {\n environment: options.environment,\n tier: options.tier,\n });\n\n return asset as ResolvedPromptAsset;\n }\n\n /**\n * Render a prompt for a specific provider.\n */\n async renderPrompt(options: RenderPromptOptions): Promise<RenderResult> {\n let resolved: ResolvedPromptAsset;\n\n if (options.source) {\n // Inline source mode\n const { asset } = parsePrompt(options.source);\n const overridden = applyOverrides(asset, {\n environment: options.environment,\n tier: options.tier,\n });\n resolved = overridden as ResolvedPromptAsset;\n } else if (options.path) {\n resolved = await this.resolvePrompt(options.path, {\n environment: options.environment,\n tier: options.tier,\n });\n } else {\n throw new Error('Either \"path\" or \"source\" must be provided to renderPrompt()');\n }\n\n const adapter = getAdapter(options.provider);\n const validation = adapter.validate(resolved);\n\n if (!validation.valid) {\n throw new Error(\n `Provider validation failed for \"${options.provider}\":\\n` +\n validation.errors.map((e) => ` - ${e}`).join('\\n'),\n );\n }\n\n const contextSizeWarnings = collectContextSizeWarnings(resolved, options.variables).map((warning) =>\n formatContextSizeWarning(resolved, warning),\n );\n\n const contextWarningPolicy = this.config.warnings?.contextSize;\n\n if (contextSizeWarnings.length > 0 && shouldLogContextWarnings(contextWarningPolicy, options, this.config.mode)) {\n for (const warning of contextSizeWarnings) {\n console.warn(`[promptopskit] Warning: ${warning}`);\n }\n }\n\n const request = adapter.render(resolved, {\n variables: options.variables,\n history: options.history,\n toolRegistry: options.toolRegistry,\n strict: options.strict,\n });\n\n return {\n resolved,\n request,\n warnings: shouldIncludeContextWarningsInResult(contextWarningPolicy)\n ? [...validation.warnings, ...contextSizeWarnings]\n : validation.warnings,\n };\n }\n\n /**\n * Validate a prompt file.\n */\n async validatePrompt(promptPath: string): Promise<PromptValidationResult> {\n const asset = await this.loadPrompt(promptPath);\n return validateAsset(asset, undefined, promptPath);\n }\n\n /**\n * Clear the internal cache.\n */\n clearCache(): void {\n this.promptCache.clear();\n }\n}\n\n// --- Factory ---\n\nexport function createPromptOpsKit(config: PromptOpsKitConfig): PromptOpsKit {\n return new PromptOpsKit(config);\n}\n\n// --- Standalone convenience ---\n\n/**\n * Standalone renderPrompt for quick usage without creating a PromptOpsKit instance.\n * Requires either `source` (inline) or `path` + implicit sourceDir of '.'.\n */\nexport async function renderPrompt(\n options: RenderPromptOptions & {\n sourceDir?: string;\n warnings?: PromptOpsKitConfig['warnings'];\n },\n): Promise<RenderResult> {\n const kit = createPromptOpsKit({\n sourceDir: options.sourceDir ?? '.',\n cache: false,\n warnings: options.warnings,\n });\n return kit.renderPrompt(options);\n}\n","import { readFile } from 'node:fs/promises';\nimport { resolve, dirname } from 'node:path';\nimport { parsePrompt } from '../parser/index.js';\nimport type { PromptAsset } from '../schema/index.js';\n\n/**\n * Resolve includes for a prompt asset, inlining content from referenced files.\n * Detects and rejects circular includes.\n */\nexport async function resolveIncludes(\n asset: PromptAsset,\n basePath: string,\n visited: Set<string> = new Set(),\n): Promise<PromptAsset> {\n if (!asset.includes || asset.includes.length === 0) {\n return asset;\n }\n\n const baseDir = dirname(basePath);\n const resolvedPath = resolve(basePath);\n\n if (visited.has(resolvedPath)) {\n throw new Error(`Circular include detected: ${resolvedPath}`);\n }\n visited.add(resolvedPath);\n\n let mergedSystemInstructions = '';\n\n for (const includePath of asset.includes) {\n const fullPath = resolve(baseDir, includePath);\n\n if (visited.has(fullPath)) {\n throw new Error(`Circular include detected: ${fullPath} (included from ${basePath})`);\n }\n\n const content = await readFile(fullPath, 'utf-8');\n const { asset: includedAsset } = parsePrompt(content, fullPath);\n\n // Recursively resolve nested includes\n const resolved = await resolveIncludes(includedAsset, fullPath, new Set(visited));\n\n // Append included system instructions before local ones\n if (resolved.sections?.system_instructions) {\n mergedSystemInstructions += resolved.sections.system_instructions + '\\n\\n';\n }\n }\n\n // Prepend included system instructions before the local ones\n const localSystem = asset.sections?.system_instructions ?? '';\n const combinedSystem = (mergedSystemInstructions + localSystem).trim() || undefined;\n\n return {\n ...asset,\n sections: {\n ...asset.sections,\n system_instructions: combinedSystem,\n },\n // Drop includes from the resolved asset — they've been inlined\n includes: undefined,\n };\n}\n","import type { PromptAsset, PromptAssetOverrides } from '../schema/index.js';\n\nexport interface OverrideOptions {\n environment?: string;\n tier?: string;\n runtime?: Partial<PromptAssetOverrides>;\n}\n\n/**\n * Apply environment, tier, and runtime overrides to a prompt asset.\n *\n * Precedence: base → environment → tier → runtime\n * Scalars are replaced. Arrays are replaced (not concatenated).\n */\nexport function applyOverrides(\n asset: PromptAsset,\n options: OverrideOptions = {},\n): PromptAsset {\n let result = { ...asset };\n\n // Apply environment override\n if (options.environment && result.environments?.[options.environment]) {\n result = mergeOverride(result, result.environments[options.environment]);\n }\n\n // Apply tier override\n if (options.tier && result.tiers?.[options.tier]) {\n result = mergeOverride(result, result.tiers[options.tier]);\n }\n\n // Apply runtime overrides\n if (options.runtime) {\n result = mergeOverride(result, options.runtime);\n }\n\n return result;\n}\n\nfunction mergeOverride(\n base: PromptAsset,\n override: Partial<PromptAssetOverrides>,\n): PromptAsset {\n const result = { ...base };\n\n if (override.model !== undefined) result.model = override.model;\n if (override.fallback_models !== undefined) result.fallback_models = override.fallback_models;\n if (override.tools !== undefined) result.tools = override.tools;\n\n if (override.reasoning !== undefined) {\n result.reasoning = { ...result.reasoning, ...override.reasoning };\n }\n if (override.sampling !== undefined) {\n result.sampling = { ...result.sampling, ...override.sampling };\n }\n if (override.response !== undefined) {\n result.response = { ...result.response, ...override.response };\n }\n\n return result;\n}\n","export type { ProviderAdapter, ProviderRequest, ValidationResult, RuntimeRenderOptions } from './types.js';\nexport { openaiAdapter } from './openai.js';\nexport { anthropicAdapter } from './anthropic.js';\nexport { geminiAdapter } from './gemini.js';\nexport { openrouterAdapter } from './openrouter.js';\n\nimport type { ProviderAdapter } from './types.js';\nimport { openaiAdapter } from './openai.js';\nimport { anthropicAdapter } from './anthropic.js';\nimport { geminiAdapter } from './gemini.js';\nimport { openrouterAdapter } from './openrouter.js';\n\nconst adapters: Record<string, ProviderAdapter> = {\n openai: openaiAdapter,\n anthropic: anthropicAdapter,\n google: geminiAdapter,\n gemini: geminiAdapter,\n openrouter: openrouterAdapter,\n};\n\n/**\n * Get a provider adapter by name.\n */\nexport function getAdapter(provider: string): ProviderAdapter {\n const adapter = adapters[provider];\n if (!adapter) {\n throw new Error(\n `Unknown provider: \"${provider}\". Supported: ${Object.keys(adapters).join(', ')}`,\n );\n }\n return adapter;\n}\n","import type { PromptAsset, ResolvedPromptAsset, ContextInputDefinition } from './schema/index.js';\n\nexport interface NormalizedContextInput {\n name: string;\n max_size?: number;\n}\n\nexport interface ContextSizeWarning {\n variable: string;\n maxSize: number;\n actualSize: number;\n}\n\nconst textEncoder = new TextEncoder();\n\nexport function getContextInputs(\n asset: Pick<PromptAsset | ResolvedPromptAsset, 'context'>,\n): NormalizedContextInput[] {\n return (asset.context?.inputs ?? []).map(normalizeContextInput);\n}\n\nexport function getContextInputNames(\n asset: Pick<PromptAsset | ResolvedPromptAsset, 'context'>,\n): string[] {\n return getContextInputs(asset).map((input) => input.name);\n}\n\nexport function normalizeContextInput(input: ContextInputDefinition): NormalizedContextInput {\n if (typeof input === 'string') {\n return { name: input };\n }\n\n return {\n name: input.name,\n max_size: input.max_size,\n };\n}\n\nexport function measureContextValueSize(value: string): number {\n return textEncoder.encode(value).length;\n}\n\nexport function collectContextSizeWarnings(\n asset: Pick<PromptAsset | ResolvedPromptAsset, 'context'>,\n variables: Record<string, string> = {},\n): ContextSizeWarning[] {\n const warnings: ContextSizeWarning[] = [];\n\n for (const input of getContextInputs(asset)) {\n if (input.max_size === undefined) {\n continue;\n }\n\n const value = variables[input.name];\n if (value === undefined) {\n continue;\n }\n\n const actualSize = measureContextValueSize(value);\n if (actualSize > input.max_size) {\n warnings.push({\n variable: input.name,\n maxSize: input.max_size,\n actualSize,\n });\n }\n }\n\n return warnings;\n}","/**\n * Compute the Levenshtein distance between two strings.\n * Used for \"did you mean?\" suggestions on unknown fields.\n */\nexport function levenshtein(a: string, b: string): number {\n const m = a.length;\n const n = b.length;\n\n if (m === 0) return n;\n if (n === 0) return m;\n\n const dp: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0) as number[]);\n\n for (let i = 0; i <= m; i++) dp[i][0] = i;\n for (let j = 0; j <= n; j++) dp[0][j] = j;\n\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n dp[i][j] = Math.min(\n dp[i - 1][j] + 1,\n dp[i][j - 1] + 1,\n dp[i - 1][j - 1] + cost,\n );\n }\n }\n\n return dp[m][n];\n}\n","import { PromptAssetSchema } from '../schema/index.js';\nimport type { PromptAsset } from '../schema/index.js';\nimport { extractVariables } from '../renderer/index.js';\nimport { resolveIncludes } from '../composition/index.js';\nimport { getContextInputNames } from '../context.js';\nimport { levenshtein } from './levenshtein.js';\n\nexport interface ValidationError {\n code: string;\n message: string;\n filePath?: string;\n suggestion?: string;\n}\n\nexport interface PromptValidationResult {\n valid: boolean;\n errors: ValidationError[];\n warnings: ValidationError[];\n}\n\nconst KNOWN_FRONT_MATTER_KEYS = new Set([\n 'id', 'schema_version', 'description', 'provider', 'model', 'fallback_models',\n 'reasoning', 'sampling', 'response', 'tools', 'mcp', 'context', 'includes',\n 'environments', 'tiers', 'metadata',\n]);\n\n/**\n * Validate a parsed prompt asset, returning all errors and warnings.\n */\nexport function validateAsset(\n asset: PromptAsset,\n frontMatterKeys?: string[],\n filePath?: string,\n): PromptValidationResult {\n const errors: ValidationError[] = [];\n const warnings: ValidationError[] = [];\n\n // Schema validation\n const result = PromptAssetSchema.safeParse(asset);\n if (!result.success) {\n for (const issue of result.error.issues) {\n errors.push({\n code: 'POK001',\n message: `Schema error at ${issue.path.join('.')}: ${issue.message}`,\n filePath,\n });\n }\n }\n\n // Missing id\n if (!asset.id) {\n errors.push({\n code: 'POK002',\n message: 'Missing required field: \"id\"',\n filePath,\n });\n }\n\n // Missing body sections\n if (!asset.sections?.system_instructions && !asset.sections?.prompt_template) {\n errors.push({\n code: 'POK003',\n message: 'Prompt must have at least one body section (System instructions or Prompt template)',\n filePath,\n });\n }\n\n // Unknown front matter keys with \"did you mean?\"\n if (frontMatterKeys) {\n for (const key of frontMatterKeys) {\n if (!KNOWN_FRONT_MATTER_KEYS.has(key)) {\n const suggestion = findClosestMatch(key, KNOWN_FRONT_MATTER_KEYS);\n warnings.push({\n code: 'POK010',\n message: `Unknown front matter field: \"${key}\"`,\n filePath,\n suggestion: suggestion ? `Did you mean \"${suggestion}\"?` : undefined,\n });\n }\n }\n }\n\n // Variable validation: used but not declared\n const declaredInputs = new Set(getContextInputNames(asset));\n const usedVars = new Set<string>();\n\n if (asset.sections?.system_instructions) {\n for (const v of extractVariables(asset.sections.system_instructions)) {\n usedVars.add(v);\n }\n }\n if (asset.sections?.prompt_template) {\n for (const v of extractVariables(asset.sections.prompt_template)) {\n usedVars.add(v);\n }\n }\n\n for (const v of usedVars) {\n if (!declaredInputs.has(v)) {\n warnings.push({\n code: 'POK011',\n message: `Variable \"{{ ${v} }}\" is used but not declared in context.inputs`,\n filePath,\n });\n }\n }\n\n // Declared but unused\n for (const v of declaredInputs) {\n if (!usedVars.has(v)) {\n warnings.push({\n code: 'POK012',\n message: `Variable \"${v}\" is declared in context.inputs but never used`,\n filePath,\n });\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n/**\n * Validate a prompt asset including its include graph.\n * Catches missing include files, circular includes, and parse errors in included files.\n */\nexport async function validateAssetWithIncludes(\n asset: PromptAsset,\n filePath: string,\n frontMatterKeys?: string[],\n): Promise<PromptValidationResult> {\n // Run standard validation first\n const result = validateAsset(asset, frontMatterKeys, filePath);\n\n // Validate includes\n if (asset.includes && asset.includes.length > 0) {\n try {\n await resolveIncludes(asset, filePath);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const isCircular = message.includes('Circular include');\n result.errors.push({\n code: isCircular ? 'POK021' : 'POK020',\n message: isCircular\n ? `Circular include detected: ${message}`\n : `Include resolution failed: ${message}`,\n filePath,\n });\n result.valid = false;\n }\n }\n\n return result;\n}\n\nfunction findClosestMatch(input: string, candidates: Set<string>): string | undefined {\n let best: string | undefined;\n let bestDist = Infinity;\n\n for (const candidate of candidates) {\n const dist = levenshtein(input.toLowerCase(), candidate.toLowerCase());\n if (dist < bestDist && dist <= 3) {\n bestDist = dist;\n best = candidate;\n }\n }\n\n return best;\n}\n","import { statSync } from 'node:fs';\n\ninterface CacheEntry<T> {\n value: T;\n mtime: number;\n}\n\n/**\n * Simple in-memory LRU cache keyed by file path + mtime.\n * Used to avoid re-parsing prompt files on every renderPrompt() call.\n */\nexport class PromptCache<T> {\n private cache = new Map<string, CacheEntry<T>>();\n private maxSize: number;\n\n constructor(maxSize = 100) {\n this.maxSize = maxSize;\n }\n\n get(filePath: string): T | undefined {\n const entry = this.cache.get(filePath);\n if (!entry) return undefined;\n\n try {\n const stat = statSync(filePath);\n if (stat.mtimeMs !== entry.mtime) {\n this.cache.delete(filePath);\n return undefined;\n }\n } catch {\n this.cache.delete(filePath);\n return undefined;\n }\n\n return entry.value;\n }\n\n set(filePath: string, value: T): void {\n // Evict oldest if at capacity\n if (this.cache.size >= this.maxSize) {\n const oldest = this.cache.keys().next().value;\n if (oldest) this.cache.delete(oldest);\n }\n\n try {\n const stat = statSync(filePath);\n this.cache.set(filePath, { value, mtime: stat.mtimeMs });\n } catch {\n // Can't stat the file — don't cache\n }\n }\n\n clear(): void {\n this.cache.clear();\n }\n\n get size(): number {\n return this.cache.size;\n }\n}\n"],"mappings":"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","names":["readFile","statSync","resolve","resolve","statSync","readFile"]}
@@ -1,5 +1,5 @@
1
- import { P as ProviderAdapter } from '../types-S_c-ZEfK.cjs';
2
- import '../schema-C6smABrt.cjs';
1
+ import { P as ProviderAdapter } from '../types-1zDDD-Ij.cjs';
2
+ import '../schema-DIOA4OiO.cjs';
3
3
  import 'zod';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { P as ProviderAdapter } from '../types-D7lW5IYT.js';
2
- import '../schema-C6smABrt.js';
1
+ import { P as ProviderAdapter } from '../types-CQhlfAnR.js';
2
+ import '../schema-DIOA4OiO.js';
3
3
  import 'zod';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { P as ProviderAdapter } from '../types-S_c-ZEfK.cjs';
2
- import '../schema-C6smABrt.cjs';
1
+ import { P as ProviderAdapter } from '../types-1zDDD-Ij.cjs';
2
+ import '../schema-DIOA4OiO.cjs';
3
3
  import 'zod';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { P as ProviderAdapter } from '../types-D7lW5IYT.js';
2
- import '../schema-C6smABrt.js';
1
+ import { P as ProviderAdapter } from '../types-CQhlfAnR.js';
2
+ import '../schema-DIOA4OiO.js';
3
3
  import 'zod';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { P as ProviderAdapter } from '../types-S_c-ZEfK.cjs';
2
- import '../schema-C6smABrt.cjs';
1
+ import { P as ProviderAdapter } from '../types-1zDDD-Ij.cjs';
2
+ import '../schema-DIOA4OiO.cjs';
3
3
  import 'zod';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { P as ProviderAdapter } from '../types-D7lW5IYT.js';
2
- import '../schema-C6smABrt.js';
1
+ import { P as ProviderAdapter } from '../types-CQhlfAnR.js';
2
+ import '../schema-DIOA4OiO.js';
3
3
  import 'zod';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { P as ProviderAdapter } from '../types-S_c-ZEfK.cjs';
2
- import '../schema-C6smABrt.cjs';
1
+ import { P as ProviderAdapter } from '../types-1zDDD-Ij.cjs';
2
+ import '../schema-DIOA4OiO.cjs';
3
3
  import 'zod';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { P as ProviderAdapter } from '../types-D7lW5IYT.js';
2
- import '../schema-C6smABrt.js';
1
+ import { P as ProviderAdapter } from '../types-CQhlfAnR.js';
2
+ import '../schema-DIOA4OiO.js';
3
3
  import 'zod';
4
4
 
5
5
  /**
@@ -193,7 +193,16 @@ declare const PromptAssetSchema: z.ZodObject<{
193
193
  })[] | undefined;
194
194
  }>>;
195
195
  context: z.ZodOptional<z.ZodObject<{
196
- inputs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
196
+ inputs: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodObject<{
197
+ name: z.ZodString;
198
+ max_size: z.ZodOptional<z.ZodNumber>;
199
+ }, "strip", z.ZodTypeAny, {
200
+ name: string;
201
+ max_size?: number | undefined;
202
+ }, {
203
+ name: string;
204
+ max_size?: number | undefined;
205
+ }>]>, "many">>;
197
206
  history: z.ZodOptional<z.ZodObject<{
198
207
  max_items: z.ZodOptional<z.ZodNumber>;
199
208
  }, "strip", z.ZodTypeAny, {
@@ -202,12 +211,18 @@ declare const PromptAssetSchema: z.ZodObject<{
202
211
  max_items?: number | undefined;
203
212
  }>>;
204
213
  }, "strip", z.ZodTypeAny, {
205
- inputs?: string[] | undefined;
214
+ inputs?: (string | {
215
+ name: string;
216
+ max_size?: number | undefined;
217
+ })[] | undefined;
206
218
  history?: {
207
219
  max_items?: number | undefined;
208
220
  } | undefined;
209
221
  }, {
210
- inputs?: string[] | undefined;
222
+ inputs?: (string | {
223
+ name: string;
224
+ max_size?: number | undefined;
225
+ })[] | undefined;
211
226
  history?: {
212
227
  max_items?: number | undefined;
213
228
  } | undefined;
@@ -470,9 +485,8 @@ declare const PromptAssetSchema: z.ZodObject<{
470
485
  id: string;
471
486
  schema_version: number;
472
487
  description?: string | undefined;
473
- provider?: "openai" | "anthropic" | "google" | "gemini" | "openrouter" | "any" | undefined;
474
- model?: string | undefined;
475
488
  includes?: string[] | undefined;
489
+ model?: string | undefined;
476
490
  fallback_models?: string[] | undefined;
477
491
  reasoning?: {
478
492
  effort?: "low" | "medium" | "high" | undefined;
@@ -495,6 +509,18 @@ declare const PromptAssetSchema: z.ZodObject<{
495
509
  description?: string | undefined;
496
510
  input_schema?: Record<string, unknown> | undefined;
497
511
  })[] | undefined;
512
+ provider?: "openai" | "anthropic" | "google" | "gemini" | "openrouter" | "any" | undefined;
513
+ metadata?: {
514
+ owner?: string | undefined;
515
+ tags?: string[] | undefined;
516
+ review_required?: boolean | undefined;
517
+ stable?: boolean | undefined;
518
+ } | undefined;
519
+ sections?: {
520
+ system_instructions?: string | undefined;
521
+ prompt_template?: string | undefined;
522
+ notes?: string | undefined;
523
+ } | undefined;
498
524
  mcp?: {
499
525
  servers?: (string | {
500
526
  name: string;
@@ -502,7 +528,10 @@ declare const PromptAssetSchema: z.ZodObject<{
502
528
  })[] | undefined;
503
529
  } | undefined;
504
530
  context?: {
505
- inputs?: string[] | undefined;
531
+ inputs?: (string | {
532
+ name: string;
533
+ max_size?: number | undefined;
534
+ })[] | undefined;
506
535
  history?: {
507
536
  max_items?: number | undefined;
508
537
  } | undefined;
@@ -557,28 +586,15 @@ declare const PromptAssetSchema: z.ZodObject<{
557
586
  input_schema?: Record<string, unknown> | undefined;
558
587
  })[] | undefined;
559
588
  }> | undefined;
560
- metadata?: {
561
- owner?: string | undefined;
562
- tags?: string[] | undefined;
563
- review_required?: boolean | undefined;
564
- stable?: boolean | undefined;
565
- } | undefined;
566
- sections?: {
567
- system_instructions?: string | undefined;
568
- prompt_template?: string | undefined;
569
- notes?: string | undefined;
570
- } | undefined;
571
589
  source?: {
572
590
  file_path?: string | undefined;
573
591
  checksum?: string | undefined;
574
592
  } | undefined;
575
593
  }, {
576
594
  id: string;
577
- schema_version?: number | undefined;
578
595
  description?: string | undefined;
579
- provider?: "openai" | "anthropic" | "google" | "gemini" | "openrouter" | "any" | undefined;
580
- model?: string | undefined;
581
596
  includes?: string[] | undefined;
597
+ model?: string | undefined;
582
598
  fallback_models?: string[] | undefined;
583
599
  reasoning?: {
584
600
  effort?: "low" | "medium" | "high" | undefined;
@@ -601,6 +617,19 @@ declare const PromptAssetSchema: z.ZodObject<{
601
617
  description?: string | undefined;
602
618
  input_schema?: Record<string, unknown> | undefined;
603
619
  })[] | undefined;
620
+ provider?: "openai" | "anthropic" | "google" | "gemini" | "openrouter" | "any" | undefined;
621
+ metadata?: {
622
+ owner?: string | undefined;
623
+ tags?: string[] | undefined;
624
+ review_required?: boolean | undefined;
625
+ stable?: boolean | undefined;
626
+ } | undefined;
627
+ sections?: {
628
+ system_instructions?: string | undefined;
629
+ prompt_template?: string | undefined;
630
+ notes?: string | undefined;
631
+ } | undefined;
632
+ schema_version?: number | undefined;
604
633
  mcp?: {
605
634
  servers?: (string | {
606
635
  name: string;
@@ -608,7 +637,10 @@ declare const PromptAssetSchema: z.ZodObject<{
608
637
  })[] | undefined;
609
638
  } | undefined;
610
639
  context?: {
611
- inputs?: string[] | undefined;
640
+ inputs?: (string | {
641
+ name: string;
642
+ max_size?: number | undefined;
643
+ })[] | undefined;
612
644
  history?: {
613
645
  max_items?: number | undefined;
614
646
  } | undefined;
@@ -663,17 +695,6 @@ declare const PromptAssetSchema: z.ZodObject<{
663
695
  input_schema?: Record<string, unknown> | undefined;
664
696
  })[] | undefined;
665
697
  }> | undefined;
666
- metadata?: {
667
- owner?: string | undefined;
668
- tags?: string[] | undefined;
669
- review_required?: boolean | undefined;
670
- stable?: boolean | undefined;
671
- } | undefined;
672
- sections?: {
673
- system_instructions?: string | undefined;
674
- prompt_template?: string | undefined;
675
- notes?: string | undefined;
676
- } | undefined;
677
698
  source?: {
678
699
  file_path?: string | undefined;
679
700
  checksum?: string | undefined;