@zihanw/pi-forge 0.3.0 → 0.3.2

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 (156) hide show
  1. package/README.md +87 -2
  2. package/README.zh-CN.md +72 -2
  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/forge-extensions.d.ts +28 -0
  12. package/dist/forge-extensions.d.ts.map +1 -0
  13. package/dist/forge-extensions.js +182 -0
  14. package/dist/forge-extensions.js.map +1 -0
  15. package/dist/index.d.ts +8 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +376 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/lifecycle.d.ts +14 -0
  20. package/dist/lifecycle.d.ts.map +1 -0
  21. package/dist/lifecycle.js +139 -0
  22. package/dist/lifecycle.js.map +1 -0
  23. package/dist/loader.d.ts +8 -0
  24. package/dist/loader.d.ts.map +1 -0
  25. package/dist/loader.js +345 -0
  26. package/dist/loader.js.map +1 -0
  27. package/dist/macro-engine.d.ts +23 -0
  28. package/dist/macro-engine.d.ts.map +1 -0
  29. package/dist/macro-engine.js +262 -0
  30. package/dist/macro-engine.js.map +1 -0
  31. package/dist/payload-capture.d.ts +15 -0
  32. package/dist/payload-capture.d.ts.map +1 -0
  33. package/dist/payload-capture.js +86 -0
  34. package/dist/payload-capture.js.map +1 -0
  35. package/dist/payload-command.d.ts +10 -0
  36. package/dist/payload-command.d.ts.map +1 -0
  37. package/dist/payload-command.js +112 -0
  38. package/dist/payload-command.js.map +1 -0
  39. package/dist/policy.d.ts +6 -0
  40. package/dist/policy.d.ts.map +1 -0
  41. package/dist/policy.js +38 -0
  42. package/dist/policy.js.map +1 -0
  43. package/dist/preset-command.d.ts +14 -0
  44. package/dist/preset-command.d.ts.map +1 -0
  45. package/dist/preset-command.js +232 -0
  46. package/dist/preset-command.js.map +1 -0
  47. package/dist/preview.d.ts +12 -0
  48. package/dist/preview.d.ts.map +1 -0
  49. package/dist/preview.js +179 -0
  50. package/dist/preview.js.map +1 -0
  51. package/dist/regex.d.ts +7 -0
  52. package/dist/regex.d.ts.map +1 -0
  53. package/dist/regex.js +432 -0
  54. package/dist/regex.js.map +1 -0
  55. package/dist/render-helpers.d.ts +44 -0
  56. package/dist/render-helpers.d.ts.map +1 -0
  57. package/dist/render-helpers.js +128 -0
  58. package/dist/render-helpers.js.map +1 -0
  59. package/dist/runtime-state.d.ts +26 -0
  60. package/dist/runtime-state.d.ts.map +1 -0
  61. package/dist/runtime-state.js +15 -0
  62. package/dist/runtime-state.js.map +1 -0
  63. package/dist/sillytavern-importer/items.d.ts +3 -0
  64. package/dist/sillytavern-importer/items.d.ts.map +1 -0
  65. package/dist/sillytavern-importer/items.js +88 -0
  66. package/dist/sillytavern-importer/items.js.map +1 -0
  67. package/dist/sillytavern-importer/macros.d.ts +15 -0
  68. package/dist/sillytavern-importer/macros.d.ts.map +1 -0
  69. package/dist/sillytavern-importer/macros.js +141 -0
  70. package/dist/sillytavern-importer/macros.js.map +1 -0
  71. package/dist/sillytavern-importer/prompt-order.d.ts +6 -0
  72. package/dist/sillytavern-importer/prompt-order.d.ts.map +1 -0
  73. package/dist/sillytavern-importer/prompt-order.js +38 -0
  74. package/dist/sillytavern-importer/prompt-order.js.map +1 -0
  75. package/dist/sillytavern-importer/regex.d.ts +3 -0
  76. package/dist/sillytavern-importer/regex.d.ts.map +1 -0
  77. package/dist/sillytavern-importer/regex.js +275 -0
  78. package/dist/sillytavern-importer/regex.js.map +1 -0
  79. package/dist/sillytavern-importer/report.d.ts +21 -0
  80. package/dist/sillytavern-importer/report.d.ts.map +1 -0
  81. package/dist/sillytavern-importer/report.js +166 -0
  82. package/dist/sillytavern-importer/report.js.map +1 -0
  83. package/dist/sillytavern-importer/types.d.ts +106 -0
  84. package/dist/sillytavern-importer/types.d.ts.map +1 -0
  85. package/dist/sillytavern-importer/types.js +2 -0
  86. package/dist/sillytavern-importer/types.js.map +1 -0
  87. package/dist/sillytavern-importer.d.ts +5 -0
  88. package/dist/sillytavern-importer.d.ts.map +1 -0
  89. package/dist/sillytavern-importer.js +117 -0
  90. package/dist/sillytavern-importer.js.map +1 -0
  91. package/dist/slot-renderers.d.ts +25 -0
  92. package/dist/slot-renderers.d.ts.map +1 -0
  93. package/dist/slot-renderers.js +334 -0
  94. package/dist/slot-renderers.js.map +1 -0
  95. package/dist/stack-migration.d.ts +29 -0
  96. package/dist/stack-migration.d.ts.map +1 -0
  97. package/dist/stack-migration.js +126 -0
  98. package/dist/stack-migration.js.map +1 -0
  99. package/dist/storage.d.ts +10 -0
  100. package/dist/storage.d.ts.map +1 -0
  101. package/dist/storage.js +36 -0
  102. package/dist/storage.js.map +1 -0
  103. package/dist/types.d.ts +173 -0
  104. package/dist/types.d.ts.map +1 -0
  105. package/dist/types.js +2 -0
  106. package/dist/types.js.map +1 -0
  107. package/dist/web-editor/index.d.ts +3 -0
  108. package/dist/web-editor/index.d.ts.map +1 -0
  109. package/dist/web-editor/index.js +2 -0
  110. package/dist/web-editor/index.js.map +1 -0
  111. package/dist/web-editor/page.d.ts +2 -0
  112. package/dist/web-editor/page.d.ts.map +1 -0
  113. package/dist/web-editor/page.js +3331 -0
  114. package/dist/web-editor/page.js.map +1 -0
  115. package/dist/web-editor/server.d.ts +4 -0
  116. package/dist/web-editor/server.d.ts.map +1 -0
  117. package/dist/web-editor/server.js +263 -0
  118. package/dist/web-editor/server.js.map +1 -0
  119. package/dist/web-editor/types.d.ts +125 -0
  120. package/dist/web-editor/types.d.ts.map +1 -0
  121. package/dist/web-editor/types.js +2 -0
  122. package/dist/web-editor/types.js.map +1 -0
  123. package/dist/web-host.d.ts +29 -0
  124. package/dist/web-host.d.ts.map +1 -0
  125. package/dist/web-host.js +174 -0
  126. package/dist/web-host.js.map +1 -0
  127. package/examples/custom-system-status-extension/README.md +85 -0
  128. package/examples/custom-system-status-extension/index.ts +136 -0
  129. package/examples/custom-system-status-extension/prompt-stack.json +39 -0
  130. package/examples/image-reader-prompt-stack.json +124 -0
  131. package/package.json +28 -2
  132. package/src/compiler.ts +2 -472
  133. package/src/extension-registry.ts +33 -0
  134. package/src/forge-extensions.ts +223 -0
  135. package/src/index.ts +208 -653
  136. package/src/lifecycle.ts +171 -0
  137. package/src/macro-engine.ts +358 -0
  138. package/src/payload-command.ts +138 -0
  139. package/src/preset-command.ts +280 -0
  140. package/src/preview.ts +226 -0
  141. package/src/render-helpers.ts +169 -0
  142. package/src/runtime-state.ts +40 -0
  143. package/src/sillytavern-importer/items.ts +98 -0
  144. package/src/sillytavern-importer/macros.ts +159 -0
  145. package/src/sillytavern-importer/prompt-order.ts +54 -0
  146. package/src/sillytavern-importer/regex.ts +270 -0
  147. package/src/sillytavern-importer/report.ts +202 -0
  148. package/src/sillytavern-importer/types.ts +120 -0
  149. package/src/sillytavern-importer.ts +55 -865
  150. package/src/slot-renderers.ts +414 -0
  151. package/src/storage.ts +17 -0
  152. package/src/types.ts +3 -14
  153. package/src/web-editor/page.ts +516 -30
  154. package/src/web-editor/server.ts +9 -4
  155. package/src/web-editor/types.ts +18 -4
  156. package/src/web-host.ts +16 -13
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page.js","sourceRoot":"","sources":["../../src/web-editor/page.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,gBAAgB;IAC/B,OAAO,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA+vGV,CAAC;AACT,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { WebEditorHost, WebEditorServer, WebEditorServerOptions } from "./types.ts";
2
+ export declare const DEFAULT_WEB_EDITOR_PORT = 0;
3
+ export declare function startWebEditorServer(host: WebEditorHost, options?: WebEditorServerOptions): Promise<WebEditorServer>;
4
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/web-editor/server.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAA4B,eAAe,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAGnH,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,eAAe,CAAC,CAqC9H"}
@@ -0,0 +1,263 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { createServer } from "node:http";
3
+ import { convertSillyTavernPreset } from "../sillytavern-importer.js";
4
+ import { renderEditorHtml } from "./page.js";
5
+ // Port 0 asks Node to bind any available localhost port.
6
+ export const DEFAULT_WEB_EDITOR_PORT = 0;
7
+ export async function startWebEditorServer(host, options = {}) {
8
+ let currentHost = host;
9
+ const token = randomBytes(24).toString("base64url");
10
+ const sockets = new Set();
11
+ const server = createServer((req, res) => {
12
+ void handleRequest(currentHost, token, req, res).catch((error) => {
13
+ sendJson(res, 500, { error: error instanceof Error ? error.message : String(error) });
14
+ });
15
+ });
16
+ server.on("connection", (socket) => {
17
+ sockets.add(socket);
18
+ socket.on("close", () => sockets.delete(socket));
19
+ });
20
+ await new Promise((resolve, reject) => {
21
+ server.once("error", reject);
22
+ server.listen(options.port ?? DEFAULT_WEB_EDITOR_PORT, "127.0.0.1", () => {
23
+ server.off("error", reject);
24
+ resolve();
25
+ });
26
+ });
27
+ const address = server.address();
28
+ if (!address || typeof address === "string") {
29
+ await closeServer(server, sockets);
30
+ throw new Error("Failed to start pi-forge editor server.");
31
+ }
32
+ const url = `http://127.0.0.1:${address.port}/?token=${encodeURIComponent(token)}`;
33
+ return {
34
+ url,
35
+ port: address.port,
36
+ updateHost: (nextHost) => {
37
+ currentHost = nextHost;
38
+ },
39
+ close: () => closeServer(server, sockets),
40
+ };
41
+ }
42
+ async function handleRequest(host, token, req, res) {
43
+ const url = new URL(req.url ?? "/", "http://127.0.0.1");
44
+ if (url.pathname === "/" && req.method === "GET") {
45
+ if (url.searchParams.get("token") !== token) {
46
+ sendText(res, 403, "Invalid pi-forge editor token.");
47
+ return;
48
+ }
49
+ sendHtml(res, renderEditorHtml());
50
+ return;
51
+ }
52
+ if (!url.pathname.startsWith("/api/")) {
53
+ sendText(res, 404, "Not found.");
54
+ return;
55
+ }
56
+ if (!hasValidToken(req, url, token)) {
57
+ sendJson(res, 403, { error: "Invalid pi-forge editor token." });
58
+ return;
59
+ }
60
+ const parts = url.pathname.split("/").filter(Boolean).map((part) => decodeURIComponent(part));
61
+ if (req.method === "GET" && parts[1] === "stacks" && parts.length === 2) {
62
+ sendJson(res, 200, { stacks: host.listStacks(), cwd: host.cwd });
63
+ return;
64
+ }
65
+ if (req.method === "GET" && parts[1] === "resources" && parts.length === 2) {
66
+ sendJson(res, 200, host.listResources());
67
+ return;
68
+ }
69
+ if (req.method === "POST" && parts[1] === "stacks" && parts.length === 2) {
70
+ const body = await readJsonBody(req);
71
+ const parsed = readStackPayload(body);
72
+ if (!parsed.ok) {
73
+ sendJson(res, 400, { error: parsed.error });
74
+ return;
75
+ }
76
+ const options = isPlainObject(body)
77
+ ? { activate: body.activate === true, overwrite: body.overwrite === true }
78
+ : {};
79
+ const result = await host.createStack(parsed.stack, options);
80
+ if (result.ok && parsed.importFormat) {
81
+ sendJson(res, 200, { ...result, importFormat: parsed.importFormat, importReport: parsed.importReport });
82
+ return;
83
+ }
84
+ sendOperation(res, result);
85
+ return;
86
+ }
87
+ if (req.method === "GET" && parts[1] === "stacks" && parts.length === 3) {
88
+ const loaded = host.getStack(parts[2]);
89
+ if (!loaded) {
90
+ sendJson(res, 404, { error: `Unknown prompt stack: ${parts[2]}` });
91
+ return;
92
+ }
93
+ sendJson(res, 200, loaded);
94
+ return;
95
+ }
96
+ if (req.method === "PUT" && parts[1] === "stacks" && parts.length === 3) {
97
+ const body = await readJsonBody(req);
98
+ const parsed = readStackPayload(body);
99
+ if (!parsed.ok) {
100
+ sendJson(res, 400, { error: parsed.error });
101
+ return;
102
+ }
103
+ sendOperation(res, await host.saveStack(parts[2], parsed.stack));
104
+ return;
105
+ }
106
+ if (req.method === "DELETE" && parts[1] === "stacks" && parts.length === 3) {
107
+ sendOperation(res, await host.deleteStack(parts[2]));
108
+ return;
109
+ }
110
+ if (req.method === "POST" && parts[1] === "stacks" && parts.length === 4 && parts[3] === "validate") {
111
+ const body = await readJsonBody(req);
112
+ const parsed = readStackPayload(body);
113
+ if (!parsed.ok) {
114
+ sendJson(res, 400, { error: parsed.error });
115
+ return;
116
+ }
117
+ sendJson(res, 200, { diagnostics: host.validateStack(parsed.stack) });
118
+ return;
119
+ }
120
+ if (req.method === "POST" && parts[1] === "stacks" && parts.length === 4 && parts[3] === "preview") {
121
+ const body = await readJsonBody(req);
122
+ const parsed = readStackPayload(body);
123
+ if (!parsed.ok) {
124
+ sendJson(res, 400, { error: parsed.error });
125
+ return;
126
+ }
127
+ sendOperation(res, host.previewStack(parts[2], parsed.stack));
128
+ return;
129
+ }
130
+ if (req.method === "GET" && parts[1] === "payload" && parts.length === 2) {
131
+ sendOperation(res, host.getPayload());
132
+ return;
133
+ }
134
+ if (req.method === "POST" && parts[1] === "payload" && parts.length === 3 && parts[2] === "arm") {
135
+ const body = await readJsonBody(req);
136
+ const savePath = isPlainObject(body) && typeof body.savePath === "string" && body.savePath.trim() ? body.savePath.trim() : undefined;
137
+ sendOperation(res, host.armPayload(savePath));
138
+ return;
139
+ }
140
+ if (req.method === "DELETE" && parts[1] === "payload" && parts.length === 2) {
141
+ sendOperation(res, host.clearPayload());
142
+ return;
143
+ }
144
+ if (req.method === "POST" && parts[1] === "stacks" && parts.length === 4 && parts[3] === "activate") {
145
+ sendOperation(res, host.activateStack(parts[2]));
146
+ return;
147
+ }
148
+ if (req.method === "POST" && parts[1] === "disable" && parts.length === 2) {
149
+ sendOperation(res, host.disableStacks());
150
+ return;
151
+ }
152
+ if (req.method === "POST" && parts[1] === "reload" && parts.length === 2) {
153
+ sendOperation(res, await host.reloadStacks());
154
+ return;
155
+ }
156
+ sendJson(res, 404, { error: "Unknown pi-forge editor API route." });
157
+ }
158
+ function hasValidToken(req, url, token) {
159
+ const header = req.headers["x-pi-forge-token"];
160
+ return header === token || url.searchParams.get("token") === token;
161
+ }
162
+ async function readJsonBody(req) {
163
+ const chunks = [];
164
+ let size = 0;
165
+ const maxBytes = 2_000_000;
166
+ for await (const chunk of req) {
167
+ const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
168
+ size += buffer.length;
169
+ if (size > maxBytes)
170
+ throw new Error("Request body is too large.");
171
+ chunks.push(buffer);
172
+ }
173
+ const text = Buffer.concat(chunks).toString("utf8");
174
+ return text.trim() ? JSON.parse(text) : {};
175
+ }
176
+ function readStackPayload(body) {
177
+ const rawStack = isPlainObject(body) && "stack" in body ? body.stack : body;
178
+ if (!isPlainObject(rawStack))
179
+ return { ok: false, error: "Stack payload must be a JSON object." };
180
+ if (isSillyTavernPresetPayload(rawStack)) {
181
+ const sourceName = isPlainObject(body) && typeof body.sourceName === "string" ? body.sourceName : undefined;
182
+ const characterId = readCharacterId(body);
183
+ const result = convertSillyTavernPreset(rawStack, { sourceName, characterId });
184
+ if ("error" in result)
185
+ return { ok: false, error: `SillyTavern import error: ${result.error}` };
186
+ return { ok: true, stack: result.stack, importFormat: "sillytavern", importReport: result.report };
187
+ }
188
+ if (typeof rawStack.id !== "string" || !rawStack.id.trim())
189
+ return { ok: false, error: "Stack id must be a non-empty string." };
190
+ if (!Array.isArray(rawStack.items))
191
+ return { ok: false, error: "Stack items must be an array." };
192
+ for (const [index, item] of rawStack.items.entries()) {
193
+ if (!isPlainObject(item))
194
+ return { ok: false, error: `Item ${index + 1} must be an object.` };
195
+ if (item.kind !== "block" && item.kind !== "slot")
196
+ return { ok: false, error: `Item ${index + 1} kind must be block or slot.` };
197
+ if (typeof item.id !== "string" || !item.id.trim())
198
+ return { ok: false, error: `Item ${index + 1} id must be a non-empty string.` };
199
+ if (item.kind === "block" && typeof item.content !== "string")
200
+ return { ok: false, error: `Block item ${item.id} content must be a string.` };
201
+ if (item.kind === "slot" && typeof item.slot !== "string")
202
+ return { ok: false, error: `Slot item ${item.id} slot must be a string.` };
203
+ }
204
+ return { ok: true, stack: rawStack };
205
+ }
206
+ function isSillyTavernPresetPayload(value) {
207
+ return Array.isArray(value.prompts) && !Array.isArray(value.items);
208
+ }
209
+ function readCharacterId(body) {
210
+ if (!isPlainObject(body))
211
+ return undefined;
212
+ const raw = body.characterId;
213
+ if (typeof raw === "number" && Number.isInteger(raw))
214
+ return raw;
215
+ if (typeof raw === "string" && raw.trim()) {
216
+ const parsed = Number(raw.trim());
217
+ if (Number.isInteger(parsed))
218
+ return parsed;
219
+ }
220
+ return undefined;
221
+ }
222
+ function sendOperation(res, result) {
223
+ if (!result.ok) {
224
+ sendJson(res, result.status ?? 400, { error: result.error });
225
+ return;
226
+ }
227
+ sendJson(res, 200, result);
228
+ }
229
+ function sendHtml(res, html) {
230
+ res.writeHead(200, {
231
+ "content-type": "text/html; charset=utf-8",
232
+ "cache-control": "no-store",
233
+ "connection": "close",
234
+ });
235
+ res.end(html);
236
+ }
237
+ function sendText(res, status, text) {
238
+ res.writeHead(status, {
239
+ "content-type": "text/plain; charset=utf-8",
240
+ "cache-control": "no-store",
241
+ "connection": "close",
242
+ });
243
+ res.end(text);
244
+ }
245
+ function sendJson(res, status, value) {
246
+ res.writeHead(status, {
247
+ "content-type": "application/json; charset=utf-8",
248
+ "cache-control": "no-store",
249
+ "connection": "close",
250
+ });
251
+ res.end(JSON.stringify(value));
252
+ }
253
+ function closeServer(server, sockets) {
254
+ return new Promise((resolve, reject) => {
255
+ server.close((error) => error ? reject(error) : resolve());
256
+ for (const socket of sockets)
257
+ socket.destroy();
258
+ });
259
+ }
260
+ function isPlainObject(value) {
261
+ return !!value && typeof value === "object" && !Array.isArray(value);
262
+ }
263
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/web-editor/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,125 @@
1
+ import type { PromptStack, PromptStackDiagnostic } from "../types.ts";
2
+ export interface WebEditorStackSummary {
3
+ id: string;
4
+ name?: string;
5
+ filePath: string;
6
+ active: boolean;
7
+ autoActivate?: boolean;
8
+ mode?: string;
9
+ itemCount: number;
10
+ errors: number;
11
+ warnings: number;
12
+ diagnostics: PromptStackDiagnostic[];
13
+ }
14
+ export interface WebEditorHost {
15
+ cwd: string;
16
+ listStacks(): WebEditorStackSummary[];
17
+ listResources(): WebEditorPolicyResources;
18
+ getStack(id: string): {
19
+ stack: PromptStack;
20
+ filePath: string;
21
+ diagnostics: PromptStackDiagnostic[];
22
+ } | undefined;
23
+ createStack(stack: PromptStack, options: WebEditorCreateStackOptions): Promise<WebEditorOperationResult<{
24
+ stack: WebEditorStackSummary;
25
+ stacks: WebEditorStackSummary[];
26
+ }>>;
27
+ saveStack(id: string, stack: PromptStack): Promise<WebEditorOperationResult<{
28
+ stack: WebEditorStackSummary;
29
+ stacks: WebEditorStackSummary[];
30
+ }>>;
31
+ deleteStack(id: string): Promise<WebEditorOperationResult<{
32
+ activeId?: string;
33
+ stacks: WebEditorStackSummary[];
34
+ }>>;
35
+ validateStack(stack: PromptStack): PromptStackDiagnostic[];
36
+ previewStack(id: string, stack: PromptStack): WebEditorOperationResult<{
37
+ text: string;
38
+ preview?: WebEditorPreview;
39
+ diagnostics: PromptStackDiagnostic[];
40
+ }>;
41
+ getPayload(): WebEditorOperationResult<WebEditorPayloadSnapshot>;
42
+ armPayload(savePath?: string): WebEditorOperationResult<WebEditorPayloadSnapshot>;
43
+ clearPayload(): WebEditorOperationResult<WebEditorPayloadSnapshot>;
44
+ activateStack(id: string): WebEditorOperationResult<{
45
+ activeId?: string;
46
+ stacks: WebEditorStackSummary[];
47
+ }>;
48
+ disableStacks(): WebEditorOperationResult<{
49
+ activeId?: string;
50
+ stacks: WebEditorStackSummary[];
51
+ }>;
52
+ reloadStacks(): Promise<WebEditorOperationResult<{
53
+ activeId?: string;
54
+ stacks: WebEditorStackSummary[];
55
+ }>>;
56
+ }
57
+ export interface WebEditorPreviewSection {
58
+ id: string;
59
+ title: string;
60
+ role?: string;
61
+ content: string;
62
+ chars: number;
63
+ approxTokens: number;
64
+ }
65
+ export interface WebEditorPreview {
66
+ stackId: string;
67
+ generatedAt: string;
68
+ system: WebEditorPreviewSection;
69
+ messages: WebEditorPreviewSection[];
70
+ totalChars: number;
71
+ approxTokens: number;
72
+ }
73
+ export interface WebEditorPayloadCapture {
74
+ capturedAt: string;
75
+ stackId?: string;
76
+ savePath?: string;
77
+ payload?: unknown;
78
+ text: string;
79
+ chars: number;
80
+ approxTokens: number;
81
+ truncated: boolean;
82
+ error?: string;
83
+ }
84
+ export type WebEditorPayloadSnapshot = {
85
+ status: "idle";
86
+ } | {
87
+ status: "armed";
88
+ armedAt?: string;
89
+ savePath?: string;
90
+ } | {
91
+ status: "captured";
92
+ capture: WebEditorPayloadCapture;
93
+ };
94
+ export interface WebEditorCreateStackOptions {
95
+ activate?: boolean;
96
+ overwrite?: boolean;
97
+ }
98
+ export interface WebEditorPolicyResource {
99
+ name: string;
100
+ description?: string;
101
+ source?: string;
102
+ active?: boolean;
103
+ hidden?: boolean;
104
+ }
105
+ export interface WebEditorPolicyResources {
106
+ tools: WebEditorPolicyResource[];
107
+ skills: WebEditorPolicyResource[];
108
+ }
109
+ export type WebEditorOperationResult<T> = ({
110
+ ok: true;
111
+ } & T) | {
112
+ ok: false;
113
+ status?: number;
114
+ error: string;
115
+ };
116
+ export interface WebEditorServer {
117
+ url: string;
118
+ port: number;
119
+ updateHost(host: WebEditorHost): void;
120
+ close(): Promise<void>;
121
+ }
122
+ export interface WebEditorServerOptions {
123
+ port?: number;
124
+ }
125
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/web-editor/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/web-editor/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,29 @@
1
+ import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
2
+ import type { LoadedPromptStack, PromptStackDiagnostic } from "./types.ts";
3
+ import type { WebEditorHost, WebEditorOperationResult, WebEditorPayloadSnapshot, WebEditorPolicyResources, WebEditorPreview, WebEditorStackSummary } from "./web-editor/index.ts";
4
+ export interface WebHostRuntime {
5
+ getStacks(): LoadedPromptStack[];
6
+ getActive(): LoadedPromptStack | undefined;
7
+ getActiveId(): string | undefined;
8
+ getSelectedActiveId(): string | undefined;
9
+ setActive(id: string | undefined): boolean;
10
+ reloadStacks(preferredId?: string): Promise<void>;
11
+ buildPreview(target: LoadedPromptStack): {
12
+ text: string;
13
+ preview: WebEditorPreview;
14
+ diagnostics: PromptStackDiagnostic[];
15
+ };
16
+ getPolicyResources(): WebEditorPolicyResources;
17
+ getPayload(): WebEditorOperationResult<WebEditorPayloadSnapshot>;
18
+ armPayload(savePath?: string): WebEditorOperationResult<WebEditorPayloadSnapshot>;
19
+ clearPayload(): WebEditorOperationResult<WebEditorPayloadSnapshot>;
20
+ }
21
+ export declare function createWebEditorHost(ctx: ExtensionCommandContext, runtime: WebHostRuntime): WebEditorHost;
22
+ export declare function stackSummary(loaded: LoadedPromptStack, active: LoadedPromptStack | undefined): WebEditorStackSummary;
23
+ export declare function stackSummaries(stacks: LoadedPromptStack[], active: LoadedPromptStack | undefined): WebEditorStackSummary[];
24
+ export declare function loadWebEditorSettings(ctx: ExtensionCommandContext): {
25
+ preferredPort?: number;
26
+ configPath: string;
27
+ warnings: string[];
28
+ };
29
+ //# sourceMappingURL=web-host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-host.d.ts","sourceRoot":"","sources":["../src/web-host.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAM/E,OAAO,KAAK,EAAE,iBAAiB,EAAe,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACxF,OAAO,KAAK,EAEX,aAAa,EACb,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,gBAAgB,EAChB,qBAAqB,EACrB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,WAAW,cAAc;IAC9B,SAAS,IAAI,iBAAiB,EAAE,CAAC;IACjC,SAAS,IAAI,iBAAiB,GAAG,SAAS,CAAC;IAC3C,WAAW,IAAI,MAAM,GAAG,SAAS,CAAC;IAClC,mBAAmB,IAAI,MAAM,GAAG,SAAS,CAAC;IAC1C,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IAC3C,YAAY,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,YAAY,CAAC,MAAM,EAAE,iBAAiB,GAAG;QACxC,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,gBAAgB,CAAC;QAC1B,WAAW,EAAE,qBAAqB,EAAE,CAAC;KACrC,CAAC;IACF,kBAAkB,IAAI,wBAAwB,CAAC;IAC/C,UAAU,IAAI,wBAAwB,CAAC,wBAAwB,CAAC,CAAC;IACjE,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,wBAAwB,CAAC,wBAAwB,CAAC,CAAC;IAClF,YAAY,IAAI,wBAAwB,CAAC,wBAAwB,CAAC,CAAC;CACnE;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,uBAAuB,EAAE,OAAO,EAAE,cAAc,GAAG,aAAa,CAoCxG;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,iBAAiB,GAAG,SAAS,GAAG,qBAAqB,CAepH;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,iBAAiB,EAAE,EAAE,MAAM,EAAE,iBAAiB,GAAG,SAAS,GAAG,qBAAqB,EAAE,CAE1H;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,uBAAuB,GAAG;IAAE,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAmCtI"}
@@ -0,0 +1,174 @@
1
+ import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { isInsidePromptStackStorage, promptStackPath, validatePromptStack, } from "./loader.js";
4
+ export function createWebEditorHost(ctx, runtime) {
5
+ return {
6
+ cwd: ctx.cwd,
7
+ listStacks: () => stackSummaries(runtime.getStacks(), runtime.getActive()),
8
+ listResources: () => runtime.getPolicyResources(),
9
+ getStack: (id) => {
10
+ const loaded = runtime.getStacks().find((candidate) => candidate.stack.id === id);
11
+ return loaded ? { stack: loaded.stack, filePath: loaded.filePath, diagnostics: loaded.diagnostics } : undefined;
12
+ },
13
+ createStack: (stack, options) => createStackFile(ctx, runtime, stack, options),
14
+ saveStack: (id, stack) => saveStackFile(ctx, runtime, id, stack),
15
+ deleteStack: (id) => deleteStackFile(ctx, runtime, id),
16
+ validateStack: (stack) => validatePromptStack(stack),
17
+ previewStack: (id, stack) => {
18
+ const target = runtime.getStacks().find((candidate) => candidate.stack.id === id);
19
+ if (!target)
20
+ return { ok: false, status: 404, error: `Unknown prompt stack: ${id}` };
21
+ const diagnostics = validatePromptStack(stack);
22
+ const preview = runtime.buildPreview({ stack, filePath: target.filePath, diagnostics });
23
+ return { ok: true, text: preview.text, preview: preview.preview, diagnostics: preview.diagnostics };
24
+ },
25
+ getPayload: () => runtime.getPayload(),
26
+ armPayload: (savePath) => runtime.armPayload(savePath),
27
+ clearPayload: () => runtime.clearPayload(),
28
+ activateStack: (id) => {
29
+ if (!runtime.setActive(id))
30
+ return { ok: false, status: 404, error: `Unknown prompt stack: ${id}` };
31
+ return { ok: true, activeId: runtime.getActiveId(), stacks: stackSummaries(runtime.getStacks(), runtime.getActive()) };
32
+ },
33
+ disableStacks: () => {
34
+ runtime.setActive("none");
35
+ return { ok: true, activeId: runtime.getActiveId(), stacks: stackSummaries(runtime.getStacks(), runtime.getActive()) };
36
+ },
37
+ reloadStacks: async () => {
38
+ await runtime.reloadStacks(runtime.getSelectedActiveId());
39
+ return { ok: true, activeId: runtime.getActiveId(), stacks: stackSummaries(runtime.getStacks(), runtime.getActive()) };
40
+ },
41
+ };
42
+ }
43
+ export function stackSummary(loaded, active) {
44
+ const errors = loaded.diagnostics.filter((d) => d.level === "error").length;
45
+ const warnings = loaded.diagnostics.filter((d) => d.level === "warning").length;
46
+ return {
47
+ id: loaded.stack.id,
48
+ name: loaded.stack.name,
49
+ filePath: loaded.filePath,
50
+ active: loaded === active,
51
+ autoActivate: loaded.stack.autoActivate,
52
+ mode: loaded.stack.mode ?? "replace",
53
+ itemCount: loaded.stack.items.length,
54
+ errors,
55
+ warnings,
56
+ diagnostics: loaded.diagnostics,
57
+ };
58
+ }
59
+ export function stackSummaries(stacks, active) {
60
+ return stacks.map((loaded) => stackSummary(loaded, active));
61
+ }
62
+ export function loadWebEditorSettings(ctx) {
63
+ const configPath = join(ctx.cwd, ".pi", "forge", "config.json");
64
+ if (!ctx.isProjectTrusted() || !existsSync(configPath)) {
65
+ return { configPath, warnings: [] };
66
+ }
67
+ let raw;
68
+ try {
69
+ raw = JSON.parse(readFileSync(configPath, "utf8"));
70
+ }
71
+ catch (error) {
72
+ return {
73
+ configPath,
74
+ warnings: [`pi-forge: failed to read ${configPath}; using an available editor port. ${error instanceof Error ? error.message : String(error)}`],
75
+ };
76
+ }
77
+ if (!isPlainObject(raw)) {
78
+ return {
79
+ configPath,
80
+ warnings: [`pi-forge: ${configPath} must be a JSON object; using an available editor port.`],
81
+ };
82
+ }
83
+ const webEditorConfig = isPlainObject(raw.webEditor) ? raw.webEditor : undefined;
84
+ const rawPort = webEditorConfig?.port ?? raw.webEditorPort;
85
+ if (rawPort === undefined)
86
+ return { configPath, warnings: [] };
87
+ if (typeof rawPort === "number" && Number.isInteger(rawPort) && rawPort >= 1 && rawPort <= 65535) {
88
+ return { preferredPort: rawPort, configPath, warnings: [] };
89
+ }
90
+ return {
91
+ configPath,
92
+ warnings: [`pi-forge: ${configPath} webEditor.port must be an integer from 1 to 65535; using an available editor port.`],
93
+ };
94
+ }
95
+ async function saveStackFile(ctx, runtime, id, stack) {
96
+ if (!ctx.isProjectTrusted()) {
97
+ return { ok: false, status: 403, error: "Project is not trusted; refusing to save prompt stacks." };
98
+ }
99
+ const target = runtime.getStacks().find((candidate) => candidate.stack.id === id);
100
+ if (!target)
101
+ return { ok: false, status: 404, error: `Unknown prompt stack: ${id}` };
102
+ if (!isInsidePromptStackStorage(ctx.cwd, target.filePath)) {
103
+ return { ok: false, status: 403, error: "Refusing to save outside prompt-stack storage." };
104
+ }
105
+ writeFileSync(target.filePath, `${JSON.stringify(stack, null, 2)}\n`, "utf8");
106
+ const preferredId = runtime.getActive()?.stack.id === id ? stack.id : runtime.getSelectedActiveId();
107
+ await runtime.reloadStacks(preferredId);
108
+ const saved = runtime.getStacks().find((candidate) => candidate.stack.id === stack.id) ?? runtime.getStacks().find((candidate) => candidate.filePath === target.filePath);
109
+ if (!saved)
110
+ return { ok: false, status: 500, error: "Saved stack could not be reloaded." };
111
+ return { ok: true, stack: stackSummary(saved, runtime.getActive()), stacks: stackSummaries(runtime.getStacks(), runtime.getActive()) };
112
+ }
113
+ async function createStackFile(ctx, runtime, stack, options) {
114
+ if (!ctx.isProjectTrusted()) {
115
+ return { ok: false, status: 403, error: "Project is not trusted; refusing to create prompt stacks." };
116
+ }
117
+ const idError = validateWebStackId(stack.id);
118
+ if (idError)
119
+ return { ok: false, status: 400, error: idError };
120
+ const existingById = runtime.getStacks().find((candidate) => candidate.stack.id === stack.id);
121
+ if (existingById && !options.overwrite) {
122
+ return { ok: false, status: 409, error: `Prompt stack already exists: ${stack.id}` };
123
+ }
124
+ const targetPath = existingById && options.overwrite ? existingById.filePath : promptStackPath(ctx.cwd, stack.id);
125
+ if (!isInsidePromptStackStorage(ctx.cwd, targetPath)) {
126
+ return { ok: false, status: 403, error: "Refusing to create outside prompt-stack storage." };
127
+ }
128
+ if (!existingById && existsSync(targetPath) && !options.overwrite) {
129
+ return { ok: false, status: 409, error: `Prompt stack already exists: ${stack.id}` };
130
+ }
131
+ const previousSelection = runtime.getSelectedActiveId();
132
+ mkdirSync(dirname(targetPath), { recursive: true });
133
+ writeFileSync(targetPath, `${JSON.stringify(stack, null, 2)}\n`, "utf8");
134
+ await runtime.reloadStacks(options.activate ? stack.id : (previousSelection ?? "none"));
135
+ if (options.activate)
136
+ runtime.setActive(stack.id);
137
+ const created = runtime.getStacks().find((candidate) => candidate.stack.id === stack.id);
138
+ if (!created)
139
+ return { ok: false, status: 500, error: "Created stack could not be reloaded." };
140
+ return { ok: true, stack: stackSummary(created, runtime.getActive()), stacks: stackSummaries(runtime.getStacks(), runtime.getActive()) };
141
+ }
142
+ async function deleteStackFile(ctx, runtime, id) {
143
+ if (!ctx.isProjectTrusted()) {
144
+ return { ok: false, status: 403, error: "Project is not trusted; refusing to delete prompt stacks." };
145
+ }
146
+ const target = runtime.getStacks().find((candidate) => candidate.stack.id === id);
147
+ if (!target)
148
+ return { ok: false, status: 404, error: `Unknown prompt stack: ${id}` };
149
+ if (!isInsidePromptStackStorage(ctx.cwd, target.filePath)) {
150
+ return { ok: false, status: 403, error: "Refusing to delete outside prompt-stack storage." };
151
+ }
152
+ const wasActive = runtime.getActive()?.stack.id === id;
153
+ unlinkSync(target.filePath);
154
+ if (wasActive) {
155
+ runtime.setActive("none");
156
+ await runtime.reloadStacks("none");
157
+ }
158
+ else {
159
+ await runtime.reloadStacks(runtime.getSelectedActiveId());
160
+ }
161
+ return { ok: true, activeId: runtime.getActiveId(), stacks: stackSummaries(runtime.getStacks(), runtime.getActive()) };
162
+ }
163
+ function validateWebStackId(id) {
164
+ if (!id.trim())
165
+ return "Stack id must not be empty.";
166
+ if (!/^[A-Za-z0-9_-]+$/.test(id)) {
167
+ return "Stack id may only contain letters, numbers, underscore, and dash.";
168
+ }
169
+ return undefined;
170
+ }
171
+ function isPlainObject(value) {
172
+ return !!value && typeof value === "object" && !Array.isArray(value);
173
+ }
174
+ //# sourceMappingURL=web-host.js.map