promptopskit 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +98 -57
  2. package/SKILL.md +360 -6
  3. package/dist/chunk-6BOUQVSX.js +130 -0
  4. package/dist/chunk-6BOUQVSX.js.map +1 -0
  5. package/dist/{chunk-F6UJ73Y6.js → chunk-6VLKZCNS.js} +6 -4
  6. package/dist/chunk-6VLKZCNS.js.map +1 -0
  7. package/dist/{chunk-HWEVRBKZ.js → chunk-AGTGIZMR.js} +6 -2
  8. package/dist/chunk-AGTGIZMR.js.map +1 -0
  9. package/dist/{chunk-L2V7LDKD.js → chunk-D75HKF64.js} +6 -4
  10. package/dist/chunk-D75HKF64.js.map +1 -0
  11. package/dist/{chunk-UPTCSWK3.js → chunk-IN4KT5EU.js} +4 -3
  12. package/dist/chunk-IN4KT5EU.js.map +1 -0
  13. package/dist/{chunk-JBLUPKY4.js → chunk-K6ZU3CGV.js} +54 -6
  14. package/dist/chunk-K6ZU3CGV.js.map +1 -0
  15. package/dist/{chunk-XNNDGDPI.js → chunk-KN7H4JRK.js} +61 -4
  16. package/dist/chunk-KN7H4JRK.js.map +1 -0
  17. package/dist/{chunk-HLNVKKMS.js → chunk-LNGHGGJN.js} +6 -4
  18. package/dist/chunk-LNGHGGJN.js.map +1 -0
  19. package/dist/{chunk-RY5DVTLV.js → chunk-QK3WKE3K.js} +6 -4
  20. package/dist/chunk-QK3WKE3K.js.map +1 -0
  21. package/dist/cli/index.js +114 -55
  22. package/dist/cli/index.js.map +1 -1
  23. package/dist/index.cjs +265 -22
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.cts +9 -9
  26. package/dist/index.d.ts +9 -9
  27. package/dist/index.js +32 -10
  28. package/dist/index.js.map +1 -1
  29. package/dist/providers/anthropic.cjs +114 -9
  30. package/dist/providers/anthropic.cjs.map +1 -1
  31. package/dist/providers/anthropic.d.cts +2 -2
  32. package/dist/providers/anthropic.d.ts +2 -2
  33. package/dist/providers/anthropic.js +3 -3
  34. package/dist/providers/gemini.cjs +114 -9
  35. package/dist/providers/gemini.cjs.map +1 -1
  36. package/dist/providers/gemini.d.cts +2 -2
  37. package/dist/providers/gemini.d.ts +2 -2
  38. package/dist/providers/gemini.js +3 -3
  39. package/dist/providers/llmasaservice.cjs +1467 -0
  40. package/dist/providers/llmasaservice.cjs.map +1 -0
  41. package/dist/providers/llmasaservice.d.cts +28 -0
  42. package/dist/providers/llmasaservice.d.ts +28 -0
  43. package/dist/providers/llmasaservice.js +20 -0
  44. package/dist/providers/llmasaservice.js.map +1 -0
  45. package/dist/providers/openai-responses.cjs +114 -9
  46. package/dist/providers/openai-responses.cjs.map +1 -1
  47. package/dist/providers/openai-responses.d.cts +2 -2
  48. package/dist/providers/openai-responses.d.ts +2 -2
  49. package/dist/providers/openai-responses.js +3 -3
  50. package/dist/providers/openai.cjs +114 -9
  51. package/dist/providers/openai.cjs.map +1 -1
  52. package/dist/providers/openai.d.cts +2 -2
  53. package/dist/providers/openai.d.ts +2 -2
  54. package/dist/providers/openai.js +3 -3
  55. package/dist/providers/openrouter.cjs +115 -9
  56. package/dist/providers/openrouter.cjs.map +1 -1
  57. package/dist/providers/openrouter.d.cts +2 -2
  58. package/dist/providers/openrouter.d.ts +2 -2
  59. package/dist/providers/openrouter.js +4 -4
  60. package/dist/{schema-B9A1zLRk.d.cts → schema-D-RI4w-k.d.cts} +695 -183
  61. package/dist/{schema-B9A1zLRk.d.ts → schema-D-RI4w-k.d.ts} +695 -183
  62. package/dist/testing.cjs +21 -4
  63. package/dist/testing.cjs.map +1 -1
  64. package/dist/testing.d.cts +1 -1
  65. package/dist/testing.d.ts +1 -1
  66. package/dist/testing.js +1 -1
  67. package/dist/{types-DjGAwJxC.d.ts → types-B3dxBGu6.d.ts} +18 -6
  68. package/dist/{types-DpbzzZO2.d.cts → types-DbTAjlTN.d.cts} +18 -6
  69. package/dist/usagetap/index.cjs +6 -1
  70. package/dist/usagetap/index.cjs.map +1 -1
  71. package/dist/usagetap/index.d.cts +4 -3
  72. package/dist/usagetap/index.d.ts +4 -3
  73. package/dist/usagetap/index.js +3 -1
  74. package/package.json +11 -1
  75. package/dist/chunk-F6UJ73Y6.js.map +0 -1
  76. package/dist/chunk-HLNVKKMS.js.map +0 -1
  77. package/dist/chunk-HWEVRBKZ.js.map +0 -1
  78. package/dist/chunk-JBLUPKY4.js.map +0 -1
  79. package/dist/chunk-L2V7LDKD.js.map +0 -1
  80. package/dist/chunk-RY5DVTLV.js.map +0 -1
  81. package/dist/chunk-UPTCSWK3.js.map +0 -1
  82. package/dist/chunk-XNNDGDPI.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/providers/anthropic.ts"],"sourcesContent":["import type { ResolvedPromptAsset } from '../schema/index.js';\nimport type {\n ProviderAdapter,\n ProviderRequest,\n ValidationResult,\n RuntimeRenderOptions,\n} from './types.js';\nimport { renderSections } from '../renderer/index.js';\nimport { resolveAssetForProvider } from './resolve-asset.js';\nimport { withPromptInputSupport } from './prompt-input.js';\nimport { applyRawProviderBody } from './raw.js';\nimport { compactHistoryForPrompt } from '../history.js';\n\n/**\n * Anthropic provider adapter.\n * Produces request bodies compatible with the Anthropic Messages API.\n */\nexport const anthropicAdapter: ProviderAdapter = withPromptInputSupport({\n name: 'anthropic',\n\n validate(asset: ResolvedPromptAsset, runtime?: RuntimeRenderOptions): ValidationResult {\n const resolvedAsset = resolveAssetForProvider(asset, runtime);\n const errors: string[] = [];\n const warnings: string[] = [];\n\n if (!resolvedAsset.model) {\n errors.push('Anthropic adapter requires a model to be specified.');\n }\n\n if (resolvedAsset.sampling?.frequency_penalty !== undefined) {\n warnings.push('Anthropic does not support frequency_penalty. It will be ignored.');\n }\n if (resolvedAsset.sampling?.presence_penalty !== undefined) {\n warnings.push('Anthropic does not support presence_penalty. It will be ignored.');\n }\n if (resolvedAsset.reasoning?.effort !== undefined) {\n warnings.push('Anthropic uses budget_tokens for thinking, not effort. effort will be mapped approximately.');\n }\n if (resolvedAsset.response?.schema !== undefined && resolvedAsset.response?.format !== 'json') {\n warnings.push('Anthropic response.schema is mapped to output_config.format and should usually be paired with response.format: json.');\n }\n\n if (resolvedAsset.provider_options?.anthropic?.top_k !== undefined && resolvedAsset.provider_options.anthropic.top_k < 0) {\n errors.push('Anthropic provider_options.top_k must be >= 0.');\n }\n\n return { valid: errors.length === 0, errors, warnings };\n },\n\n render(asset: ResolvedPromptAsset, runtime: RuntimeRenderOptions): ProviderRequest {\n const resolvedAsset = resolveAssetForProvider(asset, runtime);\n const sections = renderSections(resolvedAsset, {\n variables: runtime.variables,\n strict: runtime.strict,\n });\n\n const messages: Array<Record<string, unknown>> = [];\n const anthropicCacheConfig = resolvedAsset.cache?.anthropic;\n const cacheType = anthropicCacheConfig?.type ?? 'ephemeral';\n const cacheControl = anthropicCacheConfig\n ? {\n type: cacheType,\n ...(anthropicCacheConfig.ttl ? { ttl: anthropicCacheConfig.ttl } : {}),\n }\n : undefined;\n const cacheMode = anthropicCacheConfig?.mode ?? 'automatic';\n\n // History\n const history = compactHistoryForPrompt(resolvedAsset, runtime);\n if (history) {\n for (const msg of history) {\n messages.push({ role: msg.role, content: msg.content });\n }\n }\n\n // User message (prompt template)\n if (sections.prompt_template) {\n if (cacheControl && cacheMode === 'explicit' && anthropicCacheConfig?.cache_prompt_template) {\n messages.push({\n role: 'user',\n content: [{ type: 'text', text: sections.prompt_template, cache_control: cacheControl }],\n });\n } else {\n messages.push({ role: 'user', content: sections.prompt_template });\n }\n }\n\n const body: Record<string, unknown> = {\n model: resolvedAsset.model,\n messages,\n };\n\n // System goes as top-level field in Anthropic\n if (sections.system_instructions) {\n if (cacheControl && cacheMode === 'explicit' && anthropicCacheConfig?.cache_system_instructions !== false) {\n body.system = [{ type: 'text', text: sections.system_instructions, cache_control: cacheControl }];\n } else {\n body.system = sections.system_instructions;\n }\n }\n\n // Sampling params\n if (resolvedAsset.sampling?.temperature !== undefined) body.temperature = resolvedAsset.sampling.temperature;\n if (resolvedAsset.sampling?.top_p !== undefined) body.top_p = resolvedAsset.sampling.top_p;\n if (resolvedAsset.sampling?.stop !== undefined) body.stop_sequences = resolvedAsset.sampling.stop;\n if (resolvedAsset.sampling?.max_output_tokens !== undefined) {\n body.max_tokens = resolvedAsset.sampling.max_output_tokens;\n } else {\n // Anthropic requires max_tokens\n body.max_tokens = 4096;\n }\n\n // Thinking/reasoning\n if (resolvedAsset.reasoning?.budget_tokens) {\n body.thinking = {\n type: 'enabled',\n budget_tokens: resolvedAsset.reasoning.budget_tokens,\n };\n }\n\n // Provider-specific options\n if (resolvedAsset.provider_options?.anthropic?.top_k !== undefined) {\n body.top_k = resolvedAsset.provider_options.anthropic.top_k;\n }\n\n if (resolvedAsset.provider_options?.anthropic?.output_config !== undefined) {\n body.output_config = resolvedAsset.provider_options.anthropic.output_config;\n } else if (resolvedAsset.response?.schema !== undefined) {\n body.output_config = {\n format: {\n type: 'json_schema',\n schema: resolvedAsset.response.schema,\n },\n };\n }\n\n // Streaming\n if (resolvedAsset.response?.stream !== undefined) {\n body.stream = resolvedAsset.response.stream;\n }\n\n if (cacheControl && cacheMode === 'automatic') {\n body.cache_control = cacheControl;\n }\n\n // Tools\n if (resolvedAsset.tools && resolvedAsset.tools.length > 0) {\n body.tools = resolvedAsset.tools.map((tool) => {\n if (typeof tool === 'string') {\n const def = runtime.toolRegistry?.[tool];\n if (def) {\n if (cacheControl && cacheMode === 'explicit' && anthropicCacheConfig?.cache_tools) {\n return { ...(def as Record<string, unknown>), cache_control: cacheControl };\n }\n return def;\n }\n return {\n name: tool,\n ...(cacheControl && cacheMode === 'explicit' && anthropicCacheConfig?.cache_tools\n ? { cache_control: cacheControl }\n : {}),\n };\n }\n return {\n name: tool.name,\n description: tool.description,\n input_schema: tool.input_schema ?? { type: 'object', properties: {} },\n ...(cacheControl && cacheMode === 'explicit' && anthropicCacheConfig?.cache_tools\n ? { cache_control: cacheControl }\n : {}),\n };\n });\n }\n\n if (resolvedAsset.provider_options?.anthropic?.tool_choice !== undefined) {\n body.tool_choice = resolvedAsset.provider_options.anthropic.tool_choice;\n }\n\n return {\n body: applyRawProviderBody(body, resolvedAsset, 'anthropic'),\n provider: 'anthropic',\n model: resolvedAsset.model ?? 'unknown',\n };\n },\n});\n"],"mappings":"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","names":[]}
@@ -1,9 +1,10 @@
1
1
  import {
2
2
  applyRawProviderBody,
3
+ compactHistoryForPrompt,
3
4
  renderSections,
4
5
  resolveAssetForProvider,
5
6
  withPromptInputSupport
6
- } from "./chunk-XNNDGDPI.js";
7
+ } from "./chunk-KN7H4JRK.js";
7
8
 
8
9
  // src/providers/gemini.ts
9
10
  var geminiAdapter = withPromptInputSupport({
@@ -38,8 +39,9 @@ var geminiAdapter = withPromptInputSupport({
38
39
  strict: runtime.strict
39
40
  });
40
41
  const contents = [];
41
- if (runtime.history) {
42
- for (const msg of runtime.history) {
42
+ const history = compactHistoryForPrompt(resolvedAsset, runtime);
43
+ if (history) {
44
+ for (const msg of history) {
43
45
  contents.push({
44
46
  role: msg.role === "assistant" ? "model" : "user",
45
47
  parts: [{ text: msg.content }]
@@ -118,4 +120,4 @@ var geminiAdapter = withPromptInputSupport({
118
120
  export {
119
121
  geminiAdapter
120
122
  };
121
- //# sourceMappingURL=chunk-RY5DVTLV.js.map
123
+ //# sourceMappingURL=chunk-QK3WKE3K.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/providers/gemini.ts"],"sourcesContent":["import type { ResolvedPromptAsset } from '../schema/index.js';\nimport type {\n ProviderAdapter,\n ProviderRequest,\n ValidationResult,\n RuntimeRenderOptions,\n} from './types.js';\nimport { renderSections } from '../renderer/index.js';\nimport { resolveAssetForProvider } from './resolve-asset.js';\nimport { withPromptInputSupport } from './prompt-input.js';\nimport { applyRawProviderBody } from './raw.js';\nimport { compactHistoryForPrompt } from '../history.js';\n\n/**\n * Google Gemini provider adapter.\n * Produces request bodies compatible with the Gemini generateContent API.\n */\nexport const geminiAdapter: ProviderAdapter = withPromptInputSupport({\n name: 'gemini',\n\n validate(asset: ResolvedPromptAsset, runtime?: RuntimeRenderOptions): ValidationResult {\n const resolvedAsset = resolveAssetForProvider(asset, runtime);\n const errors: string[] = [];\n const warnings: string[] = [];\n const geminiCache = resolvedAsset.cache?.gemini?.cached_content;\n const googleCache = resolvedAsset.cache?.google?.cached_content;\n\n if (!resolvedAsset.model) {\n errors.push('Gemini adapter requires a model to be specified.');\n }\n\n if (resolvedAsset.sampling?.frequency_penalty !== undefined) {\n warnings.push('Gemini does not support frequency_penalty. It will be ignored.');\n }\n if (resolvedAsset.sampling?.presence_penalty !== undefined) {\n warnings.push('Gemini does not support presence_penalty. It will be ignored.');\n }\n if (geminiCache && googleCache && geminiCache !== googleCache) {\n warnings.push('Both cache.gemini.cached_content and cache.google.cached_content are set. Gemini uses cache.gemini.cached_content.');\n }\n if (resolvedAsset.response?.stream !== undefined) {\n warnings.push('Gemini streaming is endpoint-based (streamGenerateContent), not body-based. response.stream will be ignored.');\n }\n\n return { valid: errors.length === 0, errors, warnings };\n },\n\n render(asset: ResolvedPromptAsset, runtime: RuntimeRenderOptions): ProviderRequest {\n const resolvedAsset = resolveAssetForProvider(asset, runtime);\n const sections = renderSections(resolvedAsset, {\n variables: runtime.variables,\n strict: runtime.strict,\n });\n\n const contents: Array<Record<string, unknown>> = [];\n\n // History\n const history = compactHistoryForPrompt(resolvedAsset, runtime);\n if (history) {\n for (const msg of history) {\n contents.push({\n role: msg.role === 'assistant' ? 'model' : 'user',\n parts: [{ text: msg.content }],\n });\n }\n }\n\n // User message (prompt template)\n if (sections.prompt_template) {\n contents.push({\n role: 'user',\n parts: [{ text: sections.prompt_template }],\n });\n }\n\n const body: Record<string, unknown> = {\n contents,\n };\n const geminiCacheConfig = resolvedAsset.cache?.gemini ?? resolvedAsset.cache?.google;\n\n // System instruction\n if (sections.system_instructions) {\n body.systemInstruction = {\n parts: [{ text: sections.system_instructions }],\n };\n }\n\n // Generation config\n const generationConfig: Record<string, unknown> = {};\n\n const geminiOptions = resolvedAsset.provider_options?.gemini;\n\n if (resolvedAsset.sampling?.temperature !== undefined) generationConfig.temperature = resolvedAsset.sampling.temperature;\n if (resolvedAsset.sampling?.top_p !== undefined) generationConfig.topP = resolvedAsset.sampling.top_p;\n if (resolvedAsset.sampling?.max_output_tokens !== undefined) generationConfig.maxOutputTokens = resolvedAsset.sampling.max_output_tokens;\n if (resolvedAsset.sampling?.stop !== undefined) generationConfig.stopSequences = resolvedAsset.sampling.stop;\n\n if (geminiOptions?.candidate_count !== undefined) generationConfig.candidateCount = geminiOptions.candidate_count;\n if (geminiOptions?.top_k !== undefined) generationConfig.topK = geminiOptions.top_k;\n if (geminiOptions?.seed !== undefined) generationConfig.seed = geminiOptions.seed;\n if (geminiOptions?.response_modalities !== undefined) generationConfig.responseModalities = geminiOptions.response_modalities;\n\n if (resolvedAsset.response?.schema !== undefined) generationConfig.responseJsonSchema = resolvedAsset.response.schema;\n if (geminiOptions?.response_schema !== undefined) generationConfig.responseSchema = geminiOptions.response_schema;\n if (geminiOptions?.response_json_schema !== undefined) generationConfig.responseJsonSchema = geminiOptions.response_json_schema;\n\n if (resolvedAsset.response?.format === 'json') {\n generationConfig.responseMimeType = 'application/json';\n }\n\n // Thinking config\n if (geminiOptions?.thinking_budget_tokens !== undefined) {\n body.thinkingConfig = {\n thinkingBudget: geminiOptions.thinking_budget_tokens,\n };\n } else if (resolvedAsset.reasoning?.effort) {\n body.thinkingConfig = {\n thinkingBudget: resolvedAsset.reasoning.effort === 'high' ? 8192 : resolvedAsset.reasoning.effort === 'medium' ? 4096 : 1024,\n };\n }\n\n if (Object.keys(generationConfig).length > 0) {\n body.generationConfig = generationConfig;\n }\n\n if (geminiCacheConfig?.cached_content) {\n body.cachedContent = geminiCacheConfig.cached_content;\n }\n\n // Tools\n if (resolvedAsset.tools && resolvedAsset.tools.length > 0) {\n const functionDeclarations = resolvedAsset.tools.map((tool) => {\n if (typeof tool === 'string') {\n const def = runtime.toolRegistry?.[tool];\n if (def) return def;\n return { name: tool };\n }\n return {\n name: tool.name,\n description: tool.description,\n parameters: tool.input_schema,\n };\n });\n body.tools = [{ functionDeclarations }];\n }\n\n return {\n body: applyRawProviderBody(body, resolvedAsset, 'gemini'),\n provider: 'gemini',\n model: resolvedAsset.model ?? 'unknown',\n };\n },\n});\n"],"mappings":"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","names":[]}
package/dist/cli/index.js CHANGED
@@ -4,8 +4,8 @@
4
4
  import { readFileSync as readFileSync2 } from "fs";
5
5
 
6
6
  // src/cli/commands/validate.ts
7
- import { readdir } from "fs/promises";
8
- import { join as join2, extname } from "path";
7
+ import { readdir, stat } from "fs/promises";
8
+ import { join as join3, extname } from "path";
9
9
 
10
10
  // src/parser/parser.ts
11
11
  import matter from "gray-matter";
@@ -65,10 +65,26 @@ var OpenRouterProviderOptionsSchema = z.object({
65
65
  plugins: z.array(z.record(z.unknown())).optional(),
66
66
  models: z.array(z.string()).optional()
67
67
  });
68
+ var LLMAsAServiceCustomerSchema = z.object({
69
+ customer_id: z.string(),
70
+ customer_name: z.string().optional(),
71
+ customer_user_id: z.string().optional(),
72
+ customer_user_name: z.string().optional(),
73
+ customer_user_email: z.string().optional()
74
+ });
75
+ var LLMAsAServiceProviderOptionsSchema = z.object({
76
+ base_url: z.string().url().optional(),
77
+ project_id: z.string().optional(),
78
+ customer: LLMAsAServiceCustomerSchema.optional(),
79
+ conversationId: z.string().optional(),
80
+ conversationTitle: z.string().optional(),
81
+ projectId: z.string().optional()
82
+ });
68
83
  var ProviderOptionsSchema = z.object({
69
84
  anthropic: AnthropicProviderOptionsSchema.optional(),
70
85
  gemini: GeminiProviderOptionsSchema.optional(),
71
- openrouter: OpenRouterProviderOptionsSchema.optional()
86
+ openrouter: OpenRouterProviderOptionsSchema.optional(),
87
+ llmasaservice: LLMAsAServiceProviderOptionsSchema.optional()
72
88
  });
73
89
  var RawProviderBodySchema = z.object({
74
90
  openai: z.record(z.unknown()).optional(),
@@ -77,7 +93,8 @@ var RawProviderBodySchema = z.object({
77
93
  anthropic: z.record(z.unknown()).optional(),
78
94
  gemini: z.record(z.unknown()).optional(),
79
95
  google: z.record(z.unknown()).optional(),
80
- openrouter: z.record(z.unknown()).optional()
96
+ openrouter: z.record(z.unknown()).optional(),
97
+ llmasaservice: z.record(z.unknown()).optional()
81
98
  });
82
99
  var OpenAICacheSchema = z.object({
83
100
  prompt_cache_key: z.string().min(1).optional(),
@@ -164,7 +181,7 @@ var SectionsSchema = z.object({
164
181
  notes: z.string().optional()
165
182
  });
166
183
  var PromptDefaultsSchema = z.object({
167
- provider: z.enum(["openai", "openai-responses", "anthropic", "google", "gemini", "openrouter", "any"]).optional(),
184
+ provider: z.enum(["openai", "openai-responses", "anthropic", "google", "gemini", "openrouter", "llmasaservice", "any"]).optional(),
168
185
  model: z.string().optional(),
169
186
  cache: CacheSchema.optional(),
170
187
  metadata: MetadataSchema.optional(),
@@ -176,7 +193,7 @@ var PromptAssetSchema = z.object({
176
193
  id: z.string(),
177
194
  schema_version: z.number().int().positive().default(1),
178
195
  description: z.string().optional(),
179
- provider: z.enum(["openai", "openai-responses", "anthropic", "google", "gemini", "openrouter", "any"]).optional(),
196
+ provider: z.enum(["openai", "openai-responses", "anthropic", "google", "gemini", "openrouter", "llmasaservice", "any"]).optional(),
180
197
  model: z.string().optional(),
181
198
  fallback_models: z.array(z.string()).optional(),
182
199
  reasoning: ReasoningSchema.optional(),
@@ -432,6 +449,7 @@ function mergeDefaults(base, local) {
432
449
  return {
433
450
  provider: local.provider ?? base.provider,
434
451
  model: local.model ?? base.model,
452
+ cache: mergeCache(base.cache, local.cache),
435
453
  metadata: {
436
454
  ...base.metadata ?? {},
437
455
  ...local.metadata ?? {}
@@ -443,10 +461,12 @@ function mergeDefaults(base, local) {
443
461
  };
444
462
  }
445
463
  function applyDefaults(asset, defaults) {
464
+ const cache = mergeCache(defaults.cache, asset.cache);
446
465
  const hasDefaultMetadata = defaults.metadata && Object.keys(defaults.metadata).length > 0;
447
466
  const hasDefaultSystem = !!defaults.sections?.system_instructions;
448
467
  const hasDefaultScalars = defaults.provider !== void 0 || defaults.model !== void 0;
449
- if (!hasDefaultMetadata && !hasDefaultSystem && !hasDefaultScalars) {
468
+ const hasDefaultCache = cache !== void 0;
469
+ if (!hasDefaultMetadata && !hasDefaultSystem && !hasDefaultScalars && !hasDefaultCache) {
450
470
  return asset;
451
471
  }
452
472
  const mergedMetadata = {
@@ -460,10 +480,38 @@ function applyDefaults(asset, defaults) {
460
480
  ...asset,
461
481
  provider: asset.provider ?? defaults.provider,
462
482
  model: asset.model ?? defaults.model,
483
+ cache,
463
484
  metadata,
464
485
  sections
465
486
  };
466
487
  }
488
+ function mergeCache(base, local) {
489
+ const merged = {
490
+ ...base ?? {},
491
+ ...local ?? {},
492
+ openai: {
493
+ ...base?.openai ?? {},
494
+ ...local?.openai ?? {}
495
+ },
496
+ anthropic: {
497
+ ...base?.anthropic ?? {},
498
+ ...local?.anthropic ?? {}
499
+ },
500
+ gemini: {
501
+ ...base?.gemini ?? {},
502
+ ...local?.gemini ?? {}
503
+ },
504
+ google: {
505
+ ...base?.google ?? {},
506
+ ...local?.google ?? {}
507
+ }
508
+ };
509
+ if (merged.openai && Object.keys(merged.openai).length === 0) delete merged.openai;
510
+ if (merged.anthropic && Object.keys(merged.anthropic).length === 0) delete merged.anthropic;
511
+ if (merged.gemini && Object.keys(merged.gemini).length === 0) delete merged.gemini;
512
+ if (merged.google && Object.keys(merged.google).length === 0) delete merged.google;
513
+ return Object.keys(merged).length > 0 ? merged : void 0;
514
+ }
467
515
 
468
516
  // src/renderer/interpolate.ts
469
517
  var VARIABLE_RE = /\{\{\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*\}\}/g;
@@ -961,8 +1009,8 @@ var PromptCache = class {
961
1009
  const entry = this.cache.get(filePath);
962
1010
  if (!entry) return void 0;
963
1011
  try {
964
- const stat = statSync(filePath);
965
- if (stat.mtimeMs !== entry.mtime) {
1012
+ const stat2 = statSync(filePath);
1013
+ if (stat2.mtimeMs !== entry.mtime) {
966
1014
  this.cache.delete(filePath);
967
1015
  return void 0;
968
1016
  }
@@ -976,14 +1024,14 @@ var PromptCache = class {
976
1024
  }
977
1025
  set(filePath, value) {
978
1026
  try {
979
- const stat = statSync(filePath);
1027
+ const stat2 = statSync(filePath);
980
1028
  if (this.cache.has(filePath)) {
981
1029
  this.cache.delete(filePath);
982
1030
  } else if (this.cache.size >= this.maxSize) {
983
1031
  const oldest = this.cache.keys().next().value;
984
1032
  if (oldest) this.cache.delete(oldest);
985
1033
  }
986
- this.cache.set(filePath, { value, mtime: stat.mtimeMs });
1034
+ this.cache.set(filePath, { value, mtime: stat2.mtimeMs });
987
1035
  } catch {
988
1036
  }
989
1037
  }
@@ -1043,7 +1091,8 @@ function mergeOverride(base, override) {
1043
1091
  anthropic: mergeRecordBlock(result.raw?.anthropic, override.raw.anthropic),
1044
1092
  gemini: mergeRecordBlock(result.raw?.gemini, override.raw.gemini),
1045
1093
  google: mergeRecordBlock(result.raw?.google, override.raw.google),
1046
- openrouter: mergeRecordBlock(result.raw?.openrouter, override.raw.openrouter)
1094
+ openrouter: mergeRecordBlock(result.raw?.openrouter, override.raw.openrouter),
1095
+ llmasaservice: mergeRecordBlock(result.raw?.llmasaservice, override.raw.llmasaservice)
1047
1096
  };
1048
1097
  }
1049
1098
  if (override.provider_options !== void 0) {
@@ -1061,6 +1110,10 @@ function mergeOverride(base, override) {
1061
1110
  openrouter: {
1062
1111
  ...result.provider_options?.openrouter,
1063
1112
  ...override.provider_options.openrouter
1113
+ },
1114
+ llmasaservice: {
1115
+ ...result.provider_options?.llmasaservice,
1116
+ ...override.provider_options.llmasaservice
1064
1117
  }
1065
1118
  };
1066
1119
  }
@@ -1080,11 +1133,33 @@ function defaultCompiledDirForFormat(format) {
1080
1133
  }
1081
1134
  var sharedPromptCache = new PromptCache();
1082
1135
 
1136
+ // src/cli/commands/defaults-root.ts
1137
+ import { existsSync as existsSync2 } from "fs";
1138
+ import { dirname as dirname3, join as join2, resolve as resolve4 } from "path";
1139
+ function findDefaultsRoot(filePath) {
1140
+ let current = resolve4(dirname3(filePath));
1141
+ let root = current;
1142
+ let foundDefaults = false;
1143
+ while (true) {
1144
+ if (existsSync2(join2(current, "defaults.md"))) {
1145
+ root = current;
1146
+ foundDefaults = true;
1147
+ } else if (foundDefaults) {
1148
+ return root;
1149
+ }
1150
+ const parent = dirname3(current);
1151
+ if (parent === current) {
1152
+ return root;
1153
+ }
1154
+ current = parent;
1155
+ }
1156
+ }
1157
+
1083
1158
  // src/cli/commands/validate.ts
1084
1159
  var HELP = `
1085
1160
  promptopskit validate [sourceDir] [options]
1086
1161
 
1087
- Validate all prompt .md files in a directory.
1162
+ Validate prompt .md files in a directory or a single prompt file.
1088
1163
 
1089
1164
  Options:
1090
1165
  --source, -s Source directory (default: ./prompts)
@@ -1097,18 +1172,19 @@ async function validate(args) {
1097
1172
  return;
1098
1173
  }
1099
1174
  const positional = getPositionalArgs(args, /* @__PURE__ */ new Set(["--source", "-s"]));
1100
- const dir = getFlag(args, "--source", "-s") ?? positional[0] ?? DEFAULT_PROMPTS_DIR;
1175
+ const target = getFlag(args, "--source", "-s") ?? positional[0] ?? DEFAULT_PROMPTS_DIR;
1101
1176
  const strict = args.includes("--strict");
1102
- const files = await collectPromptFiles(dir);
1177
+ const files = await collectPromptFiles(target);
1103
1178
  if (files.length === 0) {
1104
- console.log(`No .md prompt files found in ${dir}`);
1179
+ console.log(`No .md prompt files found in ${target}`);
1105
1180
  return;
1106
1181
  }
1107
1182
  let errorCount = 0;
1108
1183
  let warnCount = 0;
1109
1184
  for (const file of files) {
1110
1185
  try {
1111
- const { asset, raw } = await loadPromptFile(file, { defaultsRoot: dir });
1186
+ const defaultsRoot = files.length === 1 && file === target ? findDefaultsRoot(file) : target;
1187
+ const { asset, raw } = await loadPromptFile(file, { defaultsRoot });
1112
1188
  const result = await validateAssetWithIncludes(asset, file, Object.keys(raw.frontMatter));
1113
1189
  if (result.errors.length > 0) {
1114
1190
  errorCount += result.errors.length;
@@ -1163,12 +1239,19 @@ function getFlag(args, ...flags) {
1163
1239
  }
1164
1240
  return void 0;
1165
1241
  }
1166
- async function collectPromptFiles(dir) {
1242
+ async function collectPromptFiles(target) {
1243
+ const targetStats = await stat(target);
1244
+ if (targetStats.isFile()) {
1245
+ if (extname(target) !== ".md" || target.endsWith("defaults.md") || target.endsWith(".test.md")) {
1246
+ return [];
1247
+ }
1248
+ return [target];
1249
+ }
1167
1250
  const results = [];
1168
- const entries = await readdir(dir, { withFileTypes: true, recursive: true });
1251
+ const entries = await readdir(target, { withFileTypes: true, recursive: true });
1169
1252
  for (const entry of entries) {
1170
1253
  if (entry.isFile() && extname(entry.name) === ".md" && !entry.name.endsWith(".test.md") && entry.name !== "defaults.md") {
1171
- results.push(join2(entry.parentPath ?? dir, entry.name));
1254
+ results.push(join3(entry.parentPath ?? target, entry.name));
1172
1255
  }
1173
1256
  }
1174
1257
  return results.sort();
@@ -1176,7 +1259,7 @@ async function collectPromptFiles(dir) {
1176
1259
 
1177
1260
  // src/cli/commands/compile.ts
1178
1261
  import { readdir as readdir2, writeFile, mkdir, rm } from "fs/promises";
1179
- import { join as join3, extname as extname2, relative, dirname as dirname3 } from "path";
1262
+ import { join as join4, extname as extname2, relative, dirname as dirname5 } from "path";
1180
1263
  var HELP2 = `
1181
1264
  promptopskit compile [sourceDir] [outputDir] [options]
1182
1265
 
@@ -1218,7 +1301,7 @@ async function compile(args) {
1218
1301
  for (const file of files) {
1219
1302
  const rel = relative(sourceDir, file).replace(/\.md$/, "");
1220
1303
  const outExt = format === "esm" ? ".mjs" : ".json";
1221
- const outPath = join3(outputDir, rel + outExt);
1304
+ const outPath = join4(outputDir, rel + outExt);
1222
1305
  try {
1223
1306
  const { asset: parsed, raw } = await loadPromptFile(file, { defaultsRoot: sourceDir });
1224
1307
  const validation = await validateAssetWithIncludes(parsed, file, Object.keys(raw.frontMatter));
@@ -1229,7 +1312,7 @@ async function compile(args) {
1229
1312
  if (dryRun) {
1230
1313
  console.log(` Would create: ${outPath}`);
1231
1314
  } else {
1232
- await mkdir(dirname3(outPath), { recursive: true });
1315
+ await mkdir(dirname5(outPath), { recursive: true });
1233
1316
  if (format === "esm") {
1234
1317
  const esmContent = `export default ${JSON.stringify(asset, null, 2)};
1235
1318
  `;
@@ -1286,7 +1369,7 @@ async function collectPromptFiles2(dir) {
1286
1369
  const entries = await readdir2(dir, { withFileTypes: true, recursive: true });
1287
1370
  for (const entry of entries) {
1288
1371
  if (entry.isFile() && extname2(entry.name) === ".md" && !entry.name.endsWith(".test.md") && entry.name !== "defaults.md") {
1289
- results.push(join3(entry.parentPath ?? dir, entry.name));
1372
+ results.push(join4(entry.parentPath ?? dir, entry.name));
1290
1373
  }
1291
1374
  }
1292
1375
  return results.sort();
@@ -1295,30 +1378,6 @@ async function collectPromptFiles2(dir) {
1295
1378
  // src/cli/commands/render.ts
1296
1379
  import { readFile as readFile4 } from "fs/promises";
1297
1380
  import { existsSync as existsSync3 } from "fs";
1298
-
1299
- // src/cli/commands/defaults-root.ts
1300
- import { existsSync as existsSync2 } from "fs";
1301
- import { dirname as dirname4, join as join4, resolve as resolve4 } from "path";
1302
- function findDefaultsRoot(filePath) {
1303
- let current = resolve4(dirname4(filePath));
1304
- let root = current;
1305
- let foundDefaults = false;
1306
- while (true) {
1307
- if (existsSync2(join4(current, "defaults.md"))) {
1308
- root = current;
1309
- foundDefaults = true;
1310
- } else if (foundDefaults) {
1311
- return root;
1312
- }
1313
- const parent = dirname4(current);
1314
- if (parent === current) {
1315
- return root;
1316
- }
1317
- current = parent;
1318
- }
1319
- }
1320
-
1321
- // src/cli/commands/render.ts
1322
1381
  var HELP3 = `
1323
1382
  promptopskit render <file> [options]
1324
1383
 
@@ -1453,7 +1512,7 @@ async function inspect(args) {
1453
1512
 
1454
1513
  // src/cli/commands/init.ts
1455
1514
  import { writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
1456
- import { join as join5, dirname as dirname5, relative as relative2 } from "path";
1515
+ import { join as join5, dirname as dirname6, relative as relative2 } from "path";
1457
1516
  import { existsSync as existsSync4, readFileSync } from "fs";
1458
1517
  var HELP5 = `
1459
1518
  promptopskit init [dir]
@@ -1604,8 +1663,8 @@ async function init(args) {
1604
1663
  return;
1605
1664
  }
1606
1665
  const dir = args.find((a) => !a.startsWith("--")) ?? "./prompts";
1607
- const testFilePath = join5(dirname5(dir), "tests", "hello.prompt.test.mjs");
1608
- const promptsDirFromTest = relative2(dirname5(testFilePath), dir) || ".";
1666
+ const testFilePath = join5(dirname6(dir), "tests", "hello.prompt.test.mjs");
1667
+ const promptsDirFromTest = relative2(dirname6(testFilePath), dir) || ".";
1609
1668
  const helloPromptTest = createHelloPromptTest(promptsDirFromTest);
1610
1669
  const files = [
1611
1670
  { path: join5(dir, "defaults.md"), content: DEFAULTS },
@@ -1623,7 +1682,7 @@ async function init(args) {
1623
1682
  skipped++;
1624
1683
  continue;
1625
1684
  }
1626
- await mkdir2(dirname5(file.path), { recursive: true });
1685
+ await mkdir2(dirname6(file.path), { recursive: true });
1627
1686
  await writeFile2(file.path, file.content, "utf-8");
1628
1687
  console.log(` \u2713 ${file.path}`);
1629
1688
  created++;
@@ -1692,7 +1751,7 @@ test('hello prompt can return a deterministic response without calling a model',
1692
1751
 
1693
1752
  // src/cli/commands/skill.ts
1694
1753
  import { writeFile as writeFile3, readFile as readFile5, mkdir as mkdir3 } from "fs/promises";
1695
- import { dirname as dirname6 } from "path";
1754
+ import { dirname as dirname7 } from "path";
1696
1755
  import { existsSync as existsSync5 } from "fs";
1697
1756
  var MARKER_START = "<!-- promptopskit:start -->";
1698
1757
  var MARKER_END = "<!-- promptopskit:end -->";
@@ -1791,7 +1850,7 @@ async function skill(args) {
1791
1850
  written++;
1792
1851
  continue;
1793
1852
  }
1794
- await mkdir3(dirname6(filePath), { recursive: true });
1853
+ await mkdir3(dirname7(filePath), { recursive: true });
1795
1854
  await writeFile3(filePath, markedContent, "utf-8");
1796
1855
  console.log(` \u2713 ${filePath}`);
1797
1856
  written++;
@@ -1804,7 +1863,7 @@ async function skill(args) {
1804
1863
  async function deployClaude(filePath, force) {
1805
1864
  const content = CLAUDE_LINE + "\n";
1806
1865
  if (!existsSync5(filePath) || force) {
1807
- await mkdir3(dirname6(filePath), { recursive: true });
1866
+ await mkdir3(dirname7(filePath), { recursive: true });
1808
1867
  await writeFile3(filePath, content, "utf-8");
1809
1868
  console.log(` \u2713 ${filePath}`);
1810
1869
  return 1;