promptopskit 0.0.1 → 0.1.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.
- package/README.md +88 -15
- package/dist/{chunk-X64JII57.js → chunk-HMYPMHTG.js} +91 -4
- package/dist/chunk-HMYPMHTG.js.map +1 -0
- package/dist/cli/index.js +593 -35
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +1049 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +191 -0
- package/dist/index.d.ts +18 -6
- package/dist/index.js +28 -4
- package/dist/index.js.map +1 -1
- package/dist/providers/anthropic.cjs +151 -0
- package/dist/providers/anthropic.cjs.map +1 -0
- package/dist/providers/anthropic.d.cts +11 -0
- package/dist/providers/anthropic.d.ts +2 -2
- package/dist/providers/gemini.cjs +155 -0
- package/dist/providers/gemini.cjs.map +1 -0
- package/dist/providers/gemini.d.cts +11 -0
- package/dist/providers/gemini.d.ts +2 -2
- package/dist/providers/openai.cjs +146 -0
- package/dist/providers/openai.cjs.map +1 -0
- package/dist/providers/openai.d.cts +11 -0
- package/dist/providers/openai.d.ts +2 -2
- package/dist/providers/openrouter.cjs +161 -0
- package/dist/providers/openrouter.cjs.map +1 -0
- package/dist/providers/openrouter.d.cts +13 -0
- package/dist/providers/openrouter.d.ts +2 -2
- package/dist/{schema-DHRI5Mzl.d.ts → schema-C6smABrt.d.cts} +3 -3
- package/dist/schema-C6smABrt.d.ts +695 -0
- package/dist/testing.cjs +236 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +17 -0
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +1 -1
- package/dist/{types-D9hquVja.d.ts → types-D7lW5IYT.d.ts} +1 -1
- package/dist/types-S_c-ZEfK.d.cts +40 -0
- package/package.json +54 -16
- package/dist/chunk-X64JII57.js.map +0 -1
package/dist/testing.cjs
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/testing.ts
|
|
31
|
+
var testing_exports = {};
|
|
32
|
+
__export(testing_exports, {
|
|
33
|
+
createMockAsset: () => createMockAsset,
|
|
34
|
+
createMockResolvedAsset: () => createMockResolvedAsset,
|
|
35
|
+
parseTestPrompt: () => parseTestPrompt
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(testing_exports);
|
|
38
|
+
|
|
39
|
+
// src/parser/parser.ts
|
|
40
|
+
var import_gray_matter = __toESM(require("gray-matter"), 1);
|
|
41
|
+
|
|
42
|
+
// src/schema/schema.ts
|
|
43
|
+
var import_zod = require("zod");
|
|
44
|
+
var InlineToolDefSchema = import_zod.z.object({
|
|
45
|
+
name: import_zod.z.string(),
|
|
46
|
+
description: import_zod.z.string().optional(),
|
|
47
|
+
input_schema: import_zod.z.record(import_zod.z.unknown()).optional()
|
|
48
|
+
});
|
|
49
|
+
var ToolRefSchema = import_zod.z.union([import_zod.z.string(), InlineToolDefSchema]);
|
|
50
|
+
var MCPServerRefSchema = import_zod.z.union([
|
|
51
|
+
import_zod.z.string(),
|
|
52
|
+
import_zod.z.object({
|
|
53
|
+
name: import_zod.z.string(),
|
|
54
|
+
config: import_zod.z.record(import_zod.z.unknown()).optional()
|
|
55
|
+
})
|
|
56
|
+
]);
|
|
57
|
+
var ReasoningSchema = import_zod.z.object({
|
|
58
|
+
effort: import_zod.z.enum(["low", "medium", "high"]).optional(),
|
|
59
|
+
budget_tokens: import_zod.z.number().int().positive().optional()
|
|
60
|
+
});
|
|
61
|
+
var SamplingSchema = import_zod.z.object({
|
|
62
|
+
temperature: import_zod.z.number().min(0).max(2).optional(),
|
|
63
|
+
top_p: import_zod.z.number().min(0).max(1).optional(),
|
|
64
|
+
frequency_penalty: import_zod.z.number().optional(),
|
|
65
|
+
presence_penalty: import_zod.z.number().optional(),
|
|
66
|
+
stop: import_zod.z.array(import_zod.z.string()).optional(),
|
|
67
|
+
max_output_tokens: import_zod.z.number().int().positive().optional()
|
|
68
|
+
});
|
|
69
|
+
var ResponseSchema = import_zod.z.object({
|
|
70
|
+
format: import_zod.z.enum(["text", "json", "markdown"]).optional(),
|
|
71
|
+
stream: import_zod.z.boolean().optional()
|
|
72
|
+
});
|
|
73
|
+
var HistorySchema = import_zod.z.object({
|
|
74
|
+
max_items: import_zod.z.number().int().positive().optional()
|
|
75
|
+
});
|
|
76
|
+
var ContextSchema = import_zod.z.object({
|
|
77
|
+
inputs: import_zod.z.array(import_zod.z.string()).optional(),
|
|
78
|
+
history: HistorySchema.optional()
|
|
79
|
+
});
|
|
80
|
+
var MetadataSchema = import_zod.z.object({
|
|
81
|
+
owner: import_zod.z.string().optional(),
|
|
82
|
+
tags: import_zod.z.array(import_zod.z.string()).optional(),
|
|
83
|
+
review_required: import_zod.z.boolean().optional(),
|
|
84
|
+
stable: import_zod.z.boolean().optional()
|
|
85
|
+
});
|
|
86
|
+
var MCPSchema = import_zod.z.object({
|
|
87
|
+
servers: import_zod.z.array(MCPServerRefSchema).optional()
|
|
88
|
+
});
|
|
89
|
+
var PromptAssetOverridesSchema = import_zod.z.object({
|
|
90
|
+
model: import_zod.z.string().optional(),
|
|
91
|
+
fallback_models: import_zod.z.array(import_zod.z.string()).optional(),
|
|
92
|
+
reasoning: ReasoningSchema.optional(),
|
|
93
|
+
sampling: SamplingSchema.optional(),
|
|
94
|
+
response: ResponseSchema.optional(),
|
|
95
|
+
tools: import_zod.z.array(ToolRefSchema).optional()
|
|
96
|
+
});
|
|
97
|
+
var SourceSchema = import_zod.z.object({
|
|
98
|
+
file_path: import_zod.z.string().optional(),
|
|
99
|
+
checksum: import_zod.z.string().optional()
|
|
100
|
+
});
|
|
101
|
+
var SectionsSchema = import_zod.z.object({
|
|
102
|
+
system_instructions: import_zod.z.string().optional(),
|
|
103
|
+
prompt_template: import_zod.z.string().optional(),
|
|
104
|
+
notes: import_zod.z.string().optional()
|
|
105
|
+
});
|
|
106
|
+
var PromptDefaultsSchema = import_zod.z.object({
|
|
107
|
+
metadata: MetadataSchema.optional(),
|
|
108
|
+
sections: import_zod.z.object({
|
|
109
|
+
system_instructions: import_zod.z.string().optional()
|
|
110
|
+
}).optional()
|
|
111
|
+
});
|
|
112
|
+
var PromptAssetSchema = import_zod.z.object({
|
|
113
|
+
id: import_zod.z.string(),
|
|
114
|
+
schema_version: import_zod.z.number().int().positive().default(1),
|
|
115
|
+
description: import_zod.z.string().optional(),
|
|
116
|
+
provider: import_zod.z.enum(["openai", "anthropic", "google", "gemini", "openrouter", "any"]).optional(),
|
|
117
|
+
model: import_zod.z.string().optional(),
|
|
118
|
+
fallback_models: import_zod.z.array(import_zod.z.string()).optional(),
|
|
119
|
+
reasoning: ReasoningSchema.optional(),
|
|
120
|
+
sampling: SamplingSchema.optional(),
|
|
121
|
+
response: ResponseSchema.optional(),
|
|
122
|
+
tools: import_zod.z.array(ToolRefSchema).optional(),
|
|
123
|
+
mcp: MCPSchema.optional(),
|
|
124
|
+
context: ContextSchema.optional(),
|
|
125
|
+
includes: import_zod.z.array(import_zod.z.string()).optional(),
|
|
126
|
+
environments: import_zod.z.record(PromptAssetOverridesSchema).optional(),
|
|
127
|
+
tiers: import_zod.z.record(PromptAssetOverridesSchema).optional(),
|
|
128
|
+
metadata: MetadataSchema.optional(),
|
|
129
|
+
// Populated by parser, not authored in YAML
|
|
130
|
+
sections: SectionsSchema.optional(),
|
|
131
|
+
source: SourceSchema.optional()
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// src/parser/sections.ts
|
|
135
|
+
var SECTION_MAP = {
|
|
136
|
+
"system instructions": "system_instructions",
|
|
137
|
+
"prompt template": "prompt_template",
|
|
138
|
+
"notes": "notes"
|
|
139
|
+
};
|
|
140
|
+
function extractSections(body) {
|
|
141
|
+
const lines = body.split("\n");
|
|
142
|
+
const sections = {};
|
|
143
|
+
let currentKey = null;
|
|
144
|
+
let currentLines = [];
|
|
145
|
+
let foundAnyH1 = false;
|
|
146
|
+
for (const line of lines) {
|
|
147
|
+
const h1Match = line.match(/^#\s+(.+)$/);
|
|
148
|
+
if (h1Match) {
|
|
149
|
+
if (currentKey) {
|
|
150
|
+
sections[currentKey] = currentLines.join("\n").trim();
|
|
151
|
+
}
|
|
152
|
+
foundAnyH1 = true;
|
|
153
|
+
const heading = h1Match[1].trim().toLowerCase();
|
|
154
|
+
currentKey = SECTION_MAP[heading] ?? null;
|
|
155
|
+
currentLines = [];
|
|
156
|
+
} else {
|
|
157
|
+
currentLines.push(line);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
if (currentKey) {
|
|
161
|
+
sections[currentKey] = currentLines.join("\n").trim();
|
|
162
|
+
}
|
|
163
|
+
if (!foundAnyH1) {
|
|
164
|
+
const trimmed = body.trim();
|
|
165
|
+
if (trimmed) {
|
|
166
|
+
sections.prompt_template = trimmed;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return sections;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// src/parser/parser.ts
|
|
173
|
+
function parsePrompt(content, filePath) {
|
|
174
|
+
const { data: frontMatter, content: body } = (0, import_gray_matter.default)(content);
|
|
175
|
+
const sections = extractSections(body);
|
|
176
|
+
const raw = {
|
|
177
|
+
...frontMatter,
|
|
178
|
+
sections,
|
|
179
|
+
source: filePath ? { file_path: filePath } : void 0
|
|
180
|
+
};
|
|
181
|
+
const asset = PromptAssetSchema.parse(raw);
|
|
182
|
+
return {
|
|
183
|
+
asset,
|
|
184
|
+
raw: {
|
|
185
|
+
frontMatter,
|
|
186
|
+
body
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// src/parser/loader.ts
|
|
192
|
+
var import_promises = require("fs/promises");
|
|
193
|
+
var import_node_path = require("path");
|
|
194
|
+
var import_gray_matter2 = __toESM(require("gray-matter"), 1);
|
|
195
|
+
|
|
196
|
+
// src/testing.ts
|
|
197
|
+
function createMockAsset(overrides = {}) {
|
|
198
|
+
return {
|
|
199
|
+
id: "test.prompt",
|
|
200
|
+
schema_version: 1,
|
|
201
|
+
provider: "openai",
|
|
202
|
+
model: "gpt-5.4",
|
|
203
|
+
sections: {
|
|
204
|
+
system_instructions: "You are a test assistant.",
|
|
205
|
+
prompt_template: "Hello {{ name }}"
|
|
206
|
+
},
|
|
207
|
+
...overrides
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
function createMockResolvedAsset(overrides = {}) {
|
|
211
|
+
return {
|
|
212
|
+
id: "test.prompt",
|
|
213
|
+
schema_version: 1,
|
|
214
|
+
provider: "openai",
|
|
215
|
+
model: "gpt-5.4",
|
|
216
|
+
sections: {
|
|
217
|
+
system_instructions: "You are a test assistant.",
|
|
218
|
+
prompt_template: "Hello {{ name }}"
|
|
219
|
+
},
|
|
220
|
+
source: {
|
|
221
|
+
file_path: "test.md"
|
|
222
|
+
},
|
|
223
|
+
...overrides
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
function parseTestPrompt(source) {
|
|
227
|
+
const { asset } = parsePrompt(source);
|
|
228
|
+
return asset;
|
|
229
|
+
}
|
|
230
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
231
|
+
0 && (module.exports = {
|
|
232
|
+
createMockAsset,
|
|
233
|
+
createMockResolvedAsset,
|
|
234
|
+
parseTestPrompt
|
|
235
|
+
});
|
|
236
|
+
//# sourceMappingURL=testing.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/testing.ts","../src/parser/parser.ts","../src/schema/schema.ts","../src/parser/sections.ts","../src/parser/loader.ts"],"sourcesContent":["import { parsePrompt } from './parser/index.js';\r\nimport type { PromptAsset, ResolvedPromptAsset } from './schema/index.js';\r\n\r\n/**\r\n * Create a mock PromptAsset for testing.\r\n */\r\nexport function createMockAsset(overrides: Partial<PromptAsset> = {}): PromptAsset {\r\n return {\r\n id: 'test.prompt',\r\n schema_version: 1,\r\n provider: 'openai',\r\n model: 'gpt-5.4',\r\n sections: {\r\n system_instructions: 'You are a test assistant.',\r\n prompt_template: 'Hello {{ name }}',\r\n },\r\n ...overrides,\r\n };\r\n}\r\n\r\n/**\r\n * Create a mock ResolvedPromptAsset for testing.\r\n */\r\nexport function createMockResolvedAsset(\r\n overrides: Partial<ResolvedPromptAsset> = {},\r\n): ResolvedPromptAsset {\r\n return {\r\n id: 'test.prompt',\r\n schema_version: 1,\r\n provider: 'openai',\r\n model: 'gpt-5.4',\r\n sections: {\r\n system_instructions: 'You are a test assistant.',\r\n prompt_template: 'Hello {{ name }}',\r\n },\r\n source: {\r\n file_path: 'test.md',\r\n },\r\n ...overrides,\r\n } as ResolvedPromptAsset;\r\n}\r\n\r\n/**\r\n * Parse an inline prompt string for testing.\r\n */\r\nexport function parseTestPrompt(source: string): PromptAsset {\r\n const { asset } = parsePrompt(source);\r\n return asset;\r\n}\r\n","import matter from 'gray-matter';\r\nimport { PromptAssetSchema } from '../schema/index.js';\r\nimport type { PromptAsset } from '../schema/index.js';\r\nimport { extractSections } from './sections.js';\r\n\r\nexport interface ParseResult {\r\n asset: PromptAsset;\r\n raw: {\r\n frontMatter: Record<string, unknown>;\r\n body: string;\r\n };\r\n}\r\n\r\n/**\r\n * Parse a prompt markdown string (YAML front matter + markdown body)\r\n * into a validated PromptAsset.\r\n */\r\nexport function parsePrompt(content: string, filePath?: string): ParseResult {\r\n const { data: frontMatter, content: body } = matter(content);\r\n\r\n const sections = extractSections(body);\r\n\r\n const raw = {\r\n ...frontMatter,\r\n sections,\r\n source: filePath ? { file_path: filePath } : undefined,\r\n };\r\n\r\n const asset = PromptAssetSchema.parse(raw);\r\n\r\n return {\r\n asset,\r\n raw: {\r\n frontMatter: frontMatter as Record<string, unknown>,\r\n body,\r\n },\r\n };\r\n}\r\n","import { z } from 'zod';\r\n\r\n// --- Tool definitions ---\r\n\r\nexport const InlineToolDefSchema = z.object({\r\n name: z.string(),\r\n description: z.string().optional(),\r\n input_schema: z.record(z.unknown()).optional(),\r\n});\r\n\r\nexport type InlineToolDef = z.infer<typeof InlineToolDefSchema>;\r\n\r\nexport const ToolRefSchema = z.union([z.string(), InlineToolDefSchema]);\r\n\r\n// --- MCP ---\r\n\r\nexport const MCPServerRefSchema = z.union([\r\n z.string(),\r\n z.object({\r\n name: z.string(),\r\n config: z.record(z.unknown()).optional(),\r\n }),\r\n]);\r\n\r\nexport type MCPServerRef = z.infer<typeof MCPServerRefSchema>;\r\n\r\n// --- Reasoning ---\r\n\r\nexport const ReasoningSchema = z.object({\r\n effort: z.enum(['low', 'medium', 'high']).optional(),\r\n budget_tokens: z.number().int().positive().optional(),\r\n});\r\n\r\n// --- Sampling ---\r\n\r\nexport const SamplingSchema = z.object({\r\n temperature: z.number().min(0).max(2).optional(),\r\n top_p: z.number().min(0).max(1).optional(),\r\n frequency_penalty: z.number().optional(),\r\n presence_penalty: z.number().optional(),\r\n stop: z.array(z.string()).optional(),\r\n max_output_tokens: z.number().int().positive().optional(),\r\n});\r\n\r\n// --- Response ---\r\n\r\nexport const ResponseSchema = z.object({\r\n format: z.enum(['text', 'json', 'markdown']).optional(),\r\n stream: z.boolean().optional(),\r\n});\r\n\r\n// --- Context ---\r\n\r\nexport const HistorySchema = z.object({\r\n max_items: z.number().int().positive().optional(),\r\n});\r\n\r\nexport const ContextSchema = z.object({\r\n inputs: z.array(z.string()).optional(),\r\n history: HistorySchema.optional(),\r\n});\r\n\r\n// --- Metadata ---\r\n\r\nexport const MetadataSchema = z.object({\r\n owner: z.string().optional(),\r\n tags: z.array(z.string()).optional(),\r\n review_required: z.boolean().optional(),\r\n stable: z.boolean().optional(),\r\n});\r\n\r\n// --- MCP block ---\r\n\r\nexport const MCPSchema = z.object({\r\n servers: z.array(MCPServerRefSchema).optional(),\r\n});\r\n\r\n// --- Overrides (subset allowed in environments/tiers) ---\r\n\r\nexport const PromptAssetOverridesSchema = z.object({\r\n model: z.string().optional(),\r\n fallback_models: z.array(z.string()).optional(),\r\n reasoning: ReasoningSchema.optional(),\r\n sampling: SamplingSchema.optional(),\r\n response: ResponseSchema.optional(),\r\n tools: z.array(ToolRefSchema).optional(),\r\n});\r\n\r\nexport type PromptAssetOverrides = z.infer<typeof PromptAssetOverridesSchema>;\r\n\r\n// --- Source tracking ---\r\n\r\nexport const SourceSchema = z.object({\r\n file_path: z.string().optional(),\r\n checksum: z.string().optional(),\r\n});\r\n\r\n// --- Sections (populated by parser) ---\r\n\r\nexport const SectionsSchema = z.object({\r\n system_instructions: z.string().optional(),\r\n prompt_template: z.string().optional(),\r\n notes: z.string().optional(),\r\n});\r\n\r\n// --- Defaults files (folder-level inheritance) ---\r\n\r\nexport const PromptDefaultsSchema = z.object({\r\n metadata: MetadataSchema.optional(),\r\n sections: z.object({\r\n system_instructions: z.string().optional(),\r\n }).optional(),\r\n});\r\n\r\nexport type PromptDefaults = z.infer<typeof PromptDefaultsSchema>;\r\n\r\n// --- Top-level PromptAsset ---\r\n\r\nexport const PromptAssetSchema = z.object({\r\n id: z.string(),\r\n schema_version: z.number().int().positive().default(1),\r\n description: z.string().optional(),\r\n\r\n provider: z.enum(['openai', 'anthropic', 'google', 'gemini', 'openrouter', 'any']).optional(),\r\n model: z.string().optional(),\r\n fallback_models: z.array(z.string()).optional(),\r\n\r\n reasoning: ReasoningSchema.optional(),\r\n sampling: SamplingSchema.optional(),\r\n response: ResponseSchema.optional(),\r\n\r\n tools: z.array(ToolRefSchema).optional(),\r\n mcp: MCPSchema.optional(),\r\n\r\n context: ContextSchema.optional(),\r\n\r\n includes: z.array(z.string()).optional(),\r\n\r\n environments: z.record(PromptAssetOverridesSchema).optional(),\r\n tiers: z.record(PromptAssetOverridesSchema).optional(),\r\n\r\n metadata: MetadataSchema.optional(),\r\n\r\n // Populated by parser, not authored in YAML\r\n sections: SectionsSchema.optional(),\r\n source: SourceSchema.optional(),\r\n});\r\n\r\nexport type PromptAsset = z.infer<typeof PromptAssetSchema>;\r\n\r\n// --- Resolved asset (after includes, overrides applied) ---\r\n\r\nexport interface ResolvedPromptAsset extends PromptAsset {\r\n sections: {\r\n system_instructions?: string;\r\n prompt_template?: string;\r\n notes?: string;\r\n };\r\n source: {\r\n file_path?: string;\r\n checksum?: string;\r\n };\r\n}\r\n","export interface Sections {\r\n system_instructions?: string;\r\n prompt_template?: string;\r\n notes?: string;\r\n}\r\n\r\nconst SECTION_MAP: Record<string, keyof Sections> = {\r\n 'system instructions': 'system_instructions',\r\n 'prompt template': 'prompt_template',\r\n 'notes': 'notes',\r\n};\r\n\r\n/**\r\n * Extract named sections from the markdown body using H1 headings.\r\n * Case-insensitive. H2+ within a section is treated as content.\r\n * If no H1 headings are found, the entire body is treated as prompt_template.\r\n */\r\nexport function extractSections(body: string): Sections {\r\n const lines = body.split('\\n');\r\n const sections: Sections = {};\r\n\r\n let currentKey: keyof Sections | null = null;\r\n let currentLines: string[] = [];\r\n let foundAnyH1 = false;\r\n\r\n for (const line of lines) {\r\n const h1Match = line.match(/^#\\s+(.+)$/);\r\n if (h1Match) {\r\n // Flush previous section\r\n if (currentKey) {\r\n sections[currentKey] = currentLines.join('\\n').trim();\r\n }\r\n\r\n foundAnyH1 = true;\r\n const heading = h1Match[1].trim().toLowerCase();\r\n currentKey = SECTION_MAP[heading] ?? null;\r\n currentLines = [];\r\n } else {\r\n currentLines.push(line);\r\n }\r\n }\r\n\r\n // Flush last section\r\n if (currentKey) {\r\n sections[currentKey] = currentLines.join('\\n').trim();\r\n }\r\n\r\n // If no H1 headings found, treat entire body as prompt_template\r\n if (!foundAnyH1) {\r\n const trimmed = body.trim();\r\n if (trimmed) {\r\n sections.prompt_template = trimmed;\r\n }\r\n }\r\n\r\n return sections;\r\n}\r\n","import { readFile } from 'node:fs/promises';\r\nimport { dirname, join, resolve } from 'node:path';\r\nimport matter from 'gray-matter';\r\nimport { parsePrompt } from './parser.js';\r\nimport type { ParseResult } from './parser.js';\r\nimport { extractSections } from './sections.js';\r\nimport { PromptDefaultsSchema } from '../schema/index.js';\r\nimport type { PromptDefaults } from '../schema/index.js';\r\n\r\nconst DEFAULTS_FILE_NAME = 'defaults.md';\r\n\r\nexport interface LoadPromptOptions {\r\n /**\r\n * Optional boundary directory for defaults discovery.\r\n * If provided, defaults are loaded from this directory down to the prompt directory.\r\n */\r\n defaultsRoot?: string;\r\n}\r\n\r\n/**\r\n * Load and parse a prompt file from disk.\r\n */\r\nexport async function loadPromptFile(filePath: string, options: LoadPromptOptions = {}): Promise<ParseResult> {\r\n const content = await readFile(filePath, 'utf-8');\r\n const parsed = parsePrompt(content, filePath);\r\n // Default the boundary to the file's own directory so traversal never\r\n // walks above the prompt tree when no explicit root is provided.\r\n const root = options.defaultsRoot ?? dirname(filePath);\r\n const defaults = await loadDefaultsForPath(filePath, root);\r\n const asset = applyDefaults(parsed.asset, defaults);\r\n\r\n return {\r\n ...parsed,\r\n asset,\r\n };\r\n}\r\n\r\nasync function loadDefaultsForPath(filePath: string, defaultsRoot?: string): Promise<PromptDefaults> {\r\n const directories = getDirectoriesToCheck(filePath, defaultsRoot);\r\n let merged: PromptDefaults = {};\r\n\r\n for (const dir of directories) {\r\n const defaultsPath = join(dir, DEFAULTS_FILE_NAME);\r\n try {\r\n const defaultsContent = await readFile(defaultsPath, 'utf-8');\r\n const defaults = parseDefaults(defaultsContent);\r\n merged = mergeDefaults(merged, defaults);\r\n } catch (error) {\r\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\r\n throw error;\r\n }\r\n }\r\n }\r\n\r\n return merged;\r\n}\r\n\r\nfunction getDirectoriesToCheck(filePath: string, defaultsRoot?: string): string[] {\r\n const dirs: string[] = [];\r\n let current = resolve(dirname(filePath));\r\n const boundary = defaultsRoot ? resolve(defaultsRoot) : undefined;\r\n\r\n while (true) {\r\n dirs.unshift(current);\r\n if ((boundary && current === boundary) || current === dirname(current)) {\r\n break;\r\n }\r\n current = dirname(current);\r\n }\r\n\r\n return dirs;\r\n}\r\n\r\nfunction parseDefaults(content: string): PromptDefaults {\r\n const { data: frontMatter, content: body } = matter(content);\r\n const sections = extractSections(body);\r\n\r\n return PromptDefaultsSchema.parse({\r\n ...frontMatter,\r\n sections: {\r\n system_instructions: sections.system_instructions,\r\n },\r\n });\r\n}\r\n\r\nfunction mergeDefaults(base: PromptDefaults, local: PromptDefaults): PromptDefaults {\r\n return {\r\n metadata: {\r\n ...(base.metadata ?? {}),\r\n ...(local.metadata ?? {}),\r\n },\r\n sections: {\r\n ...(base.sections ?? {}),\r\n ...(local.sections ?? {}),\r\n },\r\n };\r\n}\r\n\r\nfunction applyDefaults(asset: ParseResult['asset'], defaults: PromptDefaults): ParseResult['asset'] {\r\n const hasDefaultMetadata = defaults.metadata && Object.keys(defaults.metadata).length > 0;\r\n const hasDefaultSystem = !!defaults.sections?.system_instructions;\r\n\r\n // Short-circuit: nothing to merge\r\n if (!hasDefaultMetadata && !hasDefaultSystem) {\r\n return asset;\r\n }\r\n\r\n const mergedMetadata = {\r\n ...(defaults.metadata ?? {}),\r\n ...(asset.metadata ?? {}),\r\n };\r\n const metadata = Object.keys(mergedMetadata).length > 0 ? mergedMetadata : undefined;\r\n\r\n const systemInstructions = asset.sections?.system_instructions ?? defaults.sections?.system_instructions;\r\n\r\n const sections = asset.sections\r\n ? { ...asset.sections, system_instructions: systemInstructions }\r\n : systemInstructions\r\n ? { system_instructions: systemInstructions }\r\n : undefined;\r\n\r\n return {\r\n ...asset,\r\n metadata,\r\n sections,\r\n };\r\n}\r\n"],"mappings":"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","names":["matter","import_gray_matter"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { P as PromptAsset, R as ResolvedPromptAsset } from './schema-C6smABrt.cjs';
|
|
2
|
+
import 'zod';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Create a mock PromptAsset for testing.
|
|
6
|
+
*/
|
|
7
|
+
declare function createMockAsset(overrides?: Partial<PromptAsset>): PromptAsset;
|
|
8
|
+
/**
|
|
9
|
+
* Create a mock ResolvedPromptAsset for testing.
|
|
10
|
+
*/
|
|
11
|
+
declare function createMockResolvedAsset(overrides?: Partial<ResolvedPromptAsset>): ResolvedPromptAsset;
|
|
12
|
+
/**
|
|
13
|
+
* Parse an inline prompt string for testing.
|
|
14
|
+
*/
|
|
15
|
+
declare function parseTestPrompt(source: string): PromptAsset;
|
|
16
|
+
|
|
17
|
+
export { createMockAsset, createMockResolvedAsset, parseTestPrompt };
|
package/dist/testing.d.ts
CHANGED
package/dist/testing.js
CHANGED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { R as ResolvedPromptAsset } from './schema-C6smABrt.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Provider-shaped request body output.
|
|
5
|
+
*/
|
|
6
|
+
interface ProviderRequest {
|
|
7
|
+
body: Record<string, unknown>;
|
|
8
|
+
provider: string;
|
|
9
|
+
model: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Result of validating an asset against a provider.
|
|
13
|
+
*/
|
|
14
|
+
interface ValidationResult {
|
|
15
|
+
valid: boolean;
|
|
16
|
+
errors: string[];
|
|
17
|
+
warnings: string[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Options passed at render time.
|
|
21
|
+
*/
|
|
22
|
+
interface RuntimeRenderOptions {
|
|
23
|
+
variables?: Record<string, string>;
|
|
24
|
+
history?: Array<{
|
|
25
|
+
role: string;
|
|
26
|
+
content: string;
|
|
27
|
+
}>;
|
|
28
|
+
toolRegistry?: Record<string, unknown>;
|
|
29
|
+
strict?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Provider adapter interface. Each provider implements this.
|
|
33
|
+
*/
|
|
34
|
+
interface ProviderAdapter {
|
|
35
|
+
name: string;
|
|
36
|
+
validate(asset: ResolvedPromptAsset): ValidationResult;
|
|
37
|
+
render(asset: ResolvedPromptAsset, runtime: RuntimeRenderOptions): ProviderRequest;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export type { ProviderAdapter as P, RuntimeRenderOptions as R, ValidationResult as V, ProviderRequest as a };
|
package/package.json
CHANGED
|
@@ -1,38 +1,74 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "promptopskit",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Manage prompts, system instructions, tools, and model settings as code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"promptopskit": "./dist/cli/index.js"
|
|
8
8
|
},
|
|
9
|
-
"main": "./dist/index.
|
|
9
|
+
"main": "./dist/index.cjs",
|
|
10
10
|
"module": "./dist/index.js",
|
|
11
11
|
"types": "./dist/index.d.ts",
|
|
12
12
|
"exports": {
|
|
13
13
|
".": {
|
|
14
|
-
"import":
|
|
15
|
-
|
|
14
|
+
"import": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"default": "./dist/index.js"
|
|
17
|
+
},
|
|
18
|
+
"require": {
|
|
19
|
+
"types": "./dist/index.d.cts",
|
|
20
|
+
"default": "./dist/index.cjs"
|
|
21
|
+
}
|
|
16
22
|
},
|
|
17
23
|
"./testing": {
|
|
18
|
-
"import":
|
|
19
|
-
|
|
24
|
+
"import": {
|
|
25
|
+
"types": "./dist/testing.d.ts",
|
|
26
|
+
"default": "./dist/testing.js"
|
|
27
|
+
},
|
|
28
|
+
"require": {
|
|
29
|
+
"types": "./dist/testing.d.cts",
|
|
30
|
+
"default": "./dist/testing.cjs"
|
|
31
|
+
}
|
|
20
32
|
},
|
|
21
33
|
"./openai": {
|
|
22
|
-
"import":
|
|
23
|
-
|
|
34
|
+
"import": {
|
|
35
|
+
"types": "./dist/providers/openai.d.ts",
|
|
36
|
+
"default": "./dist/providers/openai.js"
|
|
37
|
+
},
|
|
38
|
+
"require": {
|
|
39
|
+
"types": "./dist/providers/openai.d.cts",
|
|
40
|
+
"default": "./dist/providers/openai.cjs"
|
|
41
|
+
}
|
|
24
42
|
},
|
|
25
43
|
"./anthropic": {
|
|
26
|
-
"import":
|
|
27
|
-
|
|
44
|
+
"import": {
|
|
45
|
+
"types": "./dist/providers/anthropic.d.ts",
|
|
46
|
+
"default": "./dist/providers/anthropic.js"
|
|
47
|
+
},
|
|
48
|
+
"require": {
|
|
49
|
+
"types": "./dist/providers/anthropic.d.cts",
|
|
50
|
+
"default": "./dist/providers/anthropic.cjs"
|
|
51
|
+
}
|
|
28
52
|
},
|
|
29
53
|
"./gemini": {
|
|
30
|
-
"import":
|
|
31
|
-
|
|
54
|
+
"import": {
|
|
55
|
+
"types": "./dist/providers/gemini.d.ts",
|
|
56
|
+
"default": "./dist/providers/gemini.js"
|
|
57
|
+
},
|
|
58
|
+
"require": {
|
|
59
|
+
"types": "./dist/providers/gemini.d.cts",
|
|
60
|
+
"default": "./dist/providers/gemini.cjs"
|
|
61
|
+
}
|
|
32
62
|
},
|
|
33
63
|
"./openrouter": {
|
|
34
|
-
"import":
|
|
35
|
-
|
|
64
|
+
"import": {
|
|
65
|
+
"types": "./dist/providers/openrouter.d.ts",
|
|
66
|
+
"default": "./dist/providers/openrouter.js"
|
|
67
|
+
},
|
|
68
|
+
"require": {
|
|
69
|
+
"types": "./dist/providers/openrouter.d.cts",
|
|
70
|
+
"default": "./dist/providers/openrouter.cjs"
|
|
71
|
+
}
|
|
36
72
|
}
|
|
37
73
|
},
|
|
38
74
|
"files": [
|
|
@@ -41,9 +77,11 @@
|
|
|
41
77
|
"scripts": {
|
|
42
78
|
"build": "tsup",
|
|
43
79
|
"test": "vitest run",
|
|
80
|
+
"test:serial": "vitest run --no-file-parallelism",
|
|
44
81
|
"test:watch": "vitest",
|
|
45
82
|
"lint": "tsc --noEmit",
|
|
46
|
-
"clean": "rimraf dist"
|
|
83
|
+
"clean": "rimraf dist",
|
|
84
|
+
"prepublishOnly": "npm run lint && npm run test && npm run build"
|
|
47
85
|
},
|
|
48
86
|
"keywords": [
|
|
49
87
|
"prompt",
|
|
@@ -57,7 +95,7 @@
|
|
|
57
95
|
],
|
|
58
96
|
"repository": {
|
|
59
97
|
"type": "git",
|
|
60
|
-
"url": "https://github.com/PredictabilityAtScale/promptopskit.git"
|
|
98
|
+
"url": "git+https://github.com/PredictabilityAtScale/promptopskit.git"
|
|
61
99
|
},
|
|
62
100
|
"homepage": "https://github.com/PredictabilityAtScale/promptopskit",
|
|
63
101
|
"author": "Predictability at Scale, Inc.",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/schema/schema.ts","../src/parser/sections.ts","../src/parser/parser.ts","../src/parser/loader.ts"],"sourcesContent":["import { z } from 'zod';\r\n\r\n// --- Tool definitions ---\r\n\r\nexport const InlineToolDefSchema = z.object({\r\n name: z.string(),\r\n description: z.string().optional(),\r\n input_schema: z.record(z.unknown()).optional(),\r\n});\r\n\r\nexport type InlineToolDef = z.infer<typeof InlineToolDefSchema>;\r\n\r\nexport const ToolRefSchema = z.union([z.string(), InlineToolDefSchema]);\r\n\r\n// --- MCP ---\r\n\r\nexport const MCPServerRefSchema = z.union([\r\n z.string(),\r\n z.object({\r\n name: z.string(),\r\n config: z.record(z.unknown()).optional(),\r\n }),\r\n]);\r\n\r\nexport type MCPServerRef = z.infer<typeof MCPServerRefSchema>;\r\n\r\n// --- Reasoning ---\r\n\r\nexport const ReasoningSchema = z.object({\r\n effort: z.enum(['low', 'medium', 'high']).optional(),\r\n budget_tokens: z.number().int().positive().optional(),\r\n});\r\n\r\n// --- Sampling ---\r\n\r\nexport const SamplingSchema = z.object({\r\n temperature: z.number().min(0).max(2).optional(),\r\n top_p: z.number().min(0).max(1).optional(),\r\n frequency_penalty: z.number().optional(),\r\n presence_penalty: z.number().optional(),\r\n stop: z.array(z.string()).optional(),\r\n max_output_tokens: z.number().int().positive().optional(),\r\n});\r\n\r\n// --- Response ---\r\n\r\nexport const ResponseSchema = z.object({\r\n format: z.enum(['text', 'json', 'markdown']).optional(),\r\n stream: z.boolean().optional(),\r\n});\r\n\r\n// --- Context ---\r\n\r\nexport const HistorySchema = z.object({\r\n max_items: z.number().int().positive().optional(),\r\n});\r\n\r\nexport const ContextSchema = z.object({\r\n inputs: z.array(z.string()).optional(),\r\n history: HistorySchema.optional(),\r\n});\r\n\r\n// --- Metadata ---\r\n\r\nexport const MetadataSchema = z.object({\r\n owner: z.string().optional(),\r\n tags: z.array(z.string()).optional(),\r\n review_required: z.boolean().optional(),\r\n stable: z.boolean().optional(),\r\n});\r\n\r\n// --- MCP block ---\r\n\r\nexport const MCPSchema = z.object({\r\n servers: z.array(MCPServerRefSchema).optional(),\r\n});\r\n\r\n// --- Overrides (subset allowed in environments/tiers) ---\r\n\r\nexport const PromptAssetOverridesSchema = z.object({\r\n model: z.string().optional(),\r\n fallback_models: z.array(z.string()).optional(),\r\n reasoning: ReasoningSchema.optional(),\r\n sampling: SamplingSchema.optional(),\r\n response: ResponseSchema.optional(),\r\n tools: z.array(ToolRefSchema).optional(),\r\n});\r\n\r\nexport type PromptAssetOverrides = z.infer<typeof PromptAssetOverridesSchema>;\r\n\r\n// --- Source tracking ---\r\n\r\nexport const SourceSchema = z.object({\r\n file_path: z.string().optional(),\r\n checksum: z.string().optional(),\r\n});\r\n\r\n// --- Sections (populated by parser) ---\r\n\r\nexport const SectionsSchema = z.object({\r\n system_instructions: z.string().optional(),\r\n prompt_template: z.string().optional(),\r\n notes: z.string().optional(),\r\n});\r\n\r\n// --- Top-level PromptAsset ---\r\n\r\nexport const PromptAssetSchema = z.object({\r\n id: z.string(),\r\n schema_version: z.number().int().positive().default(1),\r\n description: z.string().optional(),\r\n\r\n provider: z.enum(['openai', 'anthropic', 'google', 'openrouter', 'any']).optional(),\r\n model: z.string().optional(),\r\n fallback_models: z.array(z.string()).optional(),\r\n\r\n reasoning: ReasoningSchema.optional(),\r\n sampling: SamplingSchema.optional(),\r\n response: ResponseSchema.optional(),\r\n\r\n tools: z.array(ToolRefSchema).optional(),\r\n mcp: MCPSchema.optional(),\r\n\r\n context: ContextSchema.optional(),\r\n\r\n includes: z.array(z.string()).optional(),\r\n\r\n environments: z.record(PromptAssetOverridesSchema).optional(),\r\n tiers: z.record(PromptAssetOverridesSchema).optional(),\r\n\r\n metadata: MetadataSchema.optional(),\r\n\r\n // Populated by parser, not authored in YAML\r\n sections: SectionsSchema.optional(),\r\n source: SourceSchema.optional(),\r\n});\r\n\r\nexport type PromptAsset = z.infer<typeof PromptAssetSchema>;\r\n\r\n// --- Resolved asset (after includes, overrides applied) ---\r\n\r\nexport interface ResolvedPromptAsset extends PromptAsset {\r\n sections: {\r\n system_instructions?: string;\r\n prompt_template?: string;\r\n notes?: string;\r\n };\r\n source: {\r\n file_path?: string;\r\n checksum?: string;\r\n };\r\n}\r\n","export interface Sections {\r\n system_instructions?: string;\r\n prompt_template?: string;\r\n notes?: string;\r\n}\r\n\r\nconst SECTION_MAP: Record<string, keyof Sections> = {\r\n 'system instructions': 'system_instructions',\r\n 'prompt template': 'prompt_template',\r\n 'notes': 'notes',\r\n};\r\n\r\n/**\r\n * Extract named sections from the markdown body using H1 headings.\r\n * Case-insensitive. H2+ within a section is treated as content.\r\n * If no H1 headings are found, the entire body is treated as prompt_template.\r\n */\r\nexport function extractSections(body: string): Sections {\r\n const lines = body.split('\\n');\r\n const sections: Sections = {};\r\n\r\n let currentKey: keyof Sections | null = null;\r\n let currentLines: string[] = [];\r\n let foundAnyH1 = false;\r\n\r\n for (const line of lines) {\r\n const h1Match = line.match(/^#\\s+(.+)$/);\r\n if (h1Match) {\r\n // Flush previous section\r\n if (currentKey) {\r\n sections[currentKey] = currentLines.join('\\n').trim();\r\n }\r\n\r\n foundAnyH1 = true;\r\n const heading = h1Match[1].trim().toLowerCase();\r\n currentKey = SECTION_MAP[heading] ?? null;\r\n currentLines = [];\r\n } else {\r\n currentLines.push(line);\r\n }\r\n }\r\n\r\n // Flush last section\r\n if (currentKey) {\r\n sections[currentKey] = currentLines.join('\\n').trim();\r\n }\r\n\r\n // If no H1 headings found, treat entire body as prompt_template\r\n if (!foundAnyH1) {\r\n const trimmed = body.trim();\r\n if (trimmed) {\r\n sections.prompt_template = trimmed;\r\n }\r\n }\r\n\r\n return sections;\r\n}\r\n","import matter from 'gray-matter';\r\nimport { PromptAssetSchema } from '../schema/index.js';\r\nimport type { PromptAsset } from '../schema/index.js';\r\nimport { extractSections } from './sections.js';\r\n\r\nexport interface ParseResult {\r\n asset: PromptAsset;\r\n raw: {\r\n frontMatter: Record<string, unknown>;\r\n body: string;\r\n };\r\n}\r\n\r\n/**\r\n * Parse a prompt markdown string (YAML front matter + markdown body)\r\n * into a validated PromptAsset.\r\n */\r\nexport function parsePrompt(content: string, filePath?: string): ParseResult {\r\n const { data: frontMatter, content: body } = matter(content);\r\n\r\n const sections = extractSections(body);\r\n\r\n const raw = {\r\n ...frontMatter,\r\n sections,\r\n source: filePath ? { file_path: filePath } : undefined,\r\n };\r\n\r\n const asset = PromptAssetSchema.parse(raw);\r\n\r\n return {\r\n asset,\r\n raw: {\r\n frontMatter: frontMatter as Record<string, unknown>,\r\n body,\r\n },\r\n };\r\n}\r\n","import { readFile } from 'node:fs/promises';\r\nimport { parsePrompt } from './parser.js';\r\nimport type { ParseResult } from './parser.js';\r\n\r\n/**\r\n * Load and parse a prompt file from disk.\r\n */\r\nexport async function loadPromptFile(filePath: string): Promise<ParseResult> {\r\n const content = await readFile(filePath, 'utf-8');\r\n return parsePrompt(content, filePath);\r\n}\r\n"],"mappings":"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","names":[]}
|