@zihanw/pi-forge 0.2.0 → 0.3.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 (161) hide show
  1. package/README.md +233 -105
  2. package/README.zh-CN.md +215 -104
  3. package/dist/compiler.d.ts +10 -0
  4. package/dist/compiler.d.ts.map +1 -0
  5. package/dist/compiler.js +490 -0
  6. package/dist/compiler.js.map +1 -0
  7. package/dist/extension-registry.d.ts +25 -0
  8. package/dist/extension-registry.d.ts.map +1 -0
  9. package/dist/extension-registry.js +6 -0
  10. package/dist/extension-registry.js.map +1 -0
  11. package/dist/index.d.ts +7 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +364 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/lifecycle.d.ts +14 -0
  16. package/dist/lifecycle.d.ts.map +1 -0
  17. package/dist/lifecycle.js +139 -0
  18. package/dist/lifecycle.js.map +1 -0
  19. package/dist/loader.d.ts +8 -0
  20. package/dist/loader.d.ts.map +1 -0
  21. package/dist/loader.js +345 -0
  22. package/dist/loader.js.map +1 -0
  23. package/dist/macro-engine.d.ts +23 -0
  24. package/dist/macro-engine.d.ts.map +1 -0
  25. package/dist/macro-engine.js +262 -0
  26. package/dist/macro-engine.js.map +1 -0
  27. package/dist/payload-capture.d.ts +15 -0
  28. package/dist/payload-capture.d.ts.map +1 -0
  29. package/dist/payload-capture.js +86 -0
  30. package/dist/payload-capture.js.map +1 -0
  31. package/dist/payload-command.d.ts +10 -0
  32. package/dist/payload-command.d.ts.map +1 -0
  33. package/dist/payload-command.js +112 -0
  34. package/dist/payload-command.js.map +1 -0
  35. package/dist/policy.d.ts +6 -0
  36. package/dist/policy.d.ts.map +1 -0
  37. package/dist/policy.js +38 -0
  38. package/dist/policy.js.map +1 -0
  39. package/dist/preset-command.d.ts +14 -0
  40. package/dist/preset-command.d.ts.map +1 -0
  41. package/dist/preset-command.js +223 -0
  42. package/dist/preset-command.js.map +1 -0
  43. package/dist/preview.d.ts +12 -0
  44. package/dist/preview.d.ts.map +1 -0
  45. package/dist/preview.js +179 -0
  46. package/dist/preview.js.map +1 -0
  47. package/dist/regex.d.ts +7 -0
  48. package/dist/regex.d.ts.map +1 -0
  49. package/dist/regex.js +432 -0
  50. package/dist/regex.js.map +1 -0
  51. package/dist/render-helpers.d.ts +44 -0
  52. package/dist/render-helpers.d.ts.map +1 -0
  53. package/dist/render-helpers.js +128 -0
  54. package/dist/render-helpers.js.map +1 -0
  55. package/dist/runtime-state.d.ts +24 -0
  56. package/dist/runtime-state.d.ts.map +1 -0
  57. package/dist/runtime-state.js +13 -0
  58. package/dist/runtime-state.js.map +1 -0
  59. package/dist/sillytavern-importer/items.d.ts +3 -0
  60. package/dist/sillytavern-importer/items.d.ts.map +1 -0
  61. package/dist/sillytavern-importer/items.js +88 -0
  62. package/dist/sillytavern-importer/items.js.map +1 -0
  63. package/dist/sillytavern-importer/macros.d.ts +15 -0
  64. package/dist/sillytavern-importer/macros.d.ts.map +1 -0
  65. package/dist/sillytavern-importer/macros.js +141 -0
  66. package/dist/sillytavern-importer/macros.js.map +1 -0
  67. package/dist/sillytavern-importer/prompt-order.d.ts +6 -0
  68. package/dist/sillytavern-importer/prompt-order.d.ts.map +1 -0
  69. package/dist/sillytavern-importer/prompt-order.js +38 -0
  70. package/dist/sillytavern-importer/prompt-order.js.map +1 -0
  71. package/dist/sillytavern-importer/regex.d.ts +3 -0
  72. package/dist/sillytavern-importer/regex.d.ts.map +1 -0
  73. package/dist/sillytavern-importer/regex.js +275 -0
  74. package/dist/sillytavern-importer/regex.js.map +1 -0
  75. package/dist/sillytavern-importer/report.d.ts +21 -0
  76. package/dist/sillytavern-importer/report.d.ts.map +1 -0
  77. package/dist/sillytavern-importer/report.js +166 -0
  78. package/dist/sillytavern-importer/report.js.map +1 -0
  79. package/dist/sillytavern-importer/types.d.ts +106 -0
  80. package/dist/sillytavern-importer/types.d.ts.map +1 -0
  81. package/dist/sillytavern-importer/types.js +2 -0
  82. package/dist/sillytavern-importer/types.js.map +1 -0
  83. package/dist/sillytavern-importer.d.ts +5 -0
  84. package/dist/sillytavern-importer.d.ts.map +1 -0
  85. package/dist/sillytavern-importer.js +117 -0
  86. package/dist/sillytavern-importer.js.map +1 -0
  87. package/dist/slot-renderers.d.ts +25 -0
  88. package/dist/slot-renderers.d.ts.map +1 -0
  89. package/dist/slot-renderers.js +334 -0
  90. package/dist/slot-renderers.js.map +1 -0
  91. package/dist/stack-migration.d.ts +29 -0
  92. package/dist/stack-migration.d.ts.map +1 -0
  93. package/dist/stack-migration.js +126 -0
  94. package/dist/stack-migration.js.map +1 -0
  95. package/dist/storage.d.ts +6 -0
  96. package/dist/storage.d.ts.map +1 -0
  97. package/dist/storage.js +23 -0
  98. package/dist/storage.js.map +1 -0
  99. package/dist/types.d.ts +173 -0
  100. package/dist/types.d.ts.map +1 -0
  101. package/dist/types.js +2 -0
  102. package/dist/types.js.map +1 -0
  103. package/dist/web-editor/index.d.ts +3 -0
  104. package/dist/web-editor/index.d.ts.map +1 -0
  105. package/dist/web-editor/index.js +2 -0
  106. package/dist/web-editor/index.js.map +1 -0
  107. package/dist/web-editor/page.d.ts +2 -0
  108. package/dist/web-editor/page.d.ts.map +1 -0
  109. package/dist/web-editor/page.js +3331 -0
  110. package/dist/web-editor/page.js.map +1 -0
  111. package/dist/web-editor/server.d.ts +4 -0
  112. package/dist/web-editor/server.d.ts.map +1 -0
  113. package/dist/web-editor/server.js +263 -0
  114. package/dist/web-editor/server.js.map +1 -0
  115. package/dist/web-editor/types.d.ts +125 -0
  116. package/dist/web-editor/types.d.ts.map +1 -0
  117. package/dist/web-editor/types.js +2 -0
  118. package/dist/web-editor/types.js.map +1 -0
  119. package/dist/web-host.d.ts +29 -0
  120. package/dist/web-host.d.ts.map +1 -0
  121. package/dist/web-host.js +174 -0
  122. package/dist/web-host.js.map +1 -0
  123. package/examples/custom-system-status-extension/README.md +78 -0
  124. package/examples/custom-system-status-extension/index.ts +176 -0
  125. package/examples/custom-system-status-extension/prompt-stack.json +39 -0
  126. package/examples/default-prompt-stack.json +52 -93
  127. package/examples/image-reader-prompt-stack.json +124 -0
  128. package/examples/reviewer-prompt-stack.json +115 -0
  129. package/examples/sillytavern-dm-writer-prompt-stack.json +190 -0
  130. package/package.json +30 -9
  131. package/src/compiler.ts +321 -420
  132. package/src/extension-registry.ts +33 -0
  133. package/src/index.ts +310 -1110
  134. package/src/lifecycle.ts +171 -0
  135. package/src/loader.ts +141 -56
  136. package/src/macro-engine.ts +358 -0
  137. package/src/payload-capture.ts +85 -0
  138. package/src/payload-command.ts +138 -0
  139. package/src/policy.ts +42 -0
  140. package/src/preset-command.ts +271 -0
  141. package/src/preview.ts +226 -0
  142. package/src/regex.ts +500 -0
  143. package/src/render-helpers.ts +169 -0
  144. package/src/runtime-state.ts +36 -0
  145. package/src/sillytavern-importer/items.ts +98 -0
  146. package/src/sillytavern-importer/macros.ts +159 -0
  147. package/src/sillytavern-importer/prompt-order.ts +54 -0
  148. package/src/sillytavern-importer/regex.ts +270 -0
  149. package/src/sillytavern-importer/report.ts +202 -0
  150. package/src/sillytavern-importer/types.ts +120 -0
  151. package/src/sillytavern-importer.ts +57 -482
  152. package/src/slot-renderers.ts +414 -0
  153. package/src/stack-migration.ts +159 -0
  154. package/src/storage.ts +28 -0
  155. package/src/types.ts +83 -52
  156. package/src/web-editor/index.ts +2 -0
  157. package/src/web-editor/page.ts +3330 -0
  158. package/src/web-editor/server.ts +294 -0
  159. package/src/web-editor/types.ts +98 -0
  160. package/src/web-host.ts +232 -0
  161. package/src/web-editor.ts +0 -1491
package/dist/loader.js ADDED
@@ -0,0 +1,345 @@
1
+ import { existsSync, readdirSync, readFileSync } from "node:fs";
2
+ import { basename, join } from "node:path";
3
+ import { validateRegexConfig } from "./regex.js";
4
+ import { promptStackReadDirs } from "./storage.js";
5
+ import { SUPPORTED_SLOTS } from "./types.js";
6
+ const VALID_ROLES = new Set(["system", "user", "assistant", "custom"]);
7
+ const VALID_CHAT_HISTORY_TOOL_MODES = new Set(["keep", "drop"]);
8
+ export { isInsidePromptStackStorage, legacyPromptStacksDir, promptStackPath, promptStackReadDirs, promptStacksDir } from "./storage.js";
9
+ export function loadPromptStacks(cwd) {
10
+ const files = promptStackFiles(cwd);
11
+ const loaded = files.map(loadPromptStackFile);
12
+ annotateDuplicateStackIds(loaded);
13
+ return loaded;
14
+ }
15
+ function promptStackFiles(cwd) {
16
+ const files = [];
17
+ const shadowedNames = new Set();
18
+ for (const dir of promptStackReadDirs(cwd)) {
19
+ if (!existsSync(dir))
20
+ continue;
21
+ let entries;
22
+ try {
23
+ entries = readdirSync(dir).filter((name) => name.endsWith(".json"));
24
+ }
25
+ catch {
26
+ continue;
27
+ }
28
+ for (const name of entries.sort()) {
29
+ if (shadowedNames.has(name))
30
+ continue;
31
+ shadowedNames.add(name);
32
+ files.push(join(dir, name));
33
+ }
34
+ }
35
+ return files;
36
+ }
37
+ function annotateDuplicateStackIds(stacks) {
38
+ const byId = new Map();
39
+ for (const loaded of stacks) {
40
+ const id = loaded.stack.id;
41
+ const matches = byId.get(id) ?? [];
42
+ matches.push(loaded);
43
+ byId.set(id, matches);
44
+ }
45
+ for (const [id, matches] of byId) {
46
+ if (matches.length <= 1)
47
+ continue;
48
+ const files = matches.map((loaded) => basename(loaded.filePath)).join(", ");
49
+ for (const loaded of matches) {
50
+ loaded.diagnostics.push({
51
+ level: "error",
52
+ message: `Duplicate stack id: ${id} appears in multiple files (${files}).`,
53
+ });
54
+ }
55
+ }
56
+ }
57
+ export function chooseDefaultStack(stacks, preferredId) {
58
+ if (isDisabledPromptStackId(preferredId))
59
+ return undefined;
60
+ if (preferredId) {
61
+ const preferred = stacks.find((loaded) => loaded.stack.id === preferredId);
62
+ if (preferred && isUsablePromptStack(preferred))
63
+ return preferred;
64
+ }
65
+ const defaultStack = stacks.find((loaded) => basename(loaded.filePath) === "default.json" &&
66
+ loaded.stack.autoActivate !== false &&
67
+ isUsablePromptStack(loaded));
68
+ if (defaultStack)
69
+ return defaultStack;
70
+ return stacks.find((loaded) => loaded.stack.autoActivate === true && isUsablePromptStack(loaded));
71
+ }
72
+ export function isUsablePromptStack(loaded) {
73
+ return !loaded.diagnostics.some((diagnostic) => diagnostic.level === "error");
74
+ }
75
+ export function isDisabledPromptStackId(id) {
76
+ return id === "none" || id === "off";
77
+ }
78
+ function loadPromptStackFile(filePath) {
79
+ const diagnostics = [];
80
+ let raw;
81
+ try {
82
+ raw = JSON.parse(readFileSync(filePath, "utf8"));
83
+ }
84
+ catch (error) {
85
+ return {
86
+ filePath,
87
+ stack: fallbackStack(filePath),
88
+ diagnostics: [
89
+ {
90
+ level: "error",
91
+ message: `Failed to parse JSON: ${error instanceof Error ? error.message : String(error)}`,
92
+ },
93
+ ],
94
+ };
95
+ }
96
+ const stack = normalizeStack(raw, filePath, diagnostics);
97
+ diagnostics.push(...validatePromptStack(stack));
98
+ return { filePath, stack, diagnostics };
99
+ }
100
+ function fallbackStack(filePath) {
101
+ return {
102
+ schemaVersion: 1,
103
+ type: "pi-forge.prompt-stack",
104
+ id: basename(filePath, ".json"),
105
+ name: basename(filePath),
106
+ items: [],
107
+ };
108
+ }
109
+ function normalizeStack(raw, filePath, diagnostics) {
110
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
111
+ diagnostics.push({ level: "error", message: "Prompt stack root must be a JSON object." });
112
+ return fallbackStack(filePath);
113
+ }
114
+ const obj = raw;
115
+ const id = typeof obj.id === "string" && obj.id.trim() ? obj.id.trim() : basename(filePath, ".json");
116
+ const schemaVersion = 1;
117
+ if (obj.schemaVersion !== 1) {
118
+ diagnostics.push({ level: "warning", message: "Missing or unsupported schemaVersion; assuming 1." });
119
+ }
120
+ const items = Array.isArray(obj.items) ? obj.items.map((item, index) => normalizeItem(item, index, diagnostics)) : [];
121
+ if (!Array.isArray(obj.items)) {
122
+ diagnostics.push({ level: "error", message: "Prompt stack must contain an items array." });
123
+ }
124
+ if (isPlainObject(obj.state) && Object.keys(obj.state).length > 0) {
125
+ diagnostics.push({
126
+ level: "info",
127
+ message: "state is no longer supported and was ignored; use stack.variables and template variable macros instead.",
128
+ });
129
+ }
130
+ return {
131
+ schemaVersion,
132
+ type: obj.type === "pi-forge.prompt-stack" ? "pi-forge.prompt-stack" : undefined,
133
+ id,
134
+ name: typeof obj.name === "string" ? obj.name : undefined,
135
+ description: typeof obj.description === "string" ? obj.description : undefined,
136
+ autoActivate: typeof obj.autoActivate === "boolean" ? obj.autoActivate : undefined,
137
+ mode: obj.mode === "append" || obj.mode === "prepend" || obj.mode === "replace" ? obj.mode : undefined,
138
+ defaults: isPlainObject(obj.defaults) ? obj.defaults : undefined,
139
+ context: isPlainObject(obj.context) ? obj.context : undefined,
140
+ tools: normalizeResourcePolicy(obj.tools, "tools", diagnostics),
141
+ skills: normalizeResourcePolicy(obj.skills, "skills", diagnostics),
142
+ variables: normalizeStringRecord(obj.variables),
143
+ regex: normalizeRegexConfig(obj.regex, diagnostics),
144
+ items,
145
+ import: isPlainObject(obj.import) ? obj.import : undefined,
146
+ };
147
+ }
148
+ function normalizeItem(raw, index, diagnostics) {
149
+ const fallbackId = `item-${index + 1}`;
150
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
151
+ diagnostics.push({ level: "error", message: `Item ${index + 1} must be an object.`, itemId: fallbackId });
152
+ return { kind: "block", id: fallbackId, enabled: false, content: "" };
153
+ }
154
+ const obj = raw;
155
+ const kind = obj.kind === "slot" ? "slot" : "block";
156
+ const id = normalizeId(obj.id, fallbackId);
157
+ const base = {
158
+ kind,
159
+ id,
160
+ name: typeof obj.name === "string" ? obj.name : undefined,
161
+ enabled: typeof obj.enabled === "boolean" ? obj.enabled : undefined,
162
+ role: VALID_ROLES.has(obj.role) ? obj.role : undefined,
163
+ tags: Array.isArray(obj.tags) ? obj.tags.filter((tag) => typeof tag === "string") : undefined,
164
+ source: isPlainObject(obj.source) ? obj.source : undefined,
165
+ };
166
+ if (kind === "slot") {
167
+ return {
168
+ ...base,
169
+ kind: "slot",
170
+ slot: typeof obj.slot === "string" ? obj.slot : "",
171
+ options: isPlainObject(obj.options) ? obj.options : undefined,
172
+ };
173
+ }
174
+ return {
175
+ ...base,
176
+ kind: "block",
177
+ content: typeof obj.content === "string" ? obj.content : "",
178
+ };
179
+ }
180
+ export function validatePromptStack(stack) {
181
+ const diagnostics = [];
182
+ const ids = new Set();
183
+ let chatHistoryCount = 0;
184
+ if (!stack.id.trim())
185
+ diagnostics.push({ level: "error", message: "Stack id must not be empty." });
186
+ for (const item of stack.items) {
187
+ if (ids.has(item.id))
188
+ diagnostics.push({ level: "error", message: `Duplicate item id: ${item.id}`, itemId: item.id });
189
+ ids.add(item.id);
190
+ if (item.role && !VALID_ROLES.has(item.role)) {
191
+ diagnostics.push({ level: "error", message: `Invalid role: ${item.role}`, itemId: item.id });
192
+ }
193
+ if (item.kind === "slot") {
194
+ if (!SUPPORTED_SLOTS.has(item.slot)) {
195
+ diagnostics.push({ level: "warning", message: `Unsupported slot: ${item.slot}`, itemId: item.id });
196
+ }
197
+ if (item.enabled !== false && item.slot === "chat-history")
198
+ chatHistoryCount++;
199
+ if (item.slot === "chat-history")
200
+ validateChatHistoryOptions(item, diagnostics);
201
+ }
202
+ if (item.kind === "block" && item.role !== "system" && item.enabled !== false && !item.role) {
203
+ diagnostics.push({ level: "warning", message: "Enabled block has no role and will be ignored.", itemId: item.id });
204
+ }
205
+ }
206
+ if (chatHistoryCount === 0) {
207
+ diagnostics.push({
208
+ level: "warning",
209
+ message: "No enabled chat-history slot found; Pi chat context will be appended at the end.",
210
+ });
211
+ }
212
+ else if (chatHistoryCount > 1 && !stack.context?.allowDuplicateChatHistory) {
213
+ diagnostics.push({
214
+ level: "warning",
215
+ message: "Multiple enabled chat-history slots found; only the first will be expanded unless context.allowDuplicateChatHistory is true.",
216
+ });
217
+ }
218
+ diagnostics.push(...validateResourcePolicy(stack.tools, "tools"));
219
+ diagnostics.push(...validateResourcePolicy(stack.skills, "skills"));
220
+ if ((stack.mode === "append" || stack.mode === "prepend") && hasPolicyEntries(stack.skills)) {
221
+ diagnostics.push({
222
+ level: "warning",
223
+ message: "skills policy only filters pi-forge skills slots. Use mode \"replace\" if you need the base Pi prompt to omit filtered skills.",
224
+ });
225
+ }
226
+ diagnostics.push(...validateRegexConfig(stack.regex));
227
+ return diagnostics;
228
+ }
229
+ function validateChatHistoryOptions(item, diagnostics) {
230
+ const options = item.options;
231
+ if (!options)
232
+ return;
233
+ for (const key of ["includeLastUserMessage", "stripAssistantThinking", "includeSummaries"]) {
234
+ const value = options[key];
235
+ if (value !== undefined && typeof value !== "boolean") {
236
+ diagnostics.push({ level: "warning", message: `chat-history option ${key} should be a boolean.`, itemId: item.id });
237
+ }
238
+ }
239
+ if (options.roles !== undefined && !isStringArray(options.roles)) {
240
+ diagnostics.push({ level: "error", message: "chat-history option roles must be an array of strings.", itemId: item.id });
241
+ }
242
+ if (options.toolMode !== undefined && (typeof options.toolMode !== "string" || !VALID_CHAT_HISTORY_TOOL_MODES.has(options.toolMode))) {
243
+ diagnostics.push({ level: "error", message: 'chat-history option toolMode must be "keep" or "drop".', itemId: item.id });
244
+ }
245
+ for (const key of ["maxMessages", "maxChars"]) {
246
+ const value = options[key];
247
+ if (value !== undefined && !isPositiveInteger(value)) {
248
+ diagnostics.push({ level: "error", message: `chat-history option ${key} must be a positive integer.`, itemId: item.id });
249
+ }
250
+ }
251
+ }
252
+ function normalizeId(value, fallback) {
253
+ if (typeof value === "string" && value.trim())
254
+ return value.trim();
255
+ if (typeof value === "number" && Number.isFinite(value))
256
+ return String(value);
257
+ return fallback;
258
+ }
259
+ function isStringArray(value) {
260
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
261
+ }
262
+ function isPositiveInteger(value) {
263
+ return typeof value === "number" && Number.isInteger(value) && value > 0;
264
+ }
265
+ function isPlainObject(value) {
266
+ return !!value && typeof value === "object" && !Array.isArray(value);
267
+ }
268
+ function normalizeStringRecord(value) {
269
+ if (!isPlainObject(value))
270
+ return undefined;
271
+ const result = {};
272
+ for (const [key, raw] of Object.entries(value)) {
273
+ if (typeof raw === "string")
274
+ result[key] = raw;
275
+ }
276
+ return result;
277
+ }
278
+ function normalizeResourcePolicy(value, label, diagnostics) {
279
+ if (value === undefined)
280
+ return undefined;
281
+ if (!isPlainObject(value)) {
282
+ diagnostics.push({ level: "error", message: `${label} policy must be an object when provided.` });
283
+ return undefined;
284
+ }
285
+ const allow = normalizePolicyPatterns(value.allow, `${label}.allow`, diagnostics);
286
+ const deny = normalizePolicyPatterns(value.deny, `${label}.deny`, diagnostics);
287
+ if (allow && deny) {
288
+ diagnostics.push({ level: "error", message: `${label} policy must use either allow or deny, not both.` });
289
+ return { allow };
290
+ }
291
+ if (allow)
292
+ return { allow };
293
+ if (deny)
294
+ return { deny };
295
+ return {};
296
+ }
297
+ function normalizePolicyPatterns(value, label, diagnostics) {
298
+ if (value === undefined)
299
+ return undefined;
300
+ if (!Array.isArray(value)) {
301
+ diagnostics.push({ level: "error", message: `${label} must be an array of strings when provided.` });
302
+ return undefined;
303
+ }
304
+ const patterns = [];
305
+ for (const [index, item] of value.entries()) {
306
+ if (typeof item !== "string" || !item.trim()) {
307
+ diagnostics.push({ level: "error", message: `${label}[${index}] must be a non-empty string.` });
308
+ continue;
309
+ }
310
+ patterns.push(item.trim());
311
+ }
312
+ return patterns.length > 0 ? patterns : undefined;
313
+ }
314
+ function validateResourcePolicy(policy, label) {
315
+ const diagnostics = [];
316
+ if ((policy?.allow?.length ?? 0) > 0 && (policy?.deny?.length ?? 0) > 0) {
317
+ diagnostics.push({ level: "error", message: `${label} policy must use either allow or deny, not both.` });
318
+ }
319
+ for (const key of ["allow", "deny"]) {
320
+ const values = policy?.[key];
321
+ if (!values)
322
+ continue;
323
+ const seen = new Set();
324
+ for (const value of values) {
325
+ if (seen.has(value)) {
326
+ diagnostics.push({ level: "warning", message: `Duplicate ${label}.${key} pattern: ${value}.` });
327
+ }
328
+ seen.add(value);
329
+ }
330
+ }
331
+ return diagnostics;
332
+ }
333
+ function hasPolicyEntries(policy) {
334
+ return !!policy && ((policy.allow?.length ?? 0) > 0 || (policy.deny?.length ?? 0) > 0);
335
+ }
336
+ function normalizeRegexConfig(value, diagnostics) {
337
+ if (value === undefined)
338
+ return undefined;
339
+ if (!isPlainObject(value)) {
340
+ diagnostics.push({ level: "warning", message: "regex must be an object when provided." });
341
+ return undefined;
342
+ }
343
+ return value;
344
+ }
345
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { PromptRuntime, PromptStack, PromptStackDiagnostic } from "./types.ts";
2
+ import { type PromptRenderHelpers, type PromptVariableAccess } from "./render-helpers.ts";
3
+ import { type PromptExtensionArgumentDefinition, type PromptRegistryEntry } from "./extension-registry.ts";
4
+ export interface PromptMacroRenderContext {
5
+ name: string;
6
+ command: string;
7
+ stack: PromptStack;
8
+ runtime: PromptRuntime;
9
+ rawArgs: readonly string[];
10
+ expandArg: (index: number) => string;
11
+ expandJoinedArgs: (startIndex: number) => string;
12
+ helpers: PromptRenderHelpers;
13
+ variables: PromptVariableAccess;
14
+ }
15
+ export type PromptMacroRenderer = (context: PromptMacroRenderContext) => string | undefined;
16
+ export interface PromptMacroDefinition extends PromptRegistryEntry {
17
+ args?: readonly PromptExtensionArgumentDefinition[];
18
+ render: PromptMacroRenderer;
19
+ }
20
+ export declare function expandMacros(text: string, stack: PromptStack, runtime: PromptRuntime, diagnostics: PromptStackDiagnostic[], itemId: string): string;
21
+ export declare function registerMacro(definition: PromptMacroDefinition): () => void;
22
+ export declare function getRegisteredMacros(): readonly PromptMacroDefinition[];
23
+ //# sourceMappingURL=macro-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"macro-engine.d.ts","sourceRoot":"","sources":["../src/macro-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,aAAa,EACb,WAAW,EACX,qBAAqB,EACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EAQN,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EAGzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAsB,KAAK,iCAAiC,EAAE,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAU/H,MAAM,WAAW,wBAAwB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,aAAa,CAAC;IACvB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACrC,gBAAgB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IACjD,OAAO,EAAE,mBAAmB,CAAC;IAC7B,SAAS,EAAE,oBAAoB,CAAC;CAChC;AAED,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,EAAE,wBAAwB,KAAK,MAAM,GAAG,SAAS,CAAC;AAE5F,MAAM,WAAW,qBAAsB,SAAQ,mBAAmB;IACjE,IAAI,CAAC,EAAE,SAAS,iCAAiC,EAAE,CAAC;IACpD,MAAM,EAAE,mBAAmB,CAAC;CAC5B;AAqDD,wBAAgB,YAAY,CAC3B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,aAAa,EACtB,WAAW,EAAE,qBAAqB,EAAE,EACpC,MAAM,EAAE,MAAM,GACZ,MAAM,CAeR;AAED,wBAAgB,aAAa,CAAC,UAAU,EAAE,qBAAqB,GAAG,MAAM,IAAI,CAU3E;AAED,wBAAgB,mBAAmB,IAAI,SAAS,qBAAqB,EAAE,CAEtE"}
@@ -0,0 +1,262 @@
1
+ import { createVariableAccess, escapeXml, formatDate, formatTime, getRuntimeVariable, promptRenderHelpers, selectedToolNames, variableValueToMacroText, } from "./render-helpers.js";
2
+ import { assertRegistryName } from "./extension-registry.js";
3
+ function macroRegistryState() {
4
+ const globalScope = globalThis;
5
+ globalScope.__piForgeMacroRegistry ??= { macros: new Map() };
6
+ return globalScope.__piForgeMacroRegistry;
7
+ }
8
+ const MACROS = macroRegistryState().macros;
9
+ let registeringBuiltInMacros = true;
10
+ registerMacro({ name: "cwd", description: "Current working directory.", render: ({ runtime }) => runtime.options.cwd });
11
+ registerMacro({ name: "date", description: "Current date in YYYY-MM-DD format.", render: ({ runtime }) => formatDate(runtime.now) });
12
+ registerMacro({ name: "time", description: "Current time in HH:MM:SS format.", render: ({ runtime }) => formatTime(runtime.now) });
13
+ registerMacro({ name: "lastUserMessage", description: "Latest user message text.", render: ({ runtime }) => runtime.latestUserMessage ?? "" });
14
+ registerMacro({ name: "selectedTools", description: "Comma-separated selected tool names after stack policy.", render: renderSelectedTools });
15
+ registerMacro({ name: "tools", description: "Alias for selectedTools.", render: renderSelectedTools });
16
+ registerMacro({ name: "activeModel", description: "Current model as provider/id.", render: ({ runtime }) => {
17
+ const model = runtime.ctx?.model;
18
+ return model ? `${model.provider}/${model.id}` : "";
19
+ } });
20
+ registerMacro({ name: "setvar", description: "Set a turn variable, or set a scoped variable with setvar::session|turn::name::value.", render: renderSetVariable });
21
+ registerMacro({ name: "setturnvar", description: "Set a turn variable.", render: renderSetVariable });
22
+ registerMacro({ name: "setsessionvar", description: "Set a session variable.", render: renderSetVariable });
23
+ registerMacro({ name: "getvar", description: "Read a turn, session, or static variable.", render: renderGetVariable });
24
+ registerMacro({ name: "var", description: "Alias for getvar.", render: renderGetVariable });
25
+ registerMacro({ name: "getturnvar", description: "Read a turn variable.", render: renderGetVariable });
26
+ registerMacro({ name: "getsessionvar", description: "Read a session variable.", render: renderGetVariable });
27
+ registerMacro({ name: "clearvar", description: "Clear a turn variable, or clear a scoped variable with clearvar::session|turn::name.", render: renderClearVariable });
28
+ registerMacro({ name: "clearturnvar", description: "Clear a turn variable.", render: renderClearVariable });
29
+ registerMacro({ name: "clearsessionvar", description: "Clear a session variable.", render: renderClearVariable });
30
+ registerMacro({ name: "trim", description: "Trim whitespace from an expanded argument.", args: [{ name: "value", required: true }], render: ({ expandArg }) => expandArg(0).trim() });
31
+ registerMacro({ name: "upper", description: "Uppercase an expanded argument.", args: [{ name: "value", required: true }], render: ({ expandArg }) => expandArg(0).toUpperCase() });
32
+ registerMacro({ name: "lower", description: "Lowercase an expanded argument.", args: [{ name: "value", required: true }], render: ({ expandArg }) => expandArg(0).toLowerCase() });
33
+ registerMacro({ name: "json", description: "JSON-string escape an expanded argument.", args: [{ name: "value", required: true }], render: ({ expandArg }) => JSON.stringify(expandArg(0)) });
34
+ registerMacro({ name: "xml", description: "XML-escape an expanded argument.", args: [{ name: "value", required: true }], render: ({ expandArg }) => escapeXml(expandArg(0)) });
35
+ registerMacro({ name: "ifvar", description: "Render a lazy branch based on whether a variable exists.", render: renderIfVariable });
36
+ registerMacro({ name: "ifeq", description: "Render a lazy branch based on whether a variable equals a string.", render: renderIfVariableEquals });
37
+ registerMacro({ name: "iftools", description: "Render a lazy branch based on whether a tool is selected.", render: renderIfTool });
38
+ registerMacro({ name: "ifslot", description: "Render a lazy branch based on whether an enabled slot exists in the stack.", render: renderIfSlot });
39
+ registeringBuiltInMacros = false;
40
+ export function expandMacros(text, stack, runtime, diagnostics, itemId) {
41
+ const policy = stack.defaults?.unresolvedMacroPolicy ?? "warn";
42
+ const state = { stack, runtime, diagnostics, itemId, unknown: new Set() };
43
+ const result = expandMacroText(text, state);
44
+ for (const name of state.unknown) {
45
+ if (policy === "keep")
46
+ continue;
47
+ diagnostics.push({
48
+ level: policy === "error" ? "error" : "warning",
49
+ message: `Unresolved macro: {{${name}}}`,
50
+ itemId,
51
+ });
52
+ }
53
+ return result;
54
+ }
55
+ export function registerMacro(definition) {
56
+ assertRegistryName("Macro", definition.name);
57
+ if (MACROS.has(definition.name)) {
58
+ if (registeringBuiltInMacros)
59
+ return () => { };
60
+ throw new Error(`Macro is already registered: ${definition.name}`);
61
+ }
62
+ MACROS.set(definition.name, definition);
63
+ return () => {
64
+ if (MACROS.get(definition.name) === definition)
65
+ MACROS.delete(definition.name);
66
+ };
67
+ }
68
+ export function getRegisteredMacros() {
69
+ return [...MACROS.values()];
70
+ }
71
+ function expandMacroText(text, state) {
72
+ let result = "";
73
+ let index = 0;
74
+ while (index < text.length) {
75
+ const start = text.indexOf("{{", index);
76
+ if (start === -1) {
77
+ result += text.slice(index);
78
+ break;
79
+ }
80
+ result += text.slice(index, start);
81
+ const end = findMacroEnd(text, start + 2);
82
+ if (end === undefined) {
83
+ result += "{{";
84
+ index = start + 2;
85
+ continue;
86
+ }
87
+ const expression = text.slice(start + 2, end);
88
+ const fullMacro = text.slice(start, end + 2);
89
+ result += renderMacro(expression, fullMacro, state);
90
+ index = end + 2;
91
+ }
92
+ return result;
93
+ }
94
+ function findMacroEnd(text, start) {
95
+ let depth = 1;
96
+ for (let index = start; index < text.length - 1; index++) {
97
+ const pair = text.slice(index, index + 2);
98
+ if (pair === "{{") {
99
+ depth++;
100
+ index++;
101
+ continue;
102
+ }
103
+ if (pair === "}}") {
104
+ depth--;
105
+ if (depth === 0)
106
+ return index;
107
+ index++;
108
+ }
109
+ }
110
+ return undefined;
111
+ }
112
+ function renderMacro(rawExpression, fullMacro, state) {
113
+ const expression = rawExpression.trim();
114
+ if (!expression)
115
+ return fullMacro;
116
+ const parts = splitMacroExpression(expression);
117
+ const command = parts[0]?.trim();
118
+ if (!command)
119
+ return fullMacro;
120
+ const rawArgs = parts.slice(1);
121
+ const definition = MACROS.get(command);
122
+ if (definition) {
123
+ let value;
124
+ try {
125
+ value = definition.render(createMacroRenderContext(command, rawArgs, state));
126
+ }
127
+ catch (error) {
128
+ const detail = error instanceof Error ? error.message : String(error);
129
+ state.diagnostics.push({
130
+ level: "error",
131
+ message: `Macro {{${command}}} failed: ${detail}`,
132
+ itemId: state.itemId,
133
+ });
134
+ return fullMacro;
135
+ }
136
+ if (value !== undefined)
137
+ return value;
138
+ state.unknown.add(expression);
139
+ return fullMacro;
140
+ }
141
+ const variableValue = getRuntimeVariable(state.runtime, state.stack, command);
142
+ if (variableValue !== undefined)
143
+ return variableValueToMacroText(variableValue);
144
+ state.unknown.add(expression);
145
+ return fullMacro;
146
+ }
147
+ function splitMacroExpression(expression) {
148
+ const parts = [];
149
+ let start = 0;
150
+ let depth = 0;
151
+ for (let index = 0; index < expression.length - 1; index++) {
152
+ const pair = expression.slice(index, index + 2);
153
+ if (pair === "{{") {
154
+ depth++;
155
+ index++;
156
+ continue;
157
+ }
158
+ if (pair === "}}" && depth > 0) {
159
+ depth--;
160
+ index++;
161
+ continue;
162
+ }
163
+ if (pair === "::" && depth === 0) {
164
+ parts.push(expression.slice(start, index));
165
+ start = index + 2;
166
+ index++;
167
+ }
168
+ }
169
+ parts.push(expression.slice(start));
170
+ return parts;
171
+ }
172
+ function createMacroRenderContext(command, rawArgs, state) {
173
+ const expandedArgs = new Map();
174
+ const expandArg = (index) => {
175
+ if (!expandedArgs.has(index)) {
176
+ expandedArgs.set(index, expandMacroText(rawArgs[index] ?? "", state));
177
+ }
178
+ return expandedArgs.get(index) ?? "";
179
+ };
180
+ return {
181
+ name: command,
182
+ command,
183
+ stack: state.stack,
184
+ runtime: state.runtime,
185
+ rawArgs,
186
+ expandArg,
187
+ expandJoinedArgs: (startIndex) => rawArgs.slice(startIndex).map((_, offset) => expandArg(startIndex + offset)).join("::"),
188
+ helpers: promptRenderHelpers,
189
+ variables: createVariableAccess(state.runtime, state.stack),
190
+ };
191
+ }
192
+ function renderSetVariable(context) {
193
+ const scoped = context.command === "setvar" && isVariableScope(context.expandArg(0).trim());
194
+ const scope = context.command === "setsessionvar" || (scoped && context.expandArg(0).trim() === "session")
195
+ ? "session"
196
+ : "turn";
197
+ const nameIndex = scoped ? 1 : 0;
198
+ const valueIndex = nameIndex + 1;
199
+ const name = context.expandArg(nameIndex).trim();
200
+ if (!name)
201
+ return undefined;
202
+ context.variables.set(scope, name, context.expandJoinedArgs(valueIndex));
203
+ return "";
204
+ }
205
+ function renderGetVariable(context) {
206
+ const name = context.expandArg(0).trim();
207
+ if (!name)
208
+ return undefined;
209
+ if (context.command === "getturnvar")
210
+ return context.variables.toMacroText(context.variables.get(name, "turn"));
211
+ if (context.command === "getsessionvar")
212
+ return context.variables.toMacroText(context.variables.get(name, "session"));
213
+ return context.variables.toMacroText(context.variables.get(name));
214
+ }
215
+ function renderClearVariable(context) {
216
+ const scoped = context.command === "clearvar" && isVariableScope(context.expandArg(0).trim());
217
+ const scope = context.command === "clearsessionvar" || (scoped && context.expandArg(0).trim() === "session")
218
+ ? "session"
219
+ : "turn";
220
+ const name = context.expandArg(scoped ? 1 : 0).trim();
221
+ if (!name)
222
+ return undefined;
223
+ context.variables.clear(scope, name);
224
+ return "";
225
+ }
226
+ function renderSelectedTools({ stack, runtime }) {
227
+ return selectedToolNames(stack, runtime).join(", ");
228
+ }
229
+ function renderIfVariable(context) {
230
+ const name = context.expandArg(0).trim();
231
+ if (!name)
232
+ return undefined;
233
+ return renderConditionalBranch(context, context.variables.get(name) !== undefined, 1, 2);
234
+ }
235
+ function renderIfVariableEquals(context) {
236
+ const name = context.expandArg(0).trim();
237
+ if (!name || context.rawArgs.length < 2)
238
+ return undefined;
239
+ const value = context.variables.get(name);
240
+ const expected = context.expandArg(1);
241
+ return renderConditionalBranch(context, value !== undefined && variableValueToMacroText(value) === expected, 2, 3);
242
+ }
243
+ function renderIfTool(context) {
244
+ const name = context.expandArg(0).trim();
245
+ if (!name)
246
+ return undefined;
247
+ return renderConditionalBranch(context, selectedToolNames(context.stack, context.runtime).includes(name), 1, 2);
248
+ }
249
+ function renderIfSlot(context) {
250
+ const name = context.expandArg(0).trim();
251
+ if (!name)
252
+ return undefined;
253
+ const hasSlot = context.stack.items.some((item) => item.enabled !== false && item.kind === "slot" && item.slot === name);
254
+ return renderConditionalBranch(context, hasSlot, 1, 2);
255
+ }
256
+ function renderConditionalBranch(context, condition, thenIndex, elseIndex) {
257
+ return condition ? context.expandArg(thenIndex) : context.expandArg(elseIndex);
258
+ }
259
+ function isVariableScope(value) {
260
+ return value === "turn" || value === "session";
261
+ }
262
+ //# sourceMappingURL=macro-engine.js.map