pi-forge 1.2.5 → 1.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 (64) hide show
  1. package/README.md +1 -1
  2. package/dist/client/assets/{CodeMirrorEditor-DXmxwE2Z.js → CodeMirrorEditor-DOSPzCPa.js} +13 -13
  3. package/dist/client/assets/CodeMirrorEditor-DOSPzCPa.js.map +1 -0
  4. package/dist/client/assets/index-CEqSkIuy.css +1 -0
  5. package/dist/client/assets/index-D8rNSBxI.js +375 -0
  6. package/dist/client/assets/index-D8rNSBxI.js.map +1 -0
  7. package/dist/client/assets/{workbox-window.prod.es5-Cch4wiA5.js → workbox-window.prod.es5-Bd17z0YL.js} +2 -2
  8. package/dist/client/assets/{workbox-window.prod.es5-Cch4wiA5.js.map → workbox-window.prod.es5-Bd17z0YL.js.map} +1 -1
  9. package/dist/client/index.html +2 -2
  10. package/dist/client/sw.js +1 -1
  11. package/dist/client/sw.js.map +1 -1
  12. package/dist/server/git-clone.js +364 -0
  13. package/dist/server/git-clone.js.map +1 -0
  14. package/dist/server/index.js +22 -0
  15. package/dist/server/index.js.map +1 -1
  16. package/dist/server/orchestration/config.js +61 -0
  17. package/dist/server/orchestration/config.js.map +1 -0
  18. package/dist/server/orchestration/event-bridge.js +93 -0
  19. package/dist/server/orchestration/event-bridge.js.map +1 -0
  20. package/dist/server/orchestration/inbox.js +199 -0
  21. package/dist/server/orchestration/inbox.js.map +1 -0
  22. package/dist/server/orchestration/init.js +39 -0
  23. package/dist/server/orchestration/init.js.map +1 -0
  24. package/dist/server/orchestration/store.js +352 -0
  25. package/dist/server/orchestration/store.js.map +1 -0
  26. package/dist/server/orchestration/tools.js +789 -0
  27. package/dist/server/orchestration/tools.js.map +1 -0
  28. package/dist/server/orchestration/types.js +57 -0
  29. package/dist/server/orchestration/types.js.map +1 -0
  30. package/dist/server/processes/manager.js +23 -1
  31. package/dist/server/processes/manager.js.map +1 -1
  32. package/dist/server/project-manager.js +46 -32
  33. package/dist/server/project-manager.js.map +1 -1
  34. package/dist/server/routes/control.js +9 -0
  35. package/dist/server/routes/control.js.map +1 -1
  36. package/dist/server/routes/health.js +14 -1
  37. package/dist/server/routes/health.js.map +1 -1
  38. package/dist/server/routes/orchestration.js +464 -0
  39. package/dist/server/routes/orchestration.js.map +1 -0
  40. package/dist/server/routes/projects.js +239 -14
  41. package/dist/server/routes/projects.js.map +1 -1
  42. package/dist/server/routes/sessions.js +53 -34
  43. package/dist/server/routes/sessions.js.map +1 -1
  44. package/dist/server/routes/webhooks.js +362 -0
  45. package/dist/server/routes/webhooks.js.map +1 -0
  46. package/dist/server/session-registry.js +317 -5
  47. package/dist/server/session-registry.js.map +1 -1
  48. package/dist/server/sse-bridge.js +85 -14
  49. package/dist/server/sse-bridge.js.map +1 -1
  50. package/dist/server/webhooks/dispatcher.js +254 -0
  51. package/dist/server/webhooks/dispatcher.js.map +1 -0
  52. package/dist/server/webhooks/event-bridge.js +185 -0
  53. package/dist/server/webhooks/event-bridge.js.map +1 -0
  54. package/dist/server/webhooks/init.js +55 -0
  55. package/dist/server/webhooks/init.js.map +1 -0
  56. package/dist/server/webhooks/store.js +394 -0
  57. package/dist/server/webhooks/store.js.map +1 -0
  58. package/dist/server/webhooks/types.js +32 -0
  59. package/dist/server/webhooks/types.js.map +1 -0
  60. package/package.json +4 -4
  61. package/dist/client/assets/CodeMirrorEditor-DXmxwE2Z.js.map +0 -1
  62. package/dist/client/assets/index-CMSjnWtF.js +0 -365
  63. package/dist/client/assets/index-CMSjnWtF.js.map +0 -1
  64. package/dist/client/assets/index-Cp8qEy7Q.css +0 -1
@@ -0,0 +1,362 @@
1
+ import { config } from "../config.js";
2
+ import { dispatch } from "../webhooks/dispatcher.js";
3
+ import { createWebhook, deleteWebhook, getWebhook, InvalidWebhookError, readDeliveriesForWebhook, readWebhooks, redactHeaders, updateWebhook, WebhookNotFoundError, } from "../webhooks/store.js";
4
+ import { isWebhookEvent, WEBHOOK_EVENTS } from "../webhooks/types.js";
5
+ import { errorSchema } from "./_schemas.js";
6
+ const webhookEventsEnum = WEBHOOK_EVENTS;
7
+ const scopeSchema = {
8
+ oneOf: [
9
+ {
10
+ type: "object",
11
+ required: ["kind"],
12
+ additionalProperties: false,
13
+ properties: { kind: { const: "global" } },
14
+ },
15
+ {
16
+ type: "object",
17
+ required: ["kind", "projectId"],
18
+ additionalProperties: false,
19
+ properties: { kind: { const: "project" }, projectId: { type: "string", minLength: 1 } },
20
+ },
21
+ ],
22
+ };
23
+ /**
24
+ * Webhook config returned by the API. Secret is intentionally
25
+ * REDACTED on the wire — the client doesn't need it, and
26
+ * accidentally surfacing it in a logged response body would be
27
+ * the kind of breach we wrote pi-forge to avoid. `hasSecret` is
28
+ * the boolean presence map equivalent (same pattern as
29
+ * `readAuthSummary` for provider keys).
30
+ */
31
+ const webhookSchema = {
32
+ type: "object",
33
+ required: ["id", "name", "url", "events", "scope", "enabled", "hasSecret", "createdAt"],
34
+ properties: {
35
+ id: { type: "string" },
36
+ name: { type: "string" },
37
+ url: { type: "string" },
38
+ events: { type: "array", items: { type: "string", enum: webhookEventsEnum } },
39
+ scope: scopeSchema,
40
+ enabled: { type: "boolean" },
41
+ hasSecret: { type: "boolean" },
42
+ headers: { type: "object", additionalProperties: { type: "string" } },
43
+ insecureTls: { type: "boolean" },
44
+ createdAt: { type: "string" },
45
+ },
46
+ };
47
+ const deliverySchema = {
48
+ type: "object",
49
+ required: [
50
+ "id",
51
+ "webhookId",
52
+ "deliveryId",
53
+ "event",
54
+ "attempt",
55
+ "status",
56
+ "durationMs",
57
+ "requestedAt",
58
+ ],
59
+ properties: {
60
+ id: { type: "string" },
61
+ webhookId: { type: "string" },
62
+ deliveryId: { type: "string" },
63
+ event: { type: "string" },
64
+ sessionId: { type: "string" },
65
+ projectId: { type: "string" },
66
+ attempt: { type: "integer" },
67
+ status: { type: "string", enum: ["delivered", "failed", "error"] },
68
+ statusCode: { type: "integer" },
69
+ durationMs: { type: "integer" },
70
+ errorPreview: { type: "string" },
71
+ requestedAt: { type: "string" },
72
+ },
73
+ };
74
+ function toWire(w) {
75
+ const out = {
76
+ id: w.id,
77
+ name: w.name,
78
+ url: w.url,
79
+ events: [...w.events],
80
+ scope: w.scope,
81
+ enabled: w.enabled,
82
+ hasSecret: w.secret !== undefined && w.secret.length > 0,
83
+ createdAt: w.createdAt,
84
+ };
85
+ // Header NAMES are returned so the UI can show "this webhook has
86
+ // an Authorization header configured." VALUES are redacted to
87
+ // the same `***REDACTED***` sentinel `config-manager.ts` uses
88
+ // for inline `apiKey` in models.json — the wire never carries
89
+ // the real header value, and an unchanged sentinel on the way
90
+ // back through PATCH means "keep the existing value" (see
91
+ // mergeHeadersOnWrite in store.ts).
92
+ const redacted = redactHeaders(w.headers);
93
+ if (redacted !== undefined)
94
+ out.headers = redacted;
95
+ if (w.insecureTls === true)
96
+ out.insecureTls = true;
97
+ return out;
98
+ }
99
+ function handleStoreError(reply, err) {
100
+ if (err instanceof InvalidWebhookError) {
101
+ return reply.code(400).send({ error: err.code, message: err.message });
102
+ }
103
+ if (err instanceof WebhookNotFoundError) {
104
+ return reply.code(404).send({ error: err.code, message: err.message });
105
+ }
106
+ reply.log.error({ err }, "webhooks route error");
107
+ return reply.code(500).send({ error: "internal_error" });
108
+ }
109
+ function minimalUiGate(reply) {
110
+ if (config.minimalUi) {
111
+ return reply.code(403).send({
112
+ error: "minimal_ui_disabled",
113
+ message: "Webhook configuration is disabled under MINIMAL_UI.",
114
+ });
115
+ }
116
+ return undefined;
117
+ }
118
+ export const webhookRoutes = async (fastify) => {
119
+ fastify.get("/webhooks", {
120
+ schema: {
121
+ description: "List configured webhooks. Optional `?projectId=` filter returns only " +
122
+ "global webhooks plus per-project webhooks scoped to that project (the " +
123
+ "set that would actually fire for that project's sessions). Without the " +
124
+ "filter, returns every webhook regardless of scope.",
125
+ tags: ["webhooks"],
126
+ querystring: {
127
+ type: "object",
128
+ properties: { projectId: { type: "string" } },
129
+ },
130
+ response: {
131
+ 200: {
132
+ type: "object",
133
+ required: ["webhooks"],
134
+ properties: { webhooks: { type: "array", items: webhookSchema } },
135
+ },
136
+ },
137
+ },
138
+ }, async (req) => {
139
+ const all = await readWebhooks();
140
+ const filtered = req.query.projectId === undefined
141
+ ? all
142
+ : all.filter((w) => w.scope.kind === "global" ||
143
+ (w.scope.kind === "project" && w.scope.projectId === req.query.projectId));
144
+ return { webhooks: filtered.map(toWire) };
145
+ });
146
+ fastify.post("/webhooks", {
147
+ schema: {
148
+ description: "Create a webhook. Validates HTTPS-only URL, non-empty event subscription, " +
149
+ "and known event types. The created webhook's secret is stored on disk in " +
150
+ "`webhooks.json` (mode 0600) and never returned on the wire.\n\n" +
151
+ "Disabled under MINIMAL_UI (403 `minimal_ui_disabled`).",
152
+ tags: ["webhooks"],
153
+ body: {
154
+ type: "object",
155
+ required: ["name", "url", "events", "scope"],
156
+ additionalProperties: false,
157
+ properties: {
158
+ name: { type: "string", minLength: 1, maxLength: 200 },
159
+ url: { type: "string", minLength: 1 },
160
+ events: {
161
+ type: "array",
162
+ minItems: 1,
163
+ items: { type: "string", enum: webhookEventsEnum },
164
+ },
165
+ scope: scopeSchema,
166
+ secret: { type: "string", maxLength: 256 },
167
+ headers: { type: "object", additionalProperties: { type: "string" } },
168
+ insecureTls: { type: "boolean" },
169
+ enabled: { type: "boolean" },
170
+ },
171
+ },
172
+ response: {
173
+ 201: webhookSchema,
174
+ 400: errorSchema,
175
+ 403: errorSchema,
176
+ },
177
+ },
178
+ }, async (req, reply) => {
179
+ const gate = minimalUiGate(reply);
180
+ if (gate !== undefined)
181
+ return gate;
182
+ try {
183
+ const w = await createWebhook({
184
+ name: req.body.name,
185
+ url: req.body.url,
186
+ events: req.body.events.filter(isWebhookEvent),
187
+ scope: req.body.scope,
188
+ ...(req.body.secret !== undefined ? { secret: req.body.secret } : {}),
189
+ ...(req.body.headers !== undefined ? { headers: req.body.headers } : {}),
190
+ ...(req.body.insecureTls !== undefined ? { insecureTls: req.body.insecureTls } : {}),
191
+ ...(req.body.enabled !== undefined ? { enabled: req.body.enabled } : {}),
192
+ });
193
+ return reply.code(201).send(toWire(w));
194
+ }
195
+ catch (err) {
196
+ return handleStoreError(reply, err);
197
+ }
198
+ });
199
+ fastify.patch("/webhooks/:id", {
200
+ schema: {
201
+ description: "Update a webhook. All fields are optional; omitted fields are left " +
202
+ "untouched. For `secret`/`headers`, an empty value clears the field; " +
203
+ "to leave them unchanged, omit them entirely.\n\nDisabled under MINIMAL_UI.",
204
+ tags: ["webhooks"],
205
+ params: {
206
+ type: "object",
207
+ required: ["id"],
208
+ properties: { id: { type: "string" } },
209
+ },
210
+ body: {
211
+ type: "object",
212
+ additionalProperties: false,
213
+ properties: {
214
+ name: { type: "string", minLength: 1, maxLength: 200 },
215
+ url: { type: "string", minLength: 1 },
216
+ events: {
217
+ type: "array",
218
+ minItems: 1,
219
+ items: { type: "string", enum: webhookEventsEnum },
220
+ },
221
+ scope: scopeSchema,
222
+ secret: { type: "string", maxLength: 256 },
223
+ headers: { type: "object", additionalProperties: { type: "string" } },
224
+ insecureTls: { type: "boolean" },
225
+ enabled: { type: "boolean" },
226
+ },
227
+ },
228
+ response: {
229
+ 200: webhookSchema,
230
+ 400: errorSchema,
231
+ 403: errorSchema,
232
+ 404: errorSchema,
233
+ },
234
+ },
235
+ }, async (req, reply) => {
236
+ const gate = minimalUiGate(reply);
237
+ if (gate !== undefined)
238
+ return gate;
239
+ try {
240
+ const patch = {};
241
+ if (req.body.name !== undefined)
242
+ patch.name = req.body.name;
243
+ if (req.body.url !== undefined)
244
+ patch.url = req.body.url;
245
+ if (req.body.events !== undefined)
246
+ patch.events = req.body.events.filter(isWebhookEvent);
247
+ if (req.body.scope !== undefined)
248
+ patch.scope = req.body.scope;
249
+ if (req.body.secret !== undefined)
250
+ patch.secret = req.body.secret;
251
+ if (req.body.headers !== undefined)
252
+ patch.headers = req.body.headers;
253
+ if (req.body.insecureTls !== undefined)
254
+ patch.insecureTls = req.body.insecureTls;
255
+ if (req.body.enabled !== undefined)
256
+ patch.enabled = req.body.enabled;
257
+ const w = await updateWebhook(req.params.id, patch);
258
+ return reply.code(200).send(toWire(w));
259
+ }
260
+ catch (err) {
261
+ return handleStoreError(reply, err);
262
+ }
263
+ });
264
+ fastify.delete("/webhooks/:id", {
265
+ schema: {
266
+ description: "Delete a webhook and prune its delivery history. Disabled under MINIMAL_UI.",
267
+ tags: ["webhooks"],
268
+ params: {
269
+ type: "object",
270
+ required: ["id"],
271
+ properties: { id: { type: "string" } },
272
+ },
273
+ response: {
274
+ 204: { type: "null" },
275
+ 403: errorSchema,
276
+ 404: errorSchema,
277
+ },
278
+ },
279
+ }, async (req, reply) => {
280
+ const gate = minimalUiGate(reply);
281
+ if (gate !== undefined)
282
+ return gate;
283
+ try {
284
+ await deleteWebhook(req.params.id);
285
+ return reply.code(204).send();
286
+ }
287
+ catch (err) {
288
+ return handleStoreError(reply, err);
289
+ }
290
+ });
291
+ fastify.post("/webhooks/:id/test", {
292
+ schema: {
293
+ description: "Fire a synthetic `webhook.test` event at the target webhook. Bypasses " +
294
+ "the event/scope filter — the test always reaches the targeted webhook. " +
295
+ "Useful for verifying URL + signature wiring before waiting for a real " +
296
+ "event. Returns immediately after queuing; the delivery record (with " +
297
+ "outcome) shows up in `/webhooks/:id/deliveries` once the request " +
298
+ "completes.\n\nDisabled under MINIMAL_UI.",
299
+ tags: ["webhooks"],
300
+ params: {
301
+ type: "object",
302
+ required: ["id"],
303
+ properties: { id: { type: "string" } },
304
+ },
305
+ response: {
306
+ 200: {
307
+ type: "object",
308
+ required: ["queued"],
309
+ properties: { queued: { type: "boolean" } },
310
+ },
311
+ 403: errorSchema,
312
+ 404: errorSchema,
313
+ },
314
+ },
315
+ }, async (req, reply) => {
316
+ const gate = minimalUiGate(reply);
317
+ if (gate !== undefined)
318
+ return gate;
319
+ const w = await getWebhook(req.params.id);
320
+ if (w === undefined) {
321
+ return reply.code(404).send({ error: "webhook_not_found" });
322
+ }
323
+ await dispatch({
324
+ event: "webhook.test",
325
+ data: {
326
+ message: "This is a test event from pi-forge.",
327
+ webhookId: w.id,
328
+ webhookName: w.name,
329
+ },
330
+ }, { onlyWebhookId: w.id });
331
+ return reply.code(200).send({ queued: true });
332
+ });
333
+ fastify.get("/webhooks/:id/deliveries", {
334
+ schema: {
335
+ description: "Return recent delivery records for a webhook, newest first. Capped at " +
336
+ "100 per webhook (rolling FIFO). Available regardless of MINIMAL_UI so " +
337
+ "an operator can audit delivery health without disabling the gate.",
338
+ tags: ["webhooks"],
339
+ params: {
340
+ type: "object",
341
+ required: ["id"],
342
+ properties: { id: { type: "string" } },
343
+ },
344
+ response: {
345
+ 200: {
346
+ type: "object",
347
+ required: ["deliveries"],
348
+ properties: { deliveries: { type: "array", items: deliverySchema } },
349
+ },
350
+ 404: errorSchema,
351
+ },
352
+ },
353
+ }, async (req, reply) => {
354
+ const w = await getWebhook(req.params.id);
355
+ if (w === undefined) {
356
+ return reply.code(404).send({ error: "webhook_not_found" });
357
+ }
358
+ const records = await readDeliveriesForWebhook(req.params.id);
359
+ return { deliveries: records };
360
+ });
361
+ };
362
+ //# sourceMappingURL=webhooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../src/routes/webhooks.ts"],"names":[],"mappings":"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"}