promptopskit 0.7.1 → 0.8.1

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 (71) hide show
  1. package/README.md +39 -4
  2. package/SKILL.md +152 -2
  3. package/dist/{chunk-OWMP5NMV.js → chunk-5XH2GROP.js} +2 -2
  4. package/dist/{chunk-FICB2ZSK.js → chunk-DI7Q4T7A.js} +3 -3
  5. package/dist/{chunk-ULVY473P.js → chunk-E4GEKWVP.js} +31 -3
  6. package/dist/chunk-E4GEKWVP.js.map +1 -0
  7. package/dist/{chunk-3G3EAV7H.js → chunk-PDVUVZAU.js} +2 -2
  8. package/dist/chunk-RVAFVWR2.js +1760 -0
  9. package/dist/chunk-RVAFVWR2.js.map +1 -0
  10. package/dist/{chunk-35NN5F6O.js → chunk-UQLAWU67.js} +2 -2
  11. package/dist/{chunk-6NOUETAC.js → chunk-Z3DPPJNU.js} +2 -2
  12. package/dist/{chunk-R65RAHAG.js → chunk-ZVCKP4EM.js} +3 -3
  13. package/dist/cli/index.js +86 -5
  14. package/dist/cli/index.js.map +1 -1
  15. package/dist/index.cjs +964 -44
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.d.cts +45 -5
  18. package/dist/index.d.ts +45 -5
  19. package/dist/index.js +18 -10
  20. package/dist/index.js.map +1 -1
  21. package/dist/providers/anthropic.cjs +954 -42
  22. package/dist/providers/anthropic.cjs.map +1 -1
  23. package/dist/providers/anthropic.d.cts +2 -2
  24. package/dist/providers/anthropic.d.ts +2 -2
  25. package/dist/providers/anthropic.js +3 -3
  26. package/dist/providers/gemini.cjs +954 -42
  27. package/dist/providers/gemini.cjs.map +1 -1
  28. package/dist/providers/gemini.d.cts +2 -2
  29. package/dist/providers/gemini.d.ts +2 -2
  30. package/dist/providers/gemini.js +3 -3
  31. package/dist/providers/llmasaservice.cjs +954 -42
  32. package/dist/providers/llmasaservice.cjs.map +1 -1
  33. package/dist/providers/llmasaservice.d.cts +2 -2
  34. package/dist/providers/llmasaservice.d.ts +2 -2
  35. package/dist/providers/llmasaservice.js +4 -4
  36. package/dist/providers/openai-responses.cjs +954 -42
  37. package/dist/providers/openai-responses.cjs.map +1 -1
  38. package/dist/providers/openai-responses.d.cts +2 -2
  39. package/dist/providers/openai-responses.d.ts +2 -2
  40. package/dist/providers/openai-responses.js +3 -3
  41. package/dist/providers/openai.cjs +954 -42
  42. package/dist/providers/openai.cjs.map +1 -1
  43. package/dist/providers/openai.d.cts +2 -2
  44. package/dist/providers/openai.d.ts +2 -2
  45. package/dist/providers/openai.js +3 -3
  46. package/dist/providers/openrouter.cjs +954 -42
  47. package/dist/providers/openrouter.cjs.map +1 -1
  48. package/dist/providers/openrouter.d.cts +2 -2
  49. package/dist/providers/openrouter.d.ts +2 -2
  50. package/dist/providers/openrouter.js +4 -4
  51. package/dist/{schema-DBcSns_b.d.cts → schema-BgVLZ2u5.d.cts} +641 -0
  52. package/dist/{schema-DBcSns_b.d.ts → schema-BgVLZ2u5.d.ts} +641 -0
  53. package/dist/testing.cjs +27 -1
  54. package/dist/testing.cjs.map +1 -1
  55. package/dist/testing.d.cts +1 -1
  56. package/dist/testing.d.ts +1 -1
  57. package/dist/testing.js +1 -1
  58. package/dist/{types-BlLXT5Qb.d.ts → types-2hnZmCkH.d.cts} +16 -3
  59. package/dist/{types-8T2D5KB5.d.cts → types-DgAT4jSR.d.ts} +16 -3
  60. package/dist/usagetap/index.d.cts +2 -2
  61. package/dist/usagetap/index.d.ts +2 -2
  62. package/package.json +1 -1
  63. package/dist/chunk-F552OBUV.js +0 -875
  64. package/dist/chunk-F552OBUV.js.map +0 -1
  65. package/dist/chunk-ULVY473P.js.map +0 -1
  66. /package/dist/{chunk-OWMP5NMV.js.map → chunk-5XH2GROP.js.map} +0 -0
  67. /package/dist/{chunk-FICB2ZSK.js.map → chunk-DI7Q4T7A.js.map} +0 -0
  68. /package/dist/{chunk-3G3EAV7H.js.map → chunk-PDVUVZAU.js.map} +0 -0
  69. /package/dist/{chunk-35NN5F6O.js.map → chunk-UQLAWU67.js.map} +0 -0
  70. /package/dist/{chunk-6NOUETAC.js.map → chunk-Z3DPPJNU.js.map} +0 -0
  71. /package/dist/{chunk-R65RAHAG.js.map → chunk-ZVCKP4EM.js.map} +0 -0
package/dist/testing.cjs CHANGED
@@ -154,8 +154,25 @@ var TheTokenCompanyCompressionSchema = import_zod.z.object({
154
154
  model: import_zod.z.string().min(1).optional(),
155
155
  aggressiveness: import_zod.z.number().min(0).max(1).optional()
156
156
  });
157
+ var HeuristicCompressionSchema = import_zod.z.object({
158
+ enabled: import_zod.z.boolean().optional(),
159
+ min_tokens: import_zod.z.number().int().positive().optional(),
160
+ max_sentences: import_zod.z.number().int().positive().optional(),
161
+ target_reduction: import_zod.z.number().min(0).max(1).optional(),
162
+ query: import_zod.z.string().optional(),
163
+ query_variable: import_zod.z.string().min(1).optional(),
164
+ json_to_toon: import_zod.z.boolean().optional()
165
+ });
166
+ var CodeCompactionSchema = import_zod.z.object({
167
+ enabled: import_zod.z.boolean().optional(),
168
+ remove_comments: import_zod.z.boolean().optional(),
169
+ trim_indentation: import_zod.z.boolean().optional(),
170
+ collapse_blank_lines: import_zod.z.boolean().optional()
171
+ });
157
172
  var CompressionSchema = import_zod.z.object({
158
- thetokencompany: TheTokenCompanyCompressionSchema.optional()
173
+ thetokencompany: TheTokenCompanyCompressionSchema.optional(),
174
+ heuristic: HeuristicCompressionSchema.optional(),
175
+ code: CodeCompactionSchema.optional()
159
176
  });
160
177
  var OpenAICacheSchema = import_zod.z.object({
161
178
  prompt_cache_key: import_zod.z.string().min(1).optional(),
@@ -195,12 +212,21 @@ var ContextBuiltInValidatorSchema = import_zod.z.union([
195
212
  return_message: import_zod.z.string().optional()
196
213
  })
197
214
  ]);
215
+ var ContextInputCompressionSchema = import_zod.z.union([
216
+ import_zod.z.literal("heuristic"),
217
+ import_zod.z.literal("code"),
218
+ import_zod.z.object({
219
+ heuristic: HeuristicCompressionSchema.optional(),
220
+ code: CodeCompactionSchema.optional()
221
+ })
222
+ ]);
198
223
  var ContextInputDefinitionObjectSchema = import_zod.z.object({
199
224
  name: import_zod.z.string(),
200
225
  optional: import_zod.z.boolean().optional(),
201
226
  warnings: import_zod.z.boolean().optional(),
202
227
  max_size: import_zod.z.number().int().positive().optional(),
203
228
  trim: import_zod.z.union([import_zod.z.boolean(), import_zod.z.enum(["start", "end", "both"])]).optional(),
229
+ compression: ContextInputCompressionSchema.optional(),
204
230
  allow_regex: ContextRegexSchema.optional(),
205
231
  deny_regex: ContextRegexSchema.optional(),
206
232
  non_empty: ContextBuiltInValidatorSchema.optional(),
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/testing.ts","../src/parser/parser.ts","../src/schema/schema.ts","../src/parser/frontmatter-guard.ts","../src/parser/sections.ts","../src/parser/loader.ts","../src/parser/response-schema-ref.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\n\nimport matter from 'gray-matter';\n\nimport { parsePrompt } from './parser/index.js';\nimport type { PromptAsset, ResolvedPromptAsset } from './schema/index.js';\n\nexport interface PromptTestCase<TResponse = unknown> {\n name: string;\n variables?: Record<string, string>;\n response?: TResponse;\n expected_response?: TResponse;\n}\n\nexport interface PromptTestSidecar<TResponse = unknown> {\n cases: Array<PromptTestCase<TResponse>>;\n}\n\nexport interface PromptTestRenderer {\n renderPrompt(options: {\n path?: string;\n source?: string;\n provider: string;\n environment?: string;\n tier?: string;\n variables?: Record<string, string>;\n strict?: boolean;\n }): Promise<unknown>;\n}\n\n/**\n * Create a mock PromptAsset for testing.\n */\nexport function createMockAsset(overrides: Partial<PromptAsset> = {}): PromptAsset {\n return {\n id: 'test.prompt',\n schema_version: 1,\n provider: 'openai',\n model: 'gpt-5.4',\n sections: {\n system_instructions: 'You are a test assistant.',\n prompt_template: 'Hello {{ name }}',\n },\n ...overrides,\n };\n}\n\n/**\n * Create a mock ResolvedPromptAsset for testing.\n */\nexport function createMockResolvedAsset(\n overrides: Partial<ResolvedPromptAsset> = {},\n): ResolvedPromptAsset {\n return {\n id: 'test.prompt',\n schema_version: 1,\n provider: 'openai',\n model: 'gpt-5.4',\n sections: {\n system_instructions: 'You are a test assistant.',\n prompt_template: 'Hello {{ name }}',\n },\n source: {\n file_path: 'test.md',\n },\n ...overrides,\n } as ResolvedPromptAsset;\n}\n\n/**\n * Parse an inline prompt string for testing.\n */\nexport function parseTestPrompt(source: string): PromptAsset {\n const { asset } = parsePrompt(source);\n return asset;\n}\n\n/**\n * Parse a .test.yaml sidecar file.\n */\nexport function parsePromptTestSidecar<TResponse = unknown>(source: string): PromptTestSidecar<TResponse> {\n const parsed = matter(`---\\n${source.trim()}\\n---\\n`);\n const data = parsed.data as Partial<PromptTestSidecar<TResponse>>;\n\n if (!Array.isArray(data.cases)) {\n throw new Error('Prompt test sidecar must include a \"cases\" array.');\n }\n\n return {\n cases: data.cases.map((testCase, index) => {\n if (!testCase || typeof testCase !== 'object') {\n throw new Error(`Prompt test case at index ${index} must be an object.`);\n }\n\n if (typeof testCase.name !== 'string' || testCase.name.length === 0) {\n throw new Error(`Prompt test case at index ${index} must include a non-empty \"name\".`);\n }\n\n return testCase;\n }),\n };\n}\n\n/**\n * Load a .test.yaml sidecar file from disk.\n */\nexport async function loadPromptTestSidecar<TResponse = unknown>(\n filePath: string | URL,\n): Promise<PromptTestSidecar<TResponse>> {\n return parsePromptTestSidecar<TResponse>(await readFile(filePath, 'utf-8'));\n}\n\n/**\n * Find a named test case in a sidecar.\n */\nexport function getPromptTestCase<TResponse = unknown>(\n sidecar: PromptTestSidecar<TResponse> | Array<PromptTestCase<TResponse>>,\n name: string,\n): PromptTestCase<TResponse> {\n const cases = Array.isArray(sidecar) ? sidecar : sidecar.cases;\n const testCase = cases.find((candidate) => candidate.name === name);\n\n if (!testCase) {\n throw new Error(`Prompt test case \"${name}\" was not found.`);\n }\n\n return testCase;\n}\n\n/**\n * Read the canned response for a named case.\n */\nexport function getHardcodedPromptResponse<TResponse = unknown>(\n sidecar: PromptTestSidecar<TResponse> | Array<PromptTestCase<TResponse>>,\n name: string,\n): TResponse {\n const testCase = getPromptTestCase(sidecar, name);\n const response = testCase.response ?? testCase.expected_response;\n\n if (response === undefined) {\n throw new Error(`Prompt test case \"${name}\" does not define a \"response\".`);\n }\n\n return response;\n}\n\n/**\n * Create a small responder for unit tests and local development flows.\n */\nexport function createHardcodedPromptResponder<TResponse = unknown>(\n sidecar: PromptTestSidecar<TResponse> | Array<PromptTestCase<TResponse>>,\n): (name: string) => TResponse {\n return (name) => getHardcodedPromptResponse(sidecar, name);\n}\n\n/**\n * Render a prompt using variables from a named sidecar case.\n */\nexport async function renderPromptTestCase<TResponse = unknown>(\n kit: PromptTestRenderer,\n options: {\n sidecar: PromptTestSidecar<TResponse> | Array<PromptTestCase<TResponse>>;\n caseName: string;\n path?: string;\n source?: string;\n provider: string;\n environment?: string;\n tier?: string;\n strict?: boolean;\n },\n): Promise<{\n testCase: PromptTestCase<TResponse>;\n rendered: unknown;\n response?: TResponse;\n}> {\n const testCase = getPromptTestCase(options.sidecar, options.caseName);\n const rendered = await kit.renderPrompt({\n path: options.path,\n source: options.source,\n provider: options.provider,\n environment: options.environment,\n tier: options.tier,\n variables: testCase.variables,\n strict: options.strict,\n });\n\n return {\n testCase,\n rendered,\n response: testCase.response ?? testCase.expected_response,\n };\n}\n","import matter from 'gray-matter';\nimport { PromptAssetSchema } from '../schema/index.js';\nimport type { PromptAsset } from '../schema/index.js';\nimport { assertRegexFrontMatterQuoting } from './frontmatter-guard.js';\nimport { extractSections } from './sections.js';\n\nexport interface ParseResult {\n asset: PromptAsset;\n raw: {\n frontMatter: Record<string, unknown>;\n body: string;\n };\n}\n\n/**\n * Parse a prompt markdown string (YAML front matter + markdown body)\n * into a validated PromptAsset.\n */\nexport function parsePrompt(content: string, filePath?: string): ParseResult {\n assertRegexFrontMatterQuoting(content, filePath);\n const { data: frontMatter, content: body } = matter(content);\n\n const sections = extractSections(body);\n\n const raw = {\n ...frontMatter,\n sections,\n source: filePath ? { file_path: filePath } : undefined,\n };\n\n const asset = PromptAssetSchema.parse(raw);\n\n return {\n asset,\n raw: {\n frontMatter: frontMatter as Record<string, unknown>,\n body,\n },\n };\n}\n","import { z } from 'zod';\n\n// --- Tool definitions ---\n\nexport const InlineToolDefSchema = z.object({\n name: z.string(),\n description: z.string().optional(),\n input_schema: z.record(z.unknown()).optional(),\n});\n\nexport type InlineToolDef = z.infer<typeof InlineToolDefSchema>;\n\nexport const ToolRefSchema = z.union([z.string(), InlineToolDefSchema]);\n\n// --- MCP ---\n\nexport const MCPServerRefSchema = z.union([\n z.string(),\n z.object({\n name: z.string(),\n config: z.record(z.unknown()).optional(),\n }),\n]);\n\nexport type MCPServerRef = z.infer<typeof MCPServerRefSchema>;\n\n// --- Reasoning ---\n\nexport const ReasoningSchema = z.object({\n effort: z.enum(['low', 'medium', 'high']).optional(),\n budget_tokens: z.number().int().positive().optional(),\n});\n\n// --- Sampling ---\n\nexport const SamplingSchema = z.object({\n temperature: z.number().min(0).max(2).optional(),\n top_p: z.number().min(0).max(1).optional(),\n frequency_penalty: z.number().optional(),\n presence_penalty: z.number().optional(),\n stop: z.array(z.string()).optional(),\n max_output_tokens: z.number().int().positive().optional(),\n});\n\n// --- Response ---\n\nexport const ResponseSchema = z.object({\n format: z.enum(['text', 'json', 'markdown']).optional(),\n stream: z.boolean().optional(),\n schema: z.record(z.unknown()).optional(),\n schema_ref: z.string().min(1).optional(),\n schema_source: z.object({\n mode: z.enum(['inline', 'schema_ref_json', 'schema_ref_zod_module']).optional(),\n ref: z.string().optional(),\n resolved_path: z.string().optional(),\n hash: z.string().optional(),\n }).optional(),\n schema_name: z.string().optional(),\n schema_description: z.string().optional(),\n schema_strict: z.boolean().optional(),\n});\n\nexport const ResponseSchemaWithValidation = ResponseSchema.superRefine((value, ctx) => {\n if (value.schema !== undefined && value.schema_ref !== undefined) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'response.schema and response.schema_ref are mutually exclusive',\n path: ['schema_ref'],\n });\n }\n});\n\n\n// --- Provider-specific options ---\n\nexport const AnthropicProviderOptionsSchema = z.object({\n top_k: z.number().int().min(0).optional(),\n tool_choice: z.record(z.unknown()).optional(),\n output_config: z.record(z.unknown()).optional(),\n});\n\nexport const GeminiProviderOptionsSchema = z.object({\n candidate_count: z.number().int().positive().optional(),\n top_k: z.number().int().min(0).optional(),\n seed: z.number().int().optional(),\n response_schema: z.record(z.unknown()).optional(),\n response_json_schema: z.record(z.unknown()).optional(),\n response_modalities: z.array(z.string()).optional(),\n thinking_budget_tokens: z.number().int().positive().optional(),\n});\n\nexport const OpenRouterProviderOptionsSchema = z.object({\n provider: z.record(z.unknown()).optional(),\n transforms: z.array(z.string()).optional(),\n plugins: z.array(z.record(z.unknown())).optional(),\n models: z.array(z.string()).optional(),\n});\n\nexport const LLMAsAServiceCustomerSchema = z.object({\n customer_id: z.string(),\n customer_name: z.string().optional(),\n customer_user_id: z.string().optional(),\n customer_user_name: z.string().optional(),\n customer_user_email: z.string().optional(),\n});\n\nexport const LLMAsAServiceProviderOptionsSchema = z.object({\n base_url: z.string().url().optional(),\n project_id: z.string().optional(),\n customer: LLMAsAServiceCustomerSchema.optional(),\n conversationId: z.string().optional(),\n conversationTitle: z.string().optional(),\n projectId: z.string().optional(),\n});\n\nexport const ProviderOptionsSchema = z.object({\n anthropic: AnthropicProviderOptionsSchema.optional(),\n gemini: GeminiProviderOptionsSchema.optional(),\n openrouter: OpenRouterProviderOptionsSchema.optional(),\n llmasaservice: LLMAsAServiceProviderOptionsSchema.optional(),\n});\n\nexport type ProviderOptions = z.infer<typeof ProviderOptionsSchema>;\n\n// --- Raw provider body passthrough ---\n\nexport const RawProviderBodySchema = z.object({\n openai: z.record(z.unknown()).optional(),\n 'openai-responses': z.record(z.unknown()).optional(),\n openai_responses: z.record(z.unknown()).optional(),\n anthropic: z.record(z.unknown()).optional(),\n gemini: z.record(z.unknown()).optional(),\n google: z.record(z.unknown()).optional(),\n openrouter: z.record(z.unknown()).optional(),\n llmasaservice: z.record(z.unknown()).optional(),\n});\n\nexport type RawProviderBody = z.infer<typeof RawProviderBodySchema>;\n\n// --- Prompt compression ---\n\nexport const TheTokenCompanyCompressionSchema = z.object({\n enabled: z.boolean().optional(),\n model: z.string().min(1).optional(),\n aggressiveness: z.number().min(0).max(1).optional(),\n});\n\nexport const CompressionSchema = z.object({\n thetokencompany: TheTokenCompanyCompressionSchema.optional(),\n});\n\nexport type Compression = z.infer<typeof CompressionSchema>;\nexport type TheTokenCompanyCompression = z.infer<typeof TheTokenCompanyCompressionSchema>;\n\n// --- Cache controls ---\n\nexport const OpenAICacheSchema = z.object({\n prompt_cache_key: z.string().min(1).optional(),\n retention: z.enum(['in_memory', '24h']).optional(),\n});\n\nexport const AnthropicCacheSchema = z.object({\n mode: z.enum(['automatic', 'explicit']).optional(),\n type: z.literal('ephemeral').optional(),\n ttl: z.enum(['5m', '1h']).optional(),\n cache_system_instructions: z.boolean().optional(),\n cache_tools: z.boolean().optional(),\n cache_prompt_template: z.boolean().optional(),\n});\n\nexport const GeminiCacheSchema = z.object({\n cached_content: z.string().min(1).optional(),\n});\n\nexport const CacheSchema = z.object({\n openai: OpenAICacheSchema.optional(),\n anthropic: AnthropicCacheSchema.optional(),\n gemini: GeminiCacheSchema.optional(),\n google: GeminiCacheSchema.optional(),\n});\n\n// --- Context ---\n\nexport const HistorySchema = z.object({\n max_items: z.number().int().positive().optional(),\n});\n\nexport const ContextRegexSchema = z.union([\n z.string(),\n z.object({\n pattern: z.string(),\n flags: z.string().optional(),\n return_message: z.string().optional(),\n }),\n]);\n\nexport const ContextBuiltInValidatorSchema = z.union([\n z.boolean(),\n z.object({\n return_message: z.string().optional(),\n }),\n]);\n\nexport const ContextInputDefinitionObjectSchema = z.object({\n name: z.string(),\n optional: z.boolean().optional(),\n warnings: z.boolean().optional(),\n max_size: z.number().int().positive().optional(),\n trim: z.union([z.boolean(), z.enum(['start', 'end', 'both'])]).optional(),\n allow_regex: ContextRegexSchema.optional(),\n deny_regex: ContextRegexSchema.optional(),\n non_empty: ContextBuiltInValidatorSchema.optional(),\n reject_secrets: ContextBuiltInValidatorSchema.optional(),\n});\n\nexport const ContextInputDefinitionSchema = z.union([\n z.string(),\n ContextInputDefinitionObjectSchema,\n]);\n\nexport type ContextInputDefinition = z.infer<typeof ContextInputDefinitionSchema>;\nexport type ContextRegexDefinition = z.infer<typeof ContextRegexSchema>;\nexport type ContextBuiltInValidatorDefinition = z.infer<typeof ContextBuiltInValidatorSchema>;\n\nexport const ContextSchema = z.object({\n inputs: z.array(ContextInputDefinitionSchema).optional(),\n history: HistorySchema.optional(),\n});\n\n// --- Metadata ---\n\nexport const MetadataSchema = z.object({\n owner: z.string().optional(),\n tags: z.array(z.string()).optional(),\n review_required: z.boolean().optional(),\n stable: z.boolean().optional(),\n});\n\n// --- MCP block ---\n\nexport const MCPSchema = z.object({\n servers: z.array(MCPServerRefSchema).optional(),\n});\n\n// --- Overrides (subset allowed in environments/tiers) ---\n\nexport const PromptAssetOverridesSchema = z.object({\n model: z.string().optional(),\n fallback_models: z.array(z.string()).optional(),\n reasoning: ReasoningSchema.optional(),\n sampling: SamplingSchema.optional(),\n response: ResponseSchemaWithValidation.optional(),\n compression: CompressionSchema.optional(),\n cache: CacheSchema.optional(),\n raw: RawProviderBodySchema.optional(),\n tools: z.array(ToolRefSchema).optional(),\n provider_options: ProviderOptionsSchema.optional(),\n});\n\nexport type PromptAssetOverrides = z.infer<typeof PromptAssetOverridesSchema>;\n\n// --- Source tracking ---\n\nexport const SourceSchema = z.object({\n file_path: z.string().optional(),\n checksum: z.string().optional(),\n});\n\n// --- Sections (populated by parser) ---\n\nexport const SectionsSchema = z.object({\n system_instructions: z.string().optional(),\n prompt_template: z.string().optional(),\n notes: z.string().optional(),\n});\n\n// --- Defaults files (folder-level inheritance) ---\n\nexport const PromptDefaultsSchema = z.object({\n provider: z.enum(['openai', 'openai-responses', 'anthropic', 'google', 'gemini', 'openrouter', 'llmasaservice', 'any']).optional(),\n model: z.string().optional(),\n fallback_models: z.array(z.string()).optional(),\n reasoning: ReasoningSchema.optional(),\n sampling: SamplingSchema.optional(),\n response: ResponseSchema.optional(),\n compression: CompressionSchema.optional(),\n cache: CacheSchema.optional(),\n raw: RawProviderBodySchema.optional(),\n tools: z.array(ToolRefSchema).optional(),\n provider_options: ProviderOptionsSchema.optional(),\n mcp: MCPSchema.optional(),\n context: ContextSchema.optional(),\n includes: z.array(z.string()).optional(),\n environments: z.record(PromptAssetOverridesSchema).optional(),\n tiers: z.record(PromptAssetOverridesSchema).optional(),\n metadata: MetadataSchema.optional(),\n sections: z.object({\n system_instructions: z.string().optional(),\n }).optional(),\n});\n\nexport type PromptDefaults = z.infer<typeof PromptDefaultsSchema>;\n\n// --- Top-level PromptAsset ---\n\nexport const PromptAssetSchema = z.object({\n id: z.string(),\n schema_version: z.number().int().positive().default(1),\n description: z.string().optional(),\n\n provider: z.enum(['openai', 'openai-responses', 'anthropic', 'google', 'gemini', 'openrouter', 'llmasaservice', 'any']).optional(),\n model: z.string().optional(),\n fallback_models: z.array(z.string()).optional(),\n\n reasoning: ReasoningSchema.optional(),\n sampling: SamplingSchema.optional(),\n response: ResponseSchemaWithValidation.optional(),\n compression: CompressionSchema.optional(),\n cache: CacheSchema.optional(),\n raw: RawProviderBodySchema.optional(),\n\n tools: z.array(ToolRefSchema).optional(),\n provider_options: ProviderOptionsSchema.optional(),\n mcp: MCPSchema.optional(),\n\n context: ContextSchema.optional(),\n\n includes: z.array(z.string()).optional(),\n\n environments: z.record(PromptAssetOverridesSchema).optional(),\n tiers: z.record(PromptAssetOverridesSchema).optional(),\n\n metadata: MetadataSchema.optional(),\n\n // Populated by parser, not authored in YAML\n sections: SectionsSchema.optional(),\n source: SourceSchema.optional(),\n});\n\nexport type PromptAsset = z.infer<typeof PromptAssetSchema>;\n\n// --- Resolved asset (after includes, overrides applied) ---\n\nexport interface ResolvedPromptAsset extends PromptAsset {\n sections: {\n system_instructions?: string;\n prompt_template?: string;\n notes?: string;\n };\n source: {\n file_path?: string;\n checksum?: string;\n };\n}\n","const FRONT_MATTER_DELIMITER = /^---[ \\t]*$/;\nconst REGEX_FIELD = /^(?<indent>\\s*)(?<field>allow_regex|deny_regex)\\s*:\\s*(?<value>.*)$/;\nconst PATTERN_FIELD = /^(?<indent>\\s*)pattern\\s*:\\s*(?<value>.*)$/;\nconst INLINE_PATTERN_FIELD = /(?:^|[{,]\\s*)pattern\\s*:\\s*(?<value>\"(?:\\\\.|[^\"\\\\])*\")/;\n\ninterface PendingRegexField {\n field: string;\n indent: number;\n}\n\nexport function assertRegexFrontMatterQuoting(content: string, filePath?: string): void {\n const frontMatter = extractFrontMatter(content);\n if (!frontMatter) {\n return;\n }\n\n let pendingRegex: PendingRegexField | undefined;\n\n for (const [index, line] of frontMatter.lines.entries()) {\n const lineNumber = frontMatter.startLine + index;\n const regexMatch = line.match(REGEX_FIELD);\n\n if (regexMatch?.groups) {\n const field = regexMatch.groups.field;\n const indent = regexMatch.groups.indent.length;\n const value = regexMatch.groups.value.trim();\n pendingRegex = value === '' ? { field, indent } : undefined;\n\n assertNoUnescapedBackslashInDoubleQuotedRegex(value, field, filePath, lineNumber);\n assertNoUnescapedBackslashInInlinePattern(value, field, filePath, lineNumber);\n continue;\n }\n\n if (!pendingRegex) {\n continue;\n }\n\n if (line.trim() === '' || line.trimStart().startsWith('#')) {\n continue;\n }\n\n const indent = line.match(/^\\s*/)?.[0].length ?? 0;\n if (indent <= pendingRegex.indent) {\n pendingRegex = undefined;\n continue;\n }\n\n const patternMatch = line.match(PATTERN_FIELD);\n if (!patternMatch?.groups) {\n continue;\n }\n\n assertNoUnescapedBackslashInDoubleQuotedRegex(\n patternMatch.groups.value.trim(),\n `${pendingRegex.field}.pattern`,\n filePath,\n lineNumber,\n );\n }\n}\n\nfunction assertNoUnescapedBackslashInInlinePattern(\n value: string,\n field: string,\n filePath: string | undefined,\n lineNumber: number,\n): void {\n const match = value.match(INLINE_PATTERN_FIELD);\n const pattern = match?.groups?.value;\n if (!pattern) {\n return;\n }\n\n assertNoUnescapedBackslashInDoubleQuotedRegex(pattern, `${field}.pattern`, filePath, lineNumber);\n}\n\nfunction extractFrontMatter(content: string): { lines: string[]; startLine: number } | undefined {\n const lines = content.split(/\\r?\\n/);\n if (!FRONT_MATTER_DELIMITER.test(lines[0] ?? '')) {\n return undefined;\n }\n\n for (let index = 1; index < lines.length; index += 1) {\n if (FRONT_MATTER_DELIMITER.test(lines[index] ?? '')) {\n return {\n lines: lines.slice(1, index),\n startLine: 2,\n };\n }\n }\n\n return undefined;\n}\n\nfunction assertNoUnescapedBackslashInDoubleQuotedRegex(\n value: string,\n field: string,\n filePath: string | undefined,\n lineNumber: number,\n): void {\n if (!value.startsWith('\"')) {\n return;\n }\n\n const quoted = readDoubleQuotedScalar(value);\n if (!quoted) {\n return;\n }\n\n if (!hasUnescapedBackslash(quoted)) {\n return;\n }\n\n const location = filePath ? `${filePath}:${lineNumber}` : `line ${lineNumber}`;\n throw new Error(\n `POK013: Invalid context regex YAML at ${location}, field \"${field}\": `\n + 'double-quoted regex strings treat backslashes as YAML escapes. '\n + 'Use unquoted /pattern/i literal form, single quotes, or double each backslash.',\n );\n}\n\nfunction readDoubleQuotedScalar(value: string): string | undefined {\n let result = '';\n\n for (let index = 1; index < value.length; index += 1) {\n const char = value[index];\n\n if (char === '\"') {\n return result;\n }\n\n result += char;\n\n if (char === '\\\\' && index + 1 < value.length) {\n index += 1;\n result += value[index];\n }\n }\n\n return undefined;\n}\n\nfunction hasUnescapedBackslash(value: string): boolean {\n for (let index = 0; index < value.length; index += 1) {\n if (value[index] !== '\\\\') {\n continue;\n }\n\n let count = 1;\n while (value[index + count] === '\\\\') {\n count += 1;\n }\n\n if (count % 2 === 1) {\n return true;\n }\n\n index += count - 1;\n }\n\n return false;\n}\n","export interface Sections {\n system_instructions?: string;\n prompt_template?: string;\n notes?: string;\n}\n\nconst SECTION_MAP: Record<string, keyof Sections> = {\n 'system instructions': 'system_instructions',\n 'prompt template': 'prompt_template',\n 'notes': 'notes',\n};\n\n/**\n * Extract named sections from the markdown body using H1 headings.\n * Case-insensitive. H2+ within a section is treated as content.\n * If no H1 headings are found, the entire body is treated as prompt_template.\n */\nexport function extractSections(body: string): Sections {\n const lines = body.split(/\\r?\\n/);\n const sections: Sections = {};\n\n let currentKey: keyof Sections | null = null;\n let currentLines: string[] = [];\n let foundAnyH1 = false;\n\n for (const line of lines) {\n const h1Match = line.match(/^#\\s+(.+)$/);\n if (h1Match) {\n // Flush previous section\n if (currentKey) {\n sections[currentKey] = currentLines.join('\\n').trim();\n }\n\n foundAnyH1 = true;\n const heading = h1Match[1].trim().toLowerCase();\n currentKey = SECTION_MAP[heading] ?? null;\n currentLines = [];\n } else {\n currentLines.push(line);\n }\n }\n\n // Flush last section\n if (currentKey) {\n sections[currentKey] = currentLines.join('\\n').trim();\n }\n\n // If no H1 headings found, treat entire body as prompt_template\n if (!foundAnyH1) {\n const trimmed = body.trim();\n if (trimmed) {\n sections.prompt_template = trimmed;\n }\n }\n\n return sections;\n}\n","import { readFile } from 'node:fs/promises';\nimport { dirname, join, relative, resolve } from 'node:path';\nimport matter from 'gray-matter';\nimport { parsePrompt } from './parser.js';\nimport type { ParseResult } from './parser.js';\nimport { extractSections } from './sections.js';\nimport { PromptDefaultsSchema } from '../schema/index.js';\nimport type { PromptDefaults } from '../schema/index.js';\nimport { resolveResponseSchemaRef } from './response-schema-ref.js';\n\nconst DEFAULTS_FILE_NAME = 'defaults.md';\n\nexport interface LoadPromptOptions {\n /**\n * Optional boundary directory for defaults discovery.\n * If provided, defaults are loaded from this directory down to the prompt directory.\n */\n defaultsRoot?: string;\n}\n\n/**\n * Load and parse a prompt file from disk.\n */\nexport async function loadPromptFile(filePath: string, options: LoadPromptOptions = {}): Promise<ParseResult> {\n const content = await readFile(filePath, 'utf-8');\n const parsed = parsePrompt(content, filePath);\n // Default the boundary to the file's own directory so traversal never\n // walks above the prompt tree when no explicit root is provided.\n const root = options.defaultsRoot ?? dirname(filePath);\n const defaults = await loadDefaultsForPath(filePath, root);\n const withDefaults = applyDefaults(parsed.asset, defaults);\n const resolved = await resolveResponseSchemaRef(withDefaults, filePath);\n const asset = (resolved.response?.schema !== undefined && !resolved.response?.schema_source)\n ? {\n ...resolved,\n response: {\n ...resolved.response,\n schema_source: { mode: 'inline' as const },\n },\n }\n : resolved;\n\n return {\n ...parsed,\n asset,\n };\n}\n\nasync function loadDefaultsForPath(filePath: string, defaultsRoot?: string): Promise<PromptDefaults> {\n const directories = getDirectoriesToCheck(filePath, defaultsRoot);\n let merged: PromptDefaults = {};\n\n for (const dir of directories) {\n const defaultsPath = join(dir, DEFAULTS_FILE_NAME);\n try {\n const defaultsContent = await readFile(defaultsPath, 'utf-8');\n const defaults = normalizeDefaultIncludes(parseDefaults(defaultsContent), defaultsPath, filePath);\n merged = mergeDefaults(merged, defaults);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw error;\n }\n }\n }\n\n return merged;\n}\n\nfunction getDirectoriesToCheck(filePath: string, defaultsRoot?: string): string[] {\n const dirs: string[] = [];\n let current = resolve(dirname(filePath));\n const boundary = defaultsRoot ? resolve(defaultsRoot) : undefined;\n\n while (true) {\n dirs.unshift(current);\n if ((boundary && current === boundary) || current === dirname(current)) {\n break;\n }\n current = dirname(current);\n }\n\n return dirs;\n}\n\nfunction parseDefaults(content: string): PromptDefaults {\n const { data: frontMatter, content: body } = matter(content);\n const sections = extractSections(body);\n\n return PromptDefaultsSchema.parse({\n ...frontMatter,\n sections: {\n system_instructions: sections.system_instructions,\n },\n });\n}\n\nfunction mergeDefaults(base: PromptDefaults, local: PromptDefaults): PromptDefaults {\n return {\n provider: local.provider ?? base.provider,\n model: local.model ?? base.model,\n fallback_models: local.fallback_models ?? base.fallback_models,\n reasoning: mergeRecordBlock(base.reasoning, local.reasoning),\n sampling: mergeRecordBlock(base.sampling, local.sampling),\n response: mergeRecordBlock(base.response, local.response),\n compression: mergeCompression(base.compression, local.compression),\n cache: mergeCache(base.cache, local.cache),\n raw: mergeRaw(base.raw, local.raw),\n tools: local.tools ?? base.tools,\n provider_options: mergeProviderOptions(base.provider_options, local.provider_options),\n mcp: mergeMcp(base.mcp, local.mcp),\n context: mergeContext(base.context, local.context),\n includes: local.includes ?? base.includes,\n environments: mergeOverrideMap(base.environments, local.environments),\n tiers: mergeOverrideMap(base.tiers, local.tiers),\n metadata: {\n ...(base.metadata ?? {}),\n ...(local.metadata ?? {}),\n },\n sections: {\n ...(base.sections ?? {}),\n ...(local.sections ?? {}),\n },\n };\n}\n\nfunction applyDefaults(asset: ParseResult['asset'], defaults: PromptDefaults): ParseResult['asset'] {\n const compression = mergeCompression(defaults.compression, asset.compression);\n const cache = mergeCache(defaults.cache, asset.cache);\n const raw = mergeRaw(defaults.raw, asset.raw);\n const providerOptions = mergeProviderOptions(defaults.provider_options, asset.provider_options);\n const reasoning = mergeRecordBlock(defaults.reasoning, asset.reasoning);\n const sampling = mergeRecordBlock(defaults.sampling, asset.sampling);\n const response = mergeRecordBlock(defaults.response, asset.response);\n const mcp = mergeMcp(defaults.mcp, asset.mcp);\n const context = mergeContext(defaults.context, asset.context);\n const environments = mergeOverrideMap(defaults.environments, asset.environments);\n const tiers = mergeOverrideMap(defaults.tiers, asset.tiers);\n const hasDefaultMetadata = defaults.metadata && Object.keys(defaults.metadata).length > 0;\n const hasDefaultSystem = !!defaults.sections?.system_instructions;\n const hasDefaultScalars = defaults.provider !== undefined\n || defaults.model !== undefined\n || defaults.fallback_models !== undefined\n || defaults.tools !== undefined\n || defaults.includes !== undefined;\n const hasDefaultObjects = compression !== undefined\n || cache !== undefined\n || raw !== undefined\n || providerOptions !== undefined\n || reasoning !== undefined\n || sampling !== undefined\n || response !== undefined\n || mcp !== undefined\n || context !== undefined\n || environments !== undefined\n || tiers !== undefined;\n\n // Short-circuit: nothing to merge\n if (!hasDefaultMetadata && !hasDefaultSystem && !hasDefaultScalars && !hasDefaultObjects) {\n return asset;\n }\n\n const mergedMetadata = {\n ...(defaults.metadata ?? {}),\n ...(asset.metadata ?? {}),\n };\n const metadata = Object.keys(mergedMetadata).length > 0 ? mergedMetadata : undefined;\n\n const systemInstructions = asset.sections?.system_instructions ?? defaults.sections?.system_instructions;\n\n const sections = asset.sections\n ? { ...asset.sections, system_instructions: systemInstructions }\n : systemInstructions\n ? { system_instructions: systemInstructions }\n : undefined;\n\n return {\n ...asset,\n provider: asset.provider ?? defaults.provider,\n model: asset.model ?? defaults.model,\n fallback_models: asset.fallback_models ?? defaults.fallback_models,\n reasoning,\n sampling,\n response,\n compression,\n cache,\n raw,\n tools: asset.tools ?? defaults.tools,\n provider_options: providerOptions,\n mcp,\n context,\n includes: asset.includes ?? defaults.includes,\n environments,\n tiers,\n metadata,\n sections,\n };\n}\n\nfunction normalizeDefaultIncludes(\n defaults: PromptDefaults,\n defaultsPath: string,\n filePath: string,\n): PromptDefaults {\n if (!defaults.includes) return defaults;\n\n const promptDir = dirname(filePath);\n const defaultsDir = dirname(defaultsPath);\n const includes = defaults.includes.map((includePath) => {\n const relativePath = relative(promptDir, resolve(defaultsDir, includePath)).replace(/\\\\/g, '/');\n return relativePath.startsWith('.') ? relativePath : `./${relativePath}`;\n });\n\n return {\n ...defaults,\n includes,\n };\n}\n\nfunction mergeRecordBlock<T extends object>(base: T | undefined, local: T | undefined): T | undefined {\n if (base === undefined) return local;\n if (local === undefined) return base;\n return { ...base, ...local };\n}\n\nfunction mergeMcp(base: PromptDefaults['mcp'], local: PromptDefaults['mcp']): PromptDefaults['mcp'] {\n return mergeRecordBlock(base, local);\n}\n\nfunction mergeContext(base: PromptDefaults['context'], local: PromptDefaults['context']): PromptDefaults['context'] {\n const merged = {\n ...(base ?? {}),\n ...(local ?? {}),\n history: mergeRecordBlock(base?.history, local?.history),\n };\n\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction mergeCache(base: PromptDefaults['cache'], local: PromptDefaults['cache']): PromptDefaults['cache'] {\n const merged: NonNullable<PromptDefaults['cache']> = {\n ...(base ?? {}),\n ...(local ?? {}),\n openai: {\n ...(base?.openai ?? {}),\n ...(local?.openai ?? {}),\n },\n anthropic: {\n ...(base?.anthropic ?? {}),\n ...(local?.anthropic ?? {}),\n },\n gemini: {\n ...(base?.gemini ?? {}),\n ...(local?.gemini ?? {}),\n },\n google: {\n ...(base?.google ?? {}),\n ...(local?.google ?? {}),\n },\n };\n\n if (merged.openai && Object.keys(merged.openai).length === 0) delete merged.openai;\n if (merged.anthropic && Object.keys(merged.anthropic).length === 0) delete merged.anthropic;\n if (merged.gemini && Object.keys(merged.gemini).length === 0) delete merged.gemini;\n if (merged.google && Object.keys(merged.google).length === 0) delete merged.google;\n\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction mergeCompression(\n base: PromptDefaults['compression'],\n local: PromptDefaults['compression'],\n): PromptDefaults['compression'] {\n const merged: NonNullable<PromptDefaults['compression']> = {\n ...(base ?? {}),\n ...(local ?? {}),\n thetokencompany: mergeRecordBlock(base?.thetokencompany, local?.thetokencompany),\n };\n\n removeEmptyProviderBlocks(merged);\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction mergeRaw(base: PromptDefaults['raw'], local: PromptDefaults['raw']): PromptDefaults['raw'] {\n const merged: NonNullable<PromptDefaults['raw']> = {\n ...(base ?? {}),\n ...(local ?? {}),\n openai: mergeRecordBlock(base?.openai, local?.openai),\n 'openai-responses': mergeRecordBlock(base?.['openai-responses'], local?.['openai-responses']),\n openai_responses: mergeRecordBlock(base?.openai_responses, local?.openai_responses),\n anthropic: mergeRecordBlock(base?.anthropic, local?.anthropic),\n gemini: mergeRecordBlock(base?.gemini, local?.gemini),\n google: mergeRecordBlock(base?.google, local?.google),\n openrouter: mergeRecordBlock(base?.openrouter, local?.openrouter),\n llmasaservice: mergeRecordBlock(base?.llmasaservice, local?.llmasaservice),\n };\n\n removeEmptyProviderBlocks(merged);\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction mergeProviderOptions(\n base: PromptDefaults['provider_options'],\n local: PromptDefaults['provider_options'],\n): PromptDefaults['provider_options'] {\n const merged: NonNullable<PromptDefaults['provider_options']> = {\n ...(base ?? {}),\n ...(local ?? {}),\n anthropic: mergeRecordBlock(base?.anthropic, local?.anthropic),\n gemini: mergeRecordBlock(base?.gemini, local?.gemini),\n openrouter: mergeRecordBlock(base?.openrouter, local?.openrouter),\n llmasaservice: mergeRecordBlock(base?.llmasaservice, local?.llmasaservice),\n };\n\n removeEmptyProviderBlocks(merged);\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction mergeOverrideMap(\n base: PromptDefaults['environments'],\n local: PromptDefaults['environments'],\n): PromptDefaults['environments'] {\n const merged: NonNullable<PromptDefaults['environments']> = { ...(base ?? {}) };\n\n for (const [name, localOverride] of Object.entries(local ?? {})) {\n merged[name] = mergeOverrideConfig(merged[name], localOverride);\n }\n\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction mergeOverrideConfig(\n base: NonNullable<PromptDefaults['environments']>[string] | undefined,\n local: NonNullable<PromptDefaults['environments']>[string],\n): NonNullable<PromptDefaults['environments']>[string] {\n const merged: NonNullable<PromptDefaults['environments']>[string] = {\n ...(base ?? {}),\n ...local,\n };\n\n const reasoning = mergeRecordBlock(base?.reasoning, local.reasoning);\n const sampling = mergeRecordBlock(base?.sampling, local.sampling);\n const response = mergeRecordBlock(base?.response, local.response);\n const compression = mergeCompression(base?.compression, local.compression);\n const cache = mergeCache(base?.cache, local.cache);\n const raw = mergeRaw(base?.raw, local.raw);\n const providerOptions = mergeProviderOptions(base?.provider_options, local.provider_options);\n\n if (reasoning !== undefined) merged.reasoning = reasoning;\n if (sampling !== undefined) merged.sampling = sampling;\n if (response !== undefined) merged.response = response;\n if (compression !== undefined) merged.compression = compression;\n if (cache !== undefined) merged.cache = cache;\n if (raw !== undefined) merged.raw = raw;\n if (providerOptions !== undefined) merged.provider_options = providerOptions;\n\n return merged;\n}\n\nfunction removeEmptyProviderBlocks<T extends Record<string, unknown>>(value: T): void {\n for (const key of Object.keys(value)) {\n const block = value[key];\n if (block === undefined) {\n delete value[key];\n continue;\n }\n\n if (\n block !== null\n &&\n typeof block === 'object'\n && !Array.isArray(block)\n && Object.keys(block).length === 0\n ) {\n delete value[key];\n }\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { createHash } from 'node:crypto';\nimport { dirname, extname, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { z } from 'zod';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\nimport type { PromptAsset } from '../schema/index.js';\n\nconst SUPPORTED_SCHEMA_REF_EXTENSIONS = new Set(['.json', '.js', '.mjs', '.cjs']);\n\n\nasync function resolveJsonSchemaRef(schemaRef: string, promptFilePath: string): Promise<{ schema: Record<string, unknown>; resolvedPath: string; hash: string }> {\n const resolvedPath = resolve(dirname(promptFilePath), schemaRef);\n let raw: string;\n\n try {\n raw = await readFile(resolvedPath, 'utf-8');\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') {\n throw new Error(`POK050: response.schema_ref \"${schemaRef}\" not found (resolved from ${promptFilePath})`);\n }\n throw error;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new Error(`POK050: response.schema_ref \"${schemaRef}\" is not valid JSON`);\n }\n\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error(`POK050: response.schema_ref \"${schemaRef}\" must resolve to a JSON object schema`);\n }\n\n return {\n schema: parsed as Record<string, unknown>,\n resolvedPath,\n hash: createHash('sha256').update(raw).digest('hex'),\n };\n}\n\nasync function resolveZodSchemaRef(schemaRef: string, promptFilePath: string): Promise<{ schema: Record<string, unknown>; resolvedPath: string; hash: string }> {\n const resolvedPath = resolve(dirname(promptFilePath), schemaRef);\n\n let moduleSource: string;\n try {\n moduleSource = await readFile(resolvedPath, 'utf-8');\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') {\n throw new Error(`POK051: response.schema_ref \"${schemaRef}\" not found (resolved from ${promptFilePath})`);\n }\n throw error;\n }\n\n let imported: unknown;\n try {\n imported = await import(pathToFileURL(resolvedPath).href);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`POK051: response.schema_ref \"${schemaRef}\" could not be imported as a module (${message})`);\n }\n\n const mod = imported as Record<string, unknown>;\n const candidate = mod.default ?? mod.schema;\n\n if (!(candidate instanceof z.ZodType)) {\n throw new Error('POK051: zod schema modules must export a Zod schema as default export or named export \"schema\"');\n }\n\n const jsonSchema = zodToJsonSchema(candidate, {\n target: 'jsonSchema7',\n $refStrategy: 'none',\n });\n\n if (!jsonSchema || typeof jsonSchema !== 'object' || Array.isArray(jsonSchema)) {\n throw new Error(`POK051: response.schema_ref \"${schemaRef}\" did not produce a valid JSON schema object`);\n }\n\n return {\n schema: jsonSchema as Record<string, unknown>,\n resolvedPath,\n hash: createHash('sha256').update(moduleSource).digest('hex'),\n };\n}\n\nexport async function resolveResponseSchemaRef(asset: PromptAsset, promptFilePath: string): Promise<PromptAsset> {\n const schemaRef = asset.response?.schema_ref;\n if (!schemaRef) return asset;\n\n const ext = extname(schemaRef).toLowerCase();\n if (!SUPPORTED_SCHEMA_REF_EXTENSIONS.has(ext)) {\n throw new Error(`POK051: response.schema_ref \"${schemaRef}\" has unsupported extension \"${ext}\". Use .json, .js, .mjs, or .cjs`);\n }\n\n const resolved = (ext === '.json')\n ? await resolveJsonSchemaRef(schemaRef, promptFilePath)\n : await resolveZodSchemaRef(schemaRef, promptFilePath);\n\n return {\n ...asset,\n response: {\n ...asset.response,\n schema: resolved.schema,\n schema_ref: undefined,\n schema_source: {\n mode: ext === '.json' ? 'schema_ref_json' : 'schema_ref_zod_module',\n ref: schemaRef,\n resolved_path: resolved.resolvedPath,\n hash: resolved.hash,\n },\n },\n };\n}\n"],"mappings":"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","names":["import_promises","import_gray_matter","indent","matter","import_promises","import_node_path","import_gray_matter","import_zod","matter"]}
1
+ {"version":3,"sources":["../src/testing.ts","../src/parser/parser.ts","../src/schema/schema.ts","../src/parser/frontmatter-guard.ts","../src/parser/sections.ts","../src/parser/loader.ts","../src/parser/response-schema-ref.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\n\nimport matter from 'gray-matter';\n\nimport { parsePrompt } from './parser/index.js';\nimport type { PromptAsset, ResolvedPromptAsset } from './schema/index.js';\n\nexport interface PromptTestCase<TResponse = unknown> {\n name: string;\n variables?: Record<string, string>;\n response?: TResponse;\n expected_response?: TResponse;\n}\n\nexport interface PromptTestSidecar<TResponse = unknown> {\n cases: Array<PromptTestCase<TResponse>>;\n}\n\nexport interface PromptTestRenderer {\n renderPrompt(options: {\n path?: string;\n source?: string;\n provider: string;\n environment?: string;\n tier?: string;\n variables?: Record<string, string>;\n strict?: boolean;\n }): Promise<unknown>;\n}\n\n/**\n * Create a mock PromptAsset for testing.\n */\nexport function createMockAsset(overrides: Partial<PromptAsset> = {}): PromptAsset {\n return {\n id: 'test.prompt',\n schema_version: 1,\n provider: 'openai',\n model: 'gpt-5.4',\n sections: {\n system_instructions: 'You are a test assistant.',\n prompt_template: 'Hello {{ name }}',\n },\n ...overrides,\n };\n}\n\n/**\n * Create a mock ResolvedPromptAsset for testing.\n */\nexport function createMockResolvedAsset(\n overrides: Partial<ResolvedPromptAsset> = {},\n): ResolvedPromptAsset {\n return {\n id: 'test.prompt',\n schema_version: 1,\n provider: 'openai',\n model: 'gpt-5.4',\n sections: {\n system_instructions: 'You are a test assistant.',\n prompt_template: 'Hello {{ name }}',\n },\n source: {\n file_path: 'test.md',\n },\n ...overrides,\n } as ResolvedPromptAsset;\n}\n\n/**\n * Parse an inline prompt string for testing.\n */\nexport function parseTestPrompt(source: string): PromptAsset {\n const { asset } = parsePrompt(source);\n return asset;\n}\n\n/**\n * Parse a .test.yaml sidecar file.\n */\nexport function parsePromptTestSidecar<TResponse = unknown>(source: string): PromptTestSidecar<TResponse> {\n const parsed = matter(`---\\n${source.trim()}\\n---\\n`);\n const data = parsed.data as Partial<PromptTestSidecar<TResponse>>;\n\n if (!Array.isArray(data.cases)) {\n throw new Error('Prompt test sidecar must include a \"cases\" array.');\n }\n\n return {\n cases: data.cases.map((testCase, index) => {\n if (!testCase || typeof testCase !== 'object') {\n throw new Error(`Prompt test case at index ${index} must be an object.`);\n }\n\n if (typeof testCase.name !== 'string' || testCase.name.length === 0) {\n throw new Error(`Prompt test case at index ${index} must include a non-empty \"name\".`);\n }\n\n return testCase;\n }),\n };\n}\n\n/**\n * Load a .test.yaml sidecar file from disk.\n */\nexport async function loadPromptTestSidecar<TResponse = unknown>(\n filePath: string | URL,\n): Promise<PromptTestSidecar<TResponse>> {\n return parsePromptTestSidecar<TResponse>(await readFile(filePath, 'utf-8'));\n}\n\n/**\n * Find a named test case in a sidecar.\n */\nexport function getPromptTestCase<TResponse = unknown>(\n sidecar: PromptTestSidecar<TResponse> | Array<PromptTestCase<TResponse>>,\n name: string,\n): PromptTestCase<TResponse> {\n const cases = Array.isArray(sidecar) ? sidecar : sidecar.cases;\n const testCase = cases.find((candidate) => candidate.name === name);\n\n if (!testCase) {\n throw new Error(`Prompt test case \"${name}\" was not found.`);\n }\n\n return testCase;\n}\n\n/**\n * Read the canned response for a named case.\n */\nexport function getHardcodedPromptResponse<TResponse = unknown>(\n sidecar: PromptTestSidecar<TResponse> | Array<PromptTestCase<TResponse>>,\n name: string,\n): TResponse {\n const testCase = getPromptTestCase(sidecar, name);\n const response = testCase.response ?? testCase.expected_response;\n\n if (response === undefined) {\n throw new Error(`Prompt test case \"${name}\" does not define a \"response\".`);\n }\n\n return response;\n}\n\n/**\n * Create a small responder for unit tests and local development flows.\n */\nexport function createHardcodedPromptResponder<TResponse = unknown>(\n sidecar: PromptTestSidecar<TResponse> | Array<PromptTestCase<TResponse>>,\n): (name: string) => TResponse {\n return (name) => getHardcodedPromptResponse(sidecar, name);\n}\n\n/**\n * Render a prompt using variables from a named sidecar case.\n */\nexport async function renderPromptTestCase<TResponse = unknown>(\n kit: PromptTestRenderer,\n options: {\n sidecar: PromptTestSidecar<TResponse> | Array<PromptTestCase<TResponse>>;\n caseName: string;\n path?: string;\n source?: string;\n provider: string;\n environment?: string;\n tier?: string;\n strict?: boolean;\n },\n): Promise<{\n testCase: PromptTestCase<TResponse>;\n rendered: unknown;\n response?: TResponse;\n}> {\n const testCase = getPromptTestCase(options.sidecar, options.caseName);\n const rendered = await kit.renderPrompt({\n path: options.path,\n source: options.source,\n provider: options.provider,\n environment: options.environment,\n tier: options.tier,\n variables: testCase.variables,\n strict: options.strict,\n });\n\n return {\n testCase,\n rendered,\n response: testCase.response ?? testCase.expected_response,\n };\n}\n","import matter from 'gray-matter';\nimport { PromptAssetSchema } from '../schema/index.js';\nimport type { PromptAsset } from '../schema/index.js';\nimport { assertRegexFrontMatterQuoting } from './frontmatter-guard.js';\nimport { extractSections } from './sections.js';\n\nexport interface ParseResult {\n asset: PromptAsset;\n raw: {\n frontMatter: Record<string, unknown>;\n body: string;\n };\n}\n\n/**\n * Parse a prompt markdown string (YAML front matter + markdown body)\n * into a validated PromptAsset.\n */\nexport function parsePrompt(content: string, filePath?: string): ParseResult {\n assertRegexFrontMatterQuoting(content, filePath);\n const { data: frontMatter, content: body } = matter(content);\n\n const sections = extractSections(body);\n\n const raw = {\n ...frontMatter,\n sections,\n source: filePath ? { file_path: filePath } : undefined,\n };\n\n const asset = PromptAssetSchema.parse(raw);\n\n return {\n asset,\n raw: {\n frontMatter: frontMatter as Record<string, unknown>,\n body,\n },\n };\n}\n","import { z } from 'zod';\n\n// --- Tool definitions ---\n\nexport const InlineToolDefSchema = z.object({\n name: z.string(),\n description: z.string().optional(),\n input_schema: z.record(z.unknown()).optional(),\n});\n\nexport type InlineToolDef = z.infer<typeof InlineToolDefSchema>;\n\nexport const ToolRefSchema = z.union([z.string(), InlineToolDefSchema]);\n\n// --- MCP ---\n\nexport const MCPServerRefSchema = z.union([\n z.string(),\n z.object({\n name: z.string(),\n config: z.record(z.unknown()).optional(),\n }),\n]);\n\nexport type MCPServerRef = z.infer<typeof MCPServerRefSchema>;\n\n// --- Reasoning ---\n\nexport const ReasoningSchema = z.object({\n effort: z.enum(['low', 'medium', 'high']).optional(),\n budget_tokens: z.number().int().positive().optional(),\n});\n\n// --- Sampling ---\n\nexport const SamplingSchema = z.object({\n temperature: z.number().min(0).max(2).optional(),\n top_p: z.number().min(0).max(1).optional(),\n frequency_penalty: z.number().optional(),\n presence_penalty: z.number().optional(),\n stop: z.array(z.string()).optional(),\n max_output_tokens: z.number().int().positive().optional(),\n});\n\n// --- Response ---\n\nexport const ResponseSchema = z.object({\n format: z.enum(['text', 'json', 'markdown']).optional(),\n stream: z.boolean().optional(),\n schema: z.record(z.unknown()).optional(),\n schema_ref: z.string().min(1).optional(),\n schema_source: z.object({\n mode: z.enum(['inline', 'schema_ref_json', 'schema_ref_zod_module']).optional(),\n ref: z.string().optional(),\n resolved_path: z.string().optional(),\n hash: z.string().optional(),\n }).optional(),\n schema_name: z.string().optional(),\n schema_description: z.string().optional(),\n schema_strict: z.boolean().optional(),\n});\n\nexport const ResponseSchemaWithValidation = ResponseSchema.superRefine((value, ctx) => {\n if (value.schema !== undefined && value.schema_ref !== undefined) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'response.schema and response.schema_ref are mutually exclusive',\n path: ['schema_ref'],\n });\n }\n});\n\n\n// --- Provider-specific options ---\n\nexport const AnthropicProviderOptionsSchema = z.object({\n top_k: z.number().int().min(0).optional(),\n tool_choice: z.record(z.unknown()).optional(),\n output_config: z.record(z.unknown()).optional(),\n});\n\nexport const GeminiProviderOptionsSchema = z.object({\n candidate_count: z.number().int().positive().optional(),\n top_k: z.number().int().min(0).optional(),\n seed: z.number().int().optional(),\n response_schema: z.record(z.unknown()).optional(),\n response_json_schema: z.record(z.unknown()).optional(),\n response_modalities: z.array(z.string()).optional(),\n thinking_budget_tokens: z.number().int().positive().optional(),\n});\n\nexport const OpenRouterProviderOptionsSchema = z.object({\n provider: z.record(z.unknown()).optional(),\n transforms: z.array(z.string()).optional(),\n plugins: z.array(z.record(z.unknown())).optional(),\n models: z.array(z.string()).optional(),\n});\n\nexport const LLMAsAServiceCustomerSchema = z.object({\n customer_id: z.string(),\n customer_name: z.string().optional(),\n customer_user_id: z.string().optional(),\n customer_user_name: z.string().optional(),\n customer_user_email: z.string().optional(),\n});\n\nexport const LLMAsAServiceProviderOptionsSchema = z.object({\n base_url: z.string().url().optional(),\n project_id: z.string().optional(),\n customer: LLMAsAServiceCustomerSchema.optional(),\n conversationId: z.string().optional(),\n conversationTitle: z.string().optional(),\n projectId: z.string().optional(),\n});\n\nexport const ProviderOptionsSchema = z.object({\n anthropic: AnthropicProviderOptionsSchema.optional(),\n gemini: GeminiProviderOptionsSchema.optional(),\n openrouter: OpenRouterProviderOptionsSchema.optional(),\n llmasaservice: LLMAsAServiceProviderOptionsSchema.optional(),\n});\n\nexport type ProviderOptions = z.infer<typeof ProviderOptionsSchema>;\n\n// --- Raw provider body passthrough ---\n\nexport const RawProviderBodySchema = z.object({\n openai: z.record(z.unknown()).optional(),\n 'openai-responses': z.record(z.unknown()).optional(),\n openai_responses: z.record(z.unknown()).optional(),\n anthropic: z.record(z.unknown()).optional(),\n gemini: z.record(z.unknown()).optional(),\n google: z.record(z.unknown()).optional(),\n openrouter: z.record(z.unknown()).optional(),\n llmasaservice: z.record(z.unknown()).optional(),\n});\n\nexport type RawProviderBody = z.infer<typeof RawProviderBodySchema>;\n\n// --- Prompt compression ---\n\nexport const TheTokenCompanyCompressionSchema = z.object({\n enabled: z.boolean().optional(),\n model: z.string().min(1).optional(),\n aggressiveness: z.number().min(0).max(1).optional(),\n});\n\nexport const HeuristicCompressionSchema = z.object({\n enabled: z.boolean().optional(),\n min_tokens: z.number().int().positive().optional(),\n max_sentences: z.number().int().positive().optional(),\n target_reduction: z.number().min(0).max(1).optional(),\n query: z.string().optional(),\n query_variable: z.string().min(1).optional(),\n json_to_toon: z.boolean().optional(),\n});\n\nexport const CodeCompactionSchema = z.object({\n enabled: z.boolean().optional(),\n remove_comments: z.boolean().optional(),\n trim_indentation: z.boolean().optional(),\n collapse_blank_lines: z.boolean().optional(),\n});\n\nexport const CompressionSchema = z.object({\n thetokencompany: TheTokenCompanyCompressionSchema.optional(),\n heuristic: HeuristicCompressionSchema.optional(),\n code: CodeCompactionSchema.optional(),\n});\n\nexport type Compression = z.infer<typeof CompressionSchema>;\nexport type TheTokenCompanyCompression = z.infer<typeof TheTokenCompanyCompressionSchema>;\nexport type HeuristicCompression = z.infer<typeof HeuristicCompressionSchema>;\nexport type CodeCompaction = z.infer<typeof CodeCompactionSchema>;\n\n// --- Cache controls ---\n\nexport const OpenAICacheSchema = z.object({\n prompt_cache_key: z.string().min(1).optional(),\n retention: z.enum(['in_memory', '24h']).optional(),\n});\n\nexport const AnthropicCacheSchema = z.object({\n mode: z.enum(['automatic', 'explicit']).optional(),\n type: z.literal('ephemeral').optional(),\n ttl: z.enum(['5m', '1h']).optional(),\n cache_system_instructions: z.boolean().optional(),\n cache_tools: z.boolean().optional(),\n cache_prompt_template: z.boolean().optional(),\n});\n\nexport const GeminiCacheSchema = z.object({\n cached_content: z.string().min(1).optional(),\n});\n\nexport const CacheSchema = z.object({\n openai: OpenAICacheSchema.optional(),\n anthropic: AnthropicCacheSchema.optional(),\n gemini: GeminiCacheSchema.optional(),\n google: GeminiCacheSchema.optional(),\n});\n\n// --- Context ---\n\nexport const HistorySchema = z.object({\n max_items: z.number().int().positive().optional(),\n});\n\nexport const ContextRegexSchema = z.union([\n z.string(),\n z.object({\n pattern: z.string(),\n flags: z.string().optional(),\n return_message: z.string().optional(),\n }),\n]);\n\nexport const ContextBuiltInValidatorSchema = z.union([\n z.boolean(),\n z.object({\n return_message: z.string().optional(),\n }),\n]);\n\nexport const ContextInputCompressionSchema = z.union([\n z.literal('heuristic'),\n z.literal('code'),\n z.object({\n heuristic: HeuristicCompressionSchema.optional(),\n code: CodeCompactionSchema.optional(),\n }),\n]);\n\nexport const ContextInputDefinitionObjectSchema = z.object({\n name: z.string(),\n optional: z.boolean().optional(),\n warnings: z.boolean().optional(),\n max_size: z.number().int().positive().optional(),\n trim: z.union([z.boolean(), z.enum(['start', 'end', 'both'])]).optional(),\n compression: ContextInputCompressionSchema.optional(),\n allow_regex: ContextRegexSchema.optional(),\n deny_regex: ContextRegexSchema.optional(),\n non_empty: ContextBuiltInValidatorSchema.optional(),\n reject_secrets: ContextBuiltInValidatorSchema.optional(),\n});\n\nexport const ContextInputDefinitionSchema = z.union([\n z.string(),\n ContextInputDefinitionObjectSchema,\n]);\n\nexport type ContextInputDefinition = z.infer<typeof ContextInputDefinitionSchema>;\nexport type ContextInputCompression = z.infer<typeof ContextInputCompressionSchema>;\nexport type ContextRegexDefinition = z.infer<typeof ContextRegexSchema>;\nexport type ContextBuiltInValidatorDefinition = z.infer<typeof ContextBuiltInValidatorSchema>;\n\nexport const ContextSchema = z.object({\n inputs: z.array(ContextInputDefinitionSchema).optional(),\n history: HistorySchema.optional(),\n});\n\n// --- Metadata ---\n\nexport const MetadataSchema = z.object({\n owner: z.string().optional(),\n tags: z.array(z.string()).optional(),\n review_required: z.boolean().optional(),\n stable: z.boolean().optional(),\n});\n\n// --- MCP block ---\n\nexport const MCPSchema = z.object({\n servers: z.array(MCPServerRefSchema).optional(),\n});\n\n// --- Overrides (subset allowed in environments/tiers) ---\n\nexport const PromptAssetOverridesSchema = z.object({\n model: z.string().optional(),\n fallback_models: z.array(z.string()).optional(),\n reasoning: ReasoningSchema.optional(),\n sampling: SamplingSchema.optional(),\n response: ResponseSchemaWithValidation.optional(),\n compression: CompressionSchema.optional(),\n cache: CacheSchema.optional(),\n raw: RawProviderBodySchema.optional(),\n tools: z.array(ToolRefSchema).optional(),\n provider_options: ProviderOptionsSchema.optional(),\n});\n\nexport type PromptAssetOverrides = z.infer<typeof PromptAssetOverridesSchema>;\n\n// --- Source tracking ---\n\nexport const SourceSchema = z.object({\n file_path: z.string().optional(),\n checksum: z.string().optional(),\n});\n\n// --- Sections (populated by parser) ---\n\nexport const SectionsSchema = z.object({\n system_instructions: z.string().optional(),\n prompt_template: z.string().optional(),\n notes: z.string().optional(),\n});\n\n// --- Defaults files (folder-level inheritance) ---\n\nexport const PromptDefaultsSchema = z.object({\n provider: z.enum(['openai', 'openai-responses', 'anthropic', 'google', 'gemini', 'openrouter', 'llmasaservice', 'any']).optional(),\n model: z.string().optional(),\n fallback_models: z.array(z.string()).optional(),\n reasoning: ReasoningSchema.optional(),\n sampling: SamplingSchema.optional(),\n response: ResponseSchema.optional(),\n compression: CompressionSchema.optional(),\n cache: CacheSchema.optional(),\n raw: RawProviderBodySchema.optional(),\n tools: z.array(ToolRefSchema).optional(),\n provider_options: ProviderOptionsSchema.optional(),\n mcp: MCPSchema.optional(),\n context: ContextSchema.optional(),\n includes: z.array(z.string()).optional(),\n environments: z.record(PromptAssetOverridesSchema).optional(),\n tiers: z.record(PromptAssetOverridesSchema).optional(),\n metadata: MetadataSchema.optional(),\n sections: z.object({\n system_instructions: z.string().optional(),\n }).optional(),\n});\n\nexport type PromptDefaults = z.infer<typeof PromptDefaultsSchema>;\n\n// --- Top-level PromptAsset ---\n\nexport const PromptAssetSchema = z.object({\n id: z.string(),\n schema_version: z.number().int().positive().default(1),\n description: z.string().optional(),\n\n provider: z.enum(['openai', 'openai-responses', 'anthropic', 'google', 'gemini', 'openrouter', 'llmasaservice', 'any']).optional(),\n model: z.string().optional(),\n fallback_models: z.array(z.string()).optional(),\n\n reasoning: ReasoningSchema.optional(),\n sampling: SamplingSchema.optional(),\n response: ResponseSchemaWithValidation.optional(),\n compression: CompressionSchema.optional(),\n cache: CacheSchema.optional(),\n raw: RawProviderBodySchema.optional(),\n\n tools: z.array(ToolRefSchema).optional(),\n provider_options: ProviderOptionsSchema.optional(),\n mcp: MCPSchema.optional(),\n\n context: ContextSchema.optional(),\n\n includes: z.array(z.string()).optional(),\n\n environments: z.record(PromptAssetOverridesSchema).optional(),\n tiers: z.record(PromptAssetOverridesSchema).optional(),\n\n metadata: MetadataSchema.optional(),\n\n // Populated by parser, not authored in YAML\n sections: SectionsSchema.optional(),\n source: SourceSchema.optional(),\n});\n\nexport type PromptAsset = z.infer<typeof PromptAssetSchema>;\n\n// --- Resolved asset (after includes, overrides applied) ---\n\nexport interface ResolvedPromptAsset extends PromptAsset {\n sections: {\n system_instructions?: string;\n prompt_template?: string;\n notes?: string;\n };\n source: {\n file_path?: string;\n checksum?: string;\n };\n}\n","const FRONT_MATTER_DELIMITER = /^---[ \\t]*$/;\nconst REGEX_FIELD = /^(?<indent>\\s*)(?<field>allow_regex|deny_regex)\\s*:\\s*(?<value>.*)$/;\nconst PATTERN_FIELD = /^(?<indent>\\s*)pattern\\s*:\\s*(?<value>.*)$/;\nconst INLINE_PATTERN_FIELD = /(?:^|[{,]\\s*)pattern\\s*:\\s*(?<value>\"(?:\\\\.|[^\"\\\\])*\")/;\n\ninterface PendingRegexField {\n field: string;\n indent: number;\n}\n\nexport function assertRegexFrontMatterQuoting(content: string, filePath?: string): void {\n const frontMatter = extractFrontMatter(content);\n if (!frontMatter) {\n return;\n }\n\n let pendingRegex: PendingRegexField | undefined;\n\n for (const [index, line] of frontMatter.lines.entries()) {\n const lineNumber = frontMatter.startLine + index;\n const regexMatch = line.match(REGEX_FIELD);\n\n if (regexMatch?.groups) {\n const field = regexMatch.groups.field;\n const indent = regexMatch.groups.indent.length;\n const value = regexMatch.groups.value.trim();\n pendingRegex = value === '' ? { field, indent } : undefined;\n\n assertNoUnescapedBackslashInDoubleQuotedRegex(value, field, filePath, lineNumber);\n assertNoUnescapedBackslashInInlinePattern(value, field, filePath, lineNumber);\n continue;\n }\n\n if (!pendingRegex) {\n continue;\n }\n\n if (line.trim() === '' || line.trimStart().startsWith('#')) {\n continue;\n }\n\n const indent = line.match(/^\\s*/)?.[0].length ?? 0;\n if (indent <= pendingRegex.indent) {\n pendingRegex = undefined;\n continue;\n }\n\n const patternMatch = line.match(PATTERN_FIELD);\n if (!patternMatch?.groups) {\n continue;\n }\n\n assertNoUnescapedBackslashInDoubleQuotedRegex(\n patternMatch.groups.value.trim(),\n `${pendingRegex.field}.pattern`,\n filePath,\n lineNumber,\n );\n }\n}\n\nfunction assertNoUnescapedBackslashInInlinePattern(\n value: string,\n field: string,\n filePath: string | undefined,\n lineNumber: number,\n): void {\n const match = value.match(INLINE_PATTERN_FIELD);\n const pattern = match?.groups?.value;\n if (!pattern) {\n return;\n }\n\n assertNoUnescapedBackslashInDoubleQuotedRegex(pattern, `${field}.pattern`, filePath, lineNumber);\n}\n\nfunction extractFrontMatter(content: string): { lines: string[]; startLine: number } | undefined {\n const lines = content.split(/\\r?\\n/);\n if (!FRONT_MATTER_DELIMITER.test(lines[0] ?? '')) {\n return undefined;\n }\n\n for (let index = 1; index < lines.length; index += 1) {\n if (FRONT_MATTER_DELIMITER.test(lines[index] ?? '')) {\n return {\n lines: lines.slice(1, index),\n startLine: 2,\n };\n }\n }\n\n return undefined;\n}\n\nfunction assertNoUnescapedBackslashInDoubleQuotedRegex(\n value: string,\n field: string,\n filePath: string | undefined,\n lineNumber: number,\n): void {\n if (!value.startsWith('\"')) {\n return;\n }\n\n const quoted = readDoubleQuotedScalar(value);\n if (!quoted) {\n return;\n }\n\n if (!hasUnescapedBackslash(quoted)) {\n return;\n }\n\n const location = filePath ? `${filePath}:${lineNumber}` : `line ${lineNumber}`;\n throw new Error(\n `POK013: Invalid context regex YAML at ${location}, field \"${field}\": `\n + 'double-quoted regex strings treat backslashes as YAML escapes. '\n + 'Use unquoted /pattern/i literal form, single quotes, or double each backslash.',\n );\n}\n\nfunction readDoubleQuotedScalar(value: string): string | undefined {\n let result = '';\n\n for (let index = 1; index < value.length; index += 1) {\n const char = value[index];\n\n if (char === '\"') {\n return result;\n }\n\n result += char;\n\n if (char === '\\\\' && index + 1 < value.length) {\n index += 1;\n result += value[index];\n }\n }\n\n return undefined;\n}\n\nfunction hasUnescapedBackslash(value: string): boolean {\n for (let index = 0; index < value.length; index += 1) {\n if (value[index] !== '\\\\') {\n continue;\n }\n\n let count = 1;\n while (value[index + count] === '\\\\') {\n count += 1;\n }\n\n if (count % 2 === 1) {\n return true;\n }\n\n index += count - 1;\n }\n\n return false;\n}\n","export interface Sections {\n system_instructions?: string;\n prompt_template?: string;\n notes?: string;\n}\n\nconst SECTION_MAP: Record<string, keyof Sections> = {\n 'system instructions': 'system_instructions',\n 'prompt template': 'prompt_template',\n 'notes': 'notes',\n};\n\n/**\n * Extract named sections from the markdown body using H1 headings.\n * Case-insensitive. H2+ within a section is treated as content.\n * If no H1 headings are found, the entire body is treated as prompt_template.\n */\nexport function extractSections(body: string): Sections {\n const lines = body.split(/\\r?\\n/);\n const sections: Sections = {};\n\n let currentKey: keyof Sections | null = null;\n let currentLines: string[] = [];\n let foundAnyH1 = false;\n\n for (const line of lines) {\n const h1Match = line.match(/^#\\s+(.+)$/);\n if (h1Match) {\n // Flush previous section\n if (currentKey) {\n sections[currentKey] = currentLines.join('\\n').trim();\n }\n\n foundAnyH1 = true;\n const heading = h1Match[1].trim().toLowerCase();\n currentKey = SECTION_MAP[heading] ?? null;\n currentLines = [];\n } else {\n currentLines.push(line);\n }\n }\n\n // Flush last section\n if (currentKey) {\n sections[currentKey] = currentLines.join('\\n').trim();\n }\n\n // If no H1 headings found, treat entire body as prompt_template\n if (!foundAnyH1) {\n const trimmed = body.trim();\n if (trimmed) {\n sections.prompt_template = trimmed;\n }\n }\n\n return sections;\n}\n","import { readFile } from 'node:fs/promises';\nimport { dirname, join, relative, resolve } from 'node:path';\nimport matter from 'gray-matter';\nimport { parsePrompt } from './parser.js';\nimport type { ParseResult } from './parser.js';\nimport { extractSections } from './sections.js';\nimport { PromptDefaultsSchema } from '../schema/index.js';\nimport type { PromptDefaults } from '../schema/index.js';\nimport { resolveResponseSchemaRef } from './response-schema-ref.js';\n\nconst DEFAULTS_FILE_NAME = 'defaults.md';\n\nexport interface LoadPromptOptions {\n /**\n * Optional boundary directory for defaults discovery.\n * If provided, defaults are loaded from this directory down to the prompt directory.\n */\n defaultsRoot?: string;\n}\n\n/**\n * Load and parse a prompt file from disk.\n */\nexport async function loadPromptFile(filePath: string, options: LoadPromptOptions = {}): Promise<ParseResult> {\n const content = await readFile(filePath, 'utf-8');\n const parsed = parsePrompt(content, filePath);\n // Default the boundary to the file's own directory so traversal never\n // walks above the prompt tree when no explicit root is provided.\n const root = options.defaultsRoot ?? dirname(filePath);\n const defaults = await loadDefaultsForPath(filePath, root);\n const withDefaults = applyDefaults(parsed.asset, defaults);\n const resolved = await resolveResponseSchemaRef(withDefaults, filePath);\n const asset = (resolved.response?.schema !== undefined && !resolved.response?.schema_source)\n ? {\n ...resolved,\n response: {\n ...resolved.response,\n schema_source: { mode: 'inline' as const },\n },\n }\n : resolved;\n\n return {\n ...parsed,\n asset,\n };\n}\n\nasync function loadDefaultsForPath(filePath: string, defaultsRoot?: string): Promise<PromptDefaults> {\n const directories = getDirectoriesToCheck(filePath, defaultsRoot);\n let merged: PromptDefaults = {};\n\n for (const dir of directories) {\n const defaultsPath = join(dir, DEFAULTS_FILE_NAME);\n try {\n const defaultsContent = await readFile(defaultsPath, 'utf-8');\n const defaults = normalizeDefaultIncludes(parseDefaults(defaultsContent), defaultsPath, filePath);\n merged = mergeDefaults(merged, defaults);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw error;\n }\n }\n }\n\n return merged;\n}\n\nfunction getDirectoriesToCheck(filePath: string, defaultsRoot?: string): string[] {\n const dirs: string[] = [];\n let current = resolve(dirname(filePath));\n const boundary = defaultsRoot ? resolve(defaultsRoot) : undefined;\n\n while (true) {\n dirs.unshift(current);\n if ((boundary && current === boundary) || current === dirname(current)) {\n break;\n }\n current = dirname(current);\n }\n\n return dirs;\n}\n\nfunction parseDefaults(content: string): PromptDefaults {\n const { data: frontMatter, content: body } = matter(content);\n const sections = extractSections(body);\n\n return PromptDefaultsSchema.parse({\n ...frontMatter,\n sections: {\n system_instructions: sections.system_instructions,\n },\n });\n}\n\nfunction mergeDefaults(base: PromptDefaults, local: PromptDefaults): PromptDefaults {\n return {\n provider: local.provider ?? base.provider,\n model: local.model ?? base.model,\n fallback_models: local.fallback_models ?? base.fallback_models,\n reasoning: mergeRecordBlock(base.reasoning, local.reasoning),\n sampling: mergeRecordBlock(base.sampling, local.sampling),\n response: mergeRecordBlock(base.response, local.response),\n compression: mergeCompression(base.compression, local.compression),\n cache: mergeCache(base.cache, local.cache),\n raw: mergeRaw(base.raw, local.raw),\n tools: local.tools ?? base.tools,\n provider_options: mergeProviderOptions(base.provider_options, local.provider_options),\n mcp: mergeMcp(base.mcp, local.mcp),\n context: mergeContext(base.context, local.context),\n includes: local.includes ?? base.includes,\n environments: mergeOverrideMap(base.environments, local.environments),\n tiers: mergeOverrideMap(base.tiers, local.tiers),\n metadata: {\n ...(base.metadata ?? {}),\n ...(local.metadata ?? {}),\n },\n sections: {\n ...(base.sections ?? {}),\n ...(local.sections ?? {}),\n },\n };\n}\n\nfunction applyDefaults(asset: ParseResult['asset'], defaults: PromptDefaults): ParseResult['asset'] {\n const compression = mergeCompression(defaults.compression, asset.compression);\n const cache = mergeCache(defaults.cache, asset.cache);\n const raw = mergeRaw(defaults.raw, asset.raw);\n const providerOptions = mergeProviderOptions(defaults.provider_options, asset.provider_options);\n const reasoning = mergeRecordBlock(defaults.reasoning, asset.reasoning);\n const sampling = mergeRecordBlock(defaults.sampling, asset.sampling);\n const response = mergeRecordBlock(defaults.response, asset.response);\n const mcp = mergeMcp(defaults.mcp, asset.mcp);\n const context = mergeContext(defaults.context, asset.context);\n const environments = mergeOverrideMap(defaults.environments, asset.environments);\n const tiers = mergeOverrideMap(defaults.tiers, asset.tiers);\n const hasDefaultMetadata = defaults.metadata && Object.keys(defaults.metadata).length > 0;\n const hasDefaultSystem = !!defaults.sections?.system_instructions;\n const hasDefaultScalars = defaults.provider !== undefined\n || defaults.model !== undefined\n || defaults.fallback_models !== undefined\n || defaults.tools !== undefined\n || defaults.includes !== undefined;\n const hasDefaultObjects = compression !== undefined\n || cache !== undefined\n || raw !== undefined\n || providerOptions !== undefined\n || reasoning !== undefined\n || sampling !== undefined\n || response !== undefined\n || mcp !== undefined\n || context !== undefined\n || environments !== undefined\n || tiers !== undefined;\n\n // Short-circuit: nothing to merge\n if (!hasDefaultMetadata && !hasDefaultSystem && !hasDefaultScalars && !hasDefaultObjects) {\n return asset;\n }\n\n const mergedMetadata = {\n ...(defaults.metadata ?? {}),\n ...(asset.metadata ?? {}),\n };\n const metadata = Object.keys(mergedMetadata).length > 0 ? mergedMetadata : undefined;\n\n const systemInstructions = asset.sections?.system_instructions ?? defaults.sections?.system_instructions;\n\n const sections = asset.sections\n ? { ...asset.sections, system_instructions: systemInstructions }\n : systemInstructions\n ? { system_instructions: systemInstructions }\n : undefined;\n\n return {\n ...asset,\n provider: asset.provider ?? defaults.provider,\n model: asset.model ?? defaults.model,\n fallback_models: asset.fallback_models ?? defaults.fallback_models,\n reasoning,\n sampling,\n response,\n compression,\n cache,\n raw,\n tools: asset.tools ?? defaults.tools,\n provider_options: providerOptions,\n mcp,\n context,\n includes: asset.includes ?? defaults.includes,\n environments,\n tiers,\n metadata,\n sections,\n };\n}\n\nfunction normalizeDefaultIncludes(\n defaults: PromptDefaults,\n defaultsPath: string,\n filePath: string,\n): PromptDefaults {\n if (!defaults.includes) return defaults;\n\n const promptDir = dirname(filePath);\n const defaultsDir = dirname(defaultsPath);\n const includes = defaults.includes.map((includePath) => {\n const relativePath = relative(promptDir, resolve(defaultsDir, includePath)).replace(/\\\\/g, '/');\n return relativePath.startsWith('.') ? relativePath : `./${relativePath}`;\n });\n\n return {\n ...defaults,\n includes,\n };\n}\n\nfunction mergeRecordBlock<T extends object>(base: T | undefined, local: T | undefined): T | undefined {\n if (base === undefined) return local;\n if (local === undefined) return base;\n return { ...base, ...local };\n}\n\nfunction mergeMcp(base: PromptDefaults['mcp'], local: PromptDefaults['mcp']): PromptDefaults['mcp'] {\n return mergeRecordBlock(base, local);\n}\n\nfunction mergeContext(base: PromptDefaults['context'], local: PromptDefaults['context']): PromptDefaults['context'] {\n const merged = {\n ...(base ?? {}),\n ...(local ?? {}),\n history: mergeRecordBlock(base?.history, local?.history),\n };\n\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction mergeCache(base: PromptDefaults['cache'], local: PromptDefaults['cache']): PromptDefaults['cache'] {\n const merged: NonNullable<PromptDefaults['cache']> = {\n ...(base ?? {}),\n ...(local ?? {}),\n openai: {\n ...(base?.openai ?? {}),\n ...(local?.openai ?? {}),\n },\n anthropic: {\n ...(base?.anthropic ?? {}),\n ...(local?.anthropic ?? {}),\n },\n gemini: {\n ...(base?.gemini ?? {}),\n ...(local?.gemini ?? {}),\n },\n google: {\n ...(base?.google ?? {}),\n ...(local?.google ?? {}),\n },\n };\n\n if (merged.openai && Object.keys(merged.openai).length === 0) delete merged.openai;\n if (merged.anthropic && Object.keys(merged.anthropic).length === 0) delete merged.anthropic;\n if (merged.gemini && Object.keys(merged.gemini).length === 0) delete merged.gemini;\n if (merged.google && Object.keys(merged.google).length === 0) delete merged.google;\n\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction mergeCompression(\n base: PromptDefaults['compression'],\n local: PromptDefaults['compression'],\n): PromptDefaults['compression'] {\n const merged: NonNullable<PromptDefaults['compression']> = {\n ...(base ?? {}),\n ...(local ?? {}),\n thetokencompany: mergeRecordBlock(base?.thetokencompany, local?.thetokencompany),\n heuristic: mergeRecordBlock(base?.heuristic, local?.heuristic),\n code: mergeRecordBlock(base?.code, local?.code),\n };\n\n removeEmptyProviderBlocks(merged);\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction mergeRaw(base: PromptDefaults['raw'], local: PromptDefaults['raw']): PromptDefaults['raw'] {\n const merged: NonNullable<PromptDefaults['raw']> = {\n ...(base ?? {}),\n ...(local ?? {}),\n openai: mergeRecordBlock(base?.openai, local?.openai),\n 'openai-responses': mergeRecordBlock(base?.['openai-responses'], local?.['openai-responses']),\n openai_responses: mergeRecordBlock(base?.openai_responses, local?.openai_responses),\n anthropic: mergeRecordBlock(base?.anthropic, local?.anthropic),\n gemini: mergeRecordBlock(base?.gemini, local?.gemini),\n google: mergeRecordBlock(base?.google, local?.google),\n openrouter: mergeRecordBlock(base?.openrouter, local?.openrouter),\n llmasaservice: mergeRecordBlock(base?.llmasaservice, local?.llmasaservice),\n };\n\n removeEmptyProviderBlocks(merged);\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction mergeProviderOptions(\n base: PromptDefaults['provider_options'],\n local: PromptDefaults['provider_options'],\n): PromptDefaults['provider_options'] {\n const merged: NonNullable<PromptDefaults['provider_options']> = {\n ...(base ?? {}),\n ...(local ?? {}),\n anthropic: mergeRecordBlock(base?.anthropic, local?.anthropic),\n gemini: mergeRecordBlock(base?.gemini, local?.gemini),\n openrouter: mergeRecordBlock(base?.openrouter, local?.openrouter),\n llmasaservice: mergeRecordBlock(base?.llmasaservice, local?.llmasaservice),\n };\n\n removeEmptyProviderBlocks(merged);\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction mergeOverrideMap(\n base: PromptDefaults['environments'],\n local: PromptDefaults['environments'],\n): PromptDefaults['environments'] {\n const merged: NonNullable<PromptDefaults['environments']> = { ...(base ?? {}) };\n\n for (const [name, localOverride] of Object.entries(local ?? {})) {\n merged[name] = mergeOverrideConfig(merged[name], localOverride);\n }\n\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction mergeOverrideConfig(\n base: NonNullable<PromptDefaults['environments']>[string] | undefined,\n local: NonNullable<PromptDefaults['environments']>[string],\n): NonNullable<PromptDefaults['environments']>[string] {\n const merged: NonNullable<PromptDefaults['environments']>[string] = {\n ...(base ?? {}),\n ...local,\n };\n\n const reasoning = mergeRecordBlock(base?.reasoning, local.reasoning);\n const sampling = mergeRecordBlock(base?.sampling, local.sampling);\n const response = mergeRecordBlock(base?.response, local.response);\n const compression = mergeCompression(base?.compression, local.compression);\n const cache = mergeCache(base?.cache, local.cache);\n const raw = mergeRaw(base?.raw, local.raw);\n const providerOptions = mergeProviderOptions(base?.provider_options, local.provider_options);\n\n if (reasoning !== undefined) merged.reasoning = reasoning;\n if (sampling !== undefined) merged.sampling = sampling;\n if (response !== undefined) merged.response = response;\n if (compression !== undefined) merged.compression = compression;\n if (cache !== undefined) merged.cache = cache;\n if (raw !== undefined) merged.raw = raw;\n if (providerOptions !== undefined) merged.provider_options = providerOptions;\n\n return merged;\n}\n\nfunction removeEmptyProviderBlocks<T extends Record<string, unknown>>(value: T): void {\n for (const key of Object.keys(value)) {\n const block = value[key];\n if (block === undefined) {\n delete value[key];\n continue;\n }\n\n if (\n block !== null\n &&\n typeof block === 'object'\n && !Array.isArray(block)\n && Object.keys(block).length === 0\n ) {\n delete value[key];\n }\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { createHash } from 'node:crypto';\nimport { dirname, extname, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { z } from 'zod';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\nimport type { PromptAsset } from '../schema/index.js';\n\nconst SUPPORTED_SCHEMA_REF_EXTENSIONS = new Set(['.json', '.js', '.mjs', '.cjs']);\n\n\nasync function resolveJsonSchemaRef(schemaRef: string, promptFilePath: string): Promise<{ schema: Record<string, unknown>; resolvedPath: string; hash: string }> {\n const resolvedPath = resolve(dirname(promptFilePath), schemaRef);\n let raw: string;\n\n try {\n raw = await readFile(resolvedPath, 'utf-8');\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') {\n throw new Error(`POK050: response.schema_ref \"${schemaRef}\" not found (resolved from ${promptFilePath})`);\n }\n throw error;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new Error(`POK050: response.schema_ref \"${schemaRef}\" is not valid JSON`);\n }\n\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error(`POK050: response.schema_ref \"${schemaRef}\" must resolve to a JSON object schema`);\n }\n\n return {\n schema: parsed as Record<string, unknown>,\n resolvedPath,\n hash: createHash('sha256').update(raw).digest('hex'),\n };\n}\n\nasync function resolveZodSchemaRef(schemaRef: string, promptFilePath: string): Promise<{ schema: Record<string, unknown>; resolvedPath: string; hash: string }> {\n const resolvedPath = resolve(dirname(promptFilePath), schemaRef);\n\n let moduleSource: string;\n try {\n moduleSource = await readFile(resolvedPath, 'utf-8');\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') {\n throw new Error(`POK051: response.schema_ref \"${schemaRef}\" not found (resolved from ${promptFilePath})`);\n }\n throw error;\n }\n\n let imported: unknown;\n try {\n imported = await import(pathToFileURL(resolvedPath).href);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`POK051: response.schema_ref \"${schemaRef}\" could not be imported as a module (${message})`);\n }\n\n const mod = imported as Record<string, unknown>;\n const candidate = mod.default ?? mod.schema;\n\n if (!(candidate instanceof z.ZodType)) {\n throw new Error('POK051: zod schema modules must export a Zod schema as default export or named export \"schema\"');\n }\n\n const jsonSchema = zodToJsonSchema(candidate, {\n target: 'jsonSchema7',\n $refStrategy: 'none',\n });\n\n if (!jsonSchema || typeof jsonSchema !== 'object' || Array.isArray(jsonSchema)) {\n throw new Error(`POK051: response.schema_ref \"${schemaRef}\" did not produce a valid JSON schema object`);\n }\n\n return {\n schema: jsonSchema as Record<string, unknown>,\n resolvedPath,\n hash: createHash('sha256').update(moduleSource).digest('hex'),\n };\n}\n\nexport async function resolveResponseSchemaRef(asset: PromptAsset, promptFilePath: string): Promise<PromptAsset> {\n const schemaRef = asset.response?.schema_ref;\n if (!schemaRef) return asset;\n\n const ext = extname(schemaRef).toLowerCase();\n if (!SUPPORTED_SCHEMA_REF_EXTENSIONS.has(ext)) {\n throw new Error(`POK051: response.schema_ref \"${schemaRef}\" has unsupported extension \"${ext}\". Use .json, .js, .mjs, or .cjs`);\n }\n\n const resolved = (ext === '.json')\n ? await resolveJsonSchemaRef(schemaRef, promptFilePath)\n : await resolveZodSchemaRef(schemaRef, promptFilePath);\n\n return {\n ...asset,\n response: {\n ...asset.response,\n schema: resolved.schema,\n schema_ref: undefined,\n schema_source: {\n mode: ext === '.json' ? 'schema_ref_json' : 'schema_ref_zod_module',\n ref: schemaRef,\n resolved_path: resolved.resolvedPath,\n hash: resolved.hash,\n },\n },\n };\n}\n"],"mappings":"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","names":["import_promises","import_gray_matter","indent","matter","import_promises","import_node_path","import_gray_matter","import_zod","matter"]}
@@ -1,4 +1,4 @@
1
- import { P as PromptAsset, R as ResolvedPromptAsset } from './schema-DBcSns_b.cjs';
1
+ import { P as PromptAsset, R as ResolvedPromptAsset } from './schema-BgVLZ2u5.cjs';
2
2
  import 'zod';
3
3
 
4
4
  interface PromptTestCase<TResponse = unknown> {
package/dist/testing.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { P as PromptAsset, R as ResolvedPromptAsset } from './schema-DBcSns_b.js';
1
+ import { P as PromptAsset, R as ResolvedPromptAsset } from './schema-BgVLZ2u5.js';
2
2
  import 'zod';
3
3
 
4
4
  interface PromptTestCase<TResponse = unknown> {
package/dist/testing.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  parsePrompt
3
- } from "./chunk-ULVY473P.js";
3
+ } from "./chunk-E4GEKWVP.js";
4
4
 
5
5
  // src/testing.ts
6
6
  import { readFile } from "fs/promises";
@@ -1,4 +1,4 @@
1
- import { a as PromptAssetOverrides, R as ResolvedPromptAsset } from './schema-DBcSns_b.js';
1
+ import { a as PromptAssetOverrides, R as ResolvedPromptAsset } from './schema-BgVLZ2u5.cjs';
2
2
 
3
3
  type PromptResolutionMode = 'auto' | 'compiled-only' | 'source-only';
4
4
 
@@ -10,13 +10,24 @@ interface TheTokenCompanyRuntimeOptions {
10
10
  fetch?: typeof fetch;
11
11
  }
12
12
  interface PromptCompressionResult {
13
- provider: 'thetokencompany';
13
+ provider: 'thetokencompany' | 'heuristic' | 'code';
14
14
  model: string;
15
15
  inputTokens: number;
16
16
  outputTokens: number;
17
17
  tokensSaved: number;
18
18
  compressionRatio: number;
19
+ scope?: 'prompt_template' | 'placeholder';
20
+ variable?: string;
21
+ outputFormat?: 'toon' | 'code';
19
22
  }
23
+ interface PromptCompressionSummary {
24
+ steps: number;
25
+ inputTokens: number;
26
+ outputTokens: number;
27
+ tokensSaved: number;
28
+ reductionRatio: number;
29
+ }
30
+ declare function summarizePromptCompression(compression?: PromptCompressionResult[]): PromptCompressionSummary;
20
31
 
21
32
  /**
22
33
  * Provider-shaped request body output.
@@ -28,6 +39,8 @@ interface ProviderRequest {
28
39
  baseURL?: string;
29
40
  headers?: Record<string, string>;
30
41
  compression?: PromptCompressionResult[];
42
+ compressionSummary?: PromptCompressionSummary;
43
+ warnings?: string[];
31
44
  }
32
45
  interface ProviderPromptReturnMessageResult {
33
46
  provider: string;
@@ -121,4 +134,4 @@ interface ProviderAdapter {
121
134
  renderPrompt: RenderPromptMethod;
122
135
  }
123
136
 
124
- export { type OpenAIResponsesRuntimeOptions as O, type ProviderAdapter as P, type RuntimeRenderOptions as R, THETOKENCOMPANY_DEFAULT_BASE_URL as T, type ValidationResult as V, type ProviderRequest as a, type PromptCompressionResult as b, type ProviderInlinePromptSource as c, type ProviderPromptInput as d, type ProviderPromptLookup as e, type ProviderPromptRenderResult as f, type RuntimeHistoryCompactionInfo as g, type RuntimeHistoryCompactionResult as h, type RuntimeHistoryMessage as i, THETOKENCOMPANY_DEFAULT_MODEL as j, type TheTokenCompanyRuntimeOptions as k };
137
+ export { type OpenAIResponsesRuntimeOptions as O, type ProviderAdapter as P, type RuntimeRenderOptions as R, THETOKENCOMPANY_DEFAULT_BASE_URL as T, type ValidationResult as V, type ProviderRequest as a, type PromptCompressionResult as b, type PromptCompressionSummary as c, type ProviderInlinePromptSource as d, type ProviderPromptInput as e, type ProviderPromptLookup as f, type ProviderPromptRenderResult as g, type RuntimeHistoryCompactionInfo as h, type RuntimeHistoryCompactionResult as i, type RuntimeHistoryMessage as j, THETOKENCOMPANY_DEFAULT_MODEL as k, type TheTokenCompanyRuntimeOptions as l, summarizePromptCompression as s };
@@ -1,4 +1,4 @@
1
- import { a as PromptAssetOverrides, R as ResolvedPromptAsset } from './schema-DBcSns_b.cjs';
1
+ import { a as PromptAssetOverrides, R as ResolvedPromptAsset } from './schema-BgVLZ2u5.js';
2
2
 
3
3
  type PromptResolutionMode = 'auto' | 'compiled-only' | 'source-only';
4
4
 
@@ -10,13 +10,24 @@ interface TheTokenCompanyRuntimeOptions {
10
10
  fetch?: typeof fetch;
11
11
  }
12
12
  interface PromptCompressionResult {
13
- provider: 'thetokencompany';
13
+ provider: 'thetokencompany' | 'heuristic' | 'code';
14
14
  model: string;
15
15
  inputTokens: number;
16
16
  outputTokens: number;
17
17
  tokensSaved: number;
18
18
  compressionRatio: number;
19
+ scope?: 'prompt_template' | 'placeholder';
20
+ variable?: string;
21
+ outputFormat?: 'toon' | 'code';
19
22
  }
23
+ interface PromptCompressionSummary {
24
+ steps: number;
25
+ inputTokens: number;
26
+ outputTokens: number;
27
+ tokensSaved: number;
28
+ reductionRatio: number;
29
+ }
30
+ declare function summarizePromptCompression(compression?: PromptCompressionResult[]): PromptCompressionSummary;
20
31
 
21
32
  /**
22
33
  * Provider-shaped request body output.
@@ -28,6 +39,8 @@ interface ProviderRequest {
28
39
  baseURL?: string;
29
40
  headers?: Record<string, string>;
30
41
  compression?: PromptCompressionResult[];
42
+ compressionSummary?: PromptCompressionSummary;
43
+ warnings?: string[];
31
44
  }
32
45
  interface ProviderPromptReturnMessageResult {
33
46
  provider: string;
@@ -121,4 +134,4 @@ interface ProviderAdapter {
121
134
  renderPrompt: RenderPromptMethod;
122
135
  }
123
136
 
124
- export { type OpenAIResponsesRuntimeOptions as O, type ProviderAdapter as P, type RuntimeRenderOptions as R, THETOKENCOMPANY_DEFAULT_BASE_URL as T, type ValidationResult as V, type ProviderRequest as a, type PromptCompressionResult as b, type ProviderInlinePromptSource as c, type ProviderPromptInput as d, type ProviderPromptLookup as e, type ProviderPromptRenderResult as f, type RuntimeHistoryCompactionInfo as g, type RuntimeHistoryCompactionResult as h, type RuntimeHistoryMessage as i, THETOKENCOMPANY_DEFAULT_MODEL as j, type TheTokenCompanyRuntimeOptions as k };
137
+ export { type OpenAIResponsesRuntimeOptions as O, type ProviderAdapter as P, type RuntimeRenderOptions as R, THETOKENCOMPANY_DEFAULT_BASE_URL as T, type ValidationResult as V, type ProviderRequest as a, type PromptCompressionResult as b, type PromptCompressionSummary as c, type ProviderInlinePromptSource as d, type ProviderPromptInput as e, type ProviderPromptLookup as f, type ProviderPromptRenderResult as g, type RuntimeHistoryCompactionInfo as h, type RuntimeHistoryCompactionResult as i, type RuntimeHistoryMessage as j, THETOKENCOMPANY_DEFAULT_MODEL as k, type TheTokenCompanyRuntimeOptions as l, summarizePromptCompression as s };
@@ -1,5 +1,5 @@
1
- import { a as ProviderRequest } from '../types-8T2D5KB5.cjs';
2
- import '../schema-DBcSns_b.cjs';
1
+ import { a as ProviderRequest } from '../types-2hnZmCkH.cjs';
2
+ import '../schema-BgVLZ2u5.cjs';
3
3
  import 'zod';
4
4
 
5
5
  type UsageTapReasoningLevel = 'NONE' | 'LOW' | 'MEDIUM' | 'HIGH';
@@ -1,5 +1,5 @@
1
- import { a as ProviderRequest } from '../types-BlLXT5Qb.js';
2
- import '../schema-DBcSns_b.js';
1
+ import { a as ProviderRequest } from '../types-DgAT4jSR.js';
2
+ import '../schema-BgVLZ2u5.js';
3
3
  import 'zod';
4
4
 
5
5
  type UsageTapReasoningLevel = 'NONE' | 'LOW' | 'MEDIUM' | 'HIGH';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "promptopskit",
3
- "version": "0.7.1",
3
+ "version": "0.8.1",
4
4
  "description": "Manage prompts, system instructions, tools, and model settings as code",
5
5
  "type": "module",
6
6
  "bin": {