@hachej/boring-agent 0.1.111 → 0.2.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 (156) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +262 -51
  3. package/dist/agents.d.ts +75 -0
  4. package/dist/agents.js +91 -0
  5. package/dist/approval.d.ts +71 -0
  6. package/dist/approval.js +126 -0
  7. package/dist/artifacts.d.ts +53 -0
  8. package/dist/artifacts.js +129 -0
  9. package/dist/ask-user.d.ts +40 -0
  10. package/dist/ask-user.js +134 -0
  11. package/dist/attachment.d.ts +5 -0
  12. package/dist/attachment.js +4 -0
  13. package/dist/browser-task.d.ts +32 -0
  14. package/dist/browser-task.js +119 -0
  15. package/dist/chat-transport.d.ts +80 -0
  16. package/dist/chat-transport.js +306 -0
  17. package/dist/contracts.d.ts +40 -0
  18. package/dist/contracts.js +1 -0
  19. package/dist/conversations.d.ts +136 -0
  20. package/dist/conversations.js +366 -0
  21. package/dist/definitions.d.ts +37 -0
  22. package/dist/definitions.js +99 -0
  23. package/dist/delivery-input.d.ts +35 -0
  24. package/dist/delivery-input.js +56 -0
  25. package/dist/delivery.d.ts +33 -0
  26. package/dist/delivery.js +154 -0
  27. package/dist/durable-wait.d.ts +23 -0
  28. package/dist/durable-wait.js +79 -0
  29. package/dist/file-convert.d.ts +46 -0
  30. package/dist/file-convert.js +159 -0
  31. package/dist/file-guard.d.ts +50 -0
  32. package/dist/file-guard.js +177 -0
  33. package/dist/file-types.d.ts +17 -0
  34. package/dist/file-types.js +95 -0
  35. package/dist/gateway-provider.d.ts +24 -0
  36. package/dist/gateway-provider.js +42 -0
  37. package/dist/git.d.ts +34 -0
  38. package/dist/git.js +79 -0
  39. package/dist/harness-pool.d.ts +38 -0
  40. package/dist/harness-pool.js +134 -0
  41. package/dist/index.d.ts +4 -0
  42. package/dist/index.js +1 -0
  43. package/dist/json-schema-tool.d.ts +25 -0
  44. package/dist/json-schema-tool.js +19 -0
  45. package/dist/memory/optchat-core.d.ts +118 -0
  46. package/dist/memory/optchat-core.js +317 -0
  47. package/dist/memory/optchat.d.ts +156 -0
  48. package/dist/memory/optchat.js +432 -0
  49. package/dist/mentions.d.ts +56 -0
  50. package/dist/mentions.js +140 -0
  51. package/dist/metering.d.ts +183 -0
  52. package/dist/metering.js +443 -0
  53. package/dist/model-gateway.d.ts +86 -0
  54. package/dist/model-gateway.js +241 -0
  55. package/dist/native-version.d.ts +9 -0
  56. package/dist/native-version.js +7 -0
  57. package/dist/native.d.ts +4 -0
  58. package/dist/native.js +1 -0
  59. package/dist/presentation.d.ts +17 -0
  60. package/dist/presentation.js +39 -0
  61. package/dist/projection-format.d.ts +68 -0
  62. package/dist/projection-format.js +118 -0
  63. package/dist/projection-window.d.ts +9 -0
  64. package/dist/projection-window.js +93 -0
  65. package/dist/projection.d.ts +22 -0
  66. package/dist/projection.js +153 -0
  67. package/dist/question-response.d.ts +20 -0
  68. package/dist/question-response.js +75 -0
  69. package/dist/questions.d.ts +74 -0
  70. package/dist/questions.js +199 -0
  71. package/dist/self-evolving.d.ts +55 -0
  72. package/dist/self-evolving.js +239 -0
  73. package/dist/skills.d.ts +15 -0
  74. package/dist/skills.js +51 -0
  75. package/dist/tool-evidence.d.ts +14 -0
  76. package/dist/tool-evidence.js +54 -0
  77. package/dist/validation.d.ts +38 -0
  78. package/dist/validation.js +68 -0
  79. package/dist/workspaces.d.ts +107 -0
  80. package/dist/workspaces.js +212 -0
  81. package/package.json +145 -150
  82. package/dist/DebugDrawer-JNA43SVR.js +0 -8
  83. package/dist/admin-DORVQfLn.d.ts +0 -340
  84. package/dist/chunk-2BGLZZ7T.js +0 -10
  85. package/dist/chunk-42D6KAQV.js +0 -2882
  86. package/dist/chunk-4XOW57KJ.js +0 -343
  87. package/dist/chunk-72KT6VWV.js +0 -1338
  88. package/dist/chunk-7XAOVFSN.js +0 -28
  89. package/dist/chunk-KJIEMSQP.js +0 -198
  90. package/dist/chunk-KN72XWP7.js +0 -394
  91. package/dist/chunk-N6THTH7P.js +0 -110
  92. package/dist/chunk-V3H5A3BR.js +0 -22501
  93. package/dist/chunk-YGRQ4Q5P.js +0 -20
  94. package/dist/chunk-YTUZFKB3.js +0 -78
  95. package/dist/core/index.d.ts +0 -28
  96. package/dist/core/index.js +0 -617
  97. package/dist/createHarness-DOLOHA62.js +0 -18
  98. package/dist/eval/index.d.ts +0 -247
  99. package/dist/eval/index.js +0 -541
  100. package/dist/file-search-BUgMSKZE.d.ts +0 -289
  101. package/dist/front/artifacts.d.ts +0 -34
  102. package/dist/front/artifacts.js +0 -21
  103. package/dist/front/index.d.ts +0 -1082
  104. package/dist/front/index.js +0 -12912
  105. package/dist/front/styles.css +0 -5380
  106. package/dist/harness-qHlMJhZo.d.ts +0 -276
  107. package/dist/middleware-CaAEXpi5.d.ts +0 -115
  108. package/dist/piChatEvent-DpE0lIb9.d.ts +0 -450
  109. package/dist/piChatSessionService-CBct-hmz.d.ts +0 -86
  110. package/dist/sandbox-BMhut3kh.d.ts +0 -317
  111. package/dist/server/agent-host/testing/compositionRouteProof.d.ts +0 -8
  112. package/dist/server/agent-host/testing/compositionRouteProof.js +0 -78
  113. package/dist/server/agent-host/testing/gatewayConformance.d.ts +0 -43
  114. package/dist/server/agent-host/testing/gatewayConformance.js +0 -605
  115. package/dist/server/index.d.ts +0 -2278
  116. package/dist/server/index.js +0 -274
  117. package/dist/server/pi-session-readability.d.ts +0 -12
  118. package/dist/server/pi-session-readability.js +0 -23
  119. package/dist/server/worker/index.d.ts +0 -68
  120. package/dist/server/worker/index.js +0 -377
  121. package/dist/share-entry-CxS6UJ_L.d.ts +0 -330
  122. package/dist/shared/index.d.ts +0 -2111
  123. package/dist/shared/index.js +0 -262
  124. package/dist/types-DcWoQMn8.d.ts +0 -1377
  125. package/docs/ACCESSIBILITY.md +0 -52
  126. package/docs/AGENT_GATEWAY_V0.md +0 -212
  127. package/docs/AGENT_PACKAGES.md +0 -90
  128. package/docs/API.md +0 -123
  129. package/docs/AUTHORING.md +0 -68
  130. package/docs/CSP.md +0 -41
  131. package/docs/ERROR_CODES.md +0 -229
  132. package/docs/KNOWN_LIMITATIONS.md +0 -100
  133. package/docs/MIGRATION.md +0 -50
  134. package/docs/PERFORMANCE.md +0 -68
  135. package/docs/PLUGINS.md +0 -138
  136. package/docs/README.md +0 -98
  137. package/docs/RISKS-MULTI-TAB.md +0 -46
  138. package/docs/SESSION_IDENTITY.md +0 -91
  139. package/docs/STYLING.md +0 -73
  140. package/docs/UI-SHADCN.md +0 -56
  141. package/docs/VERCEL_COSTS.md +0 -103
  142. package/docs/plans/archive/AGENT_EVAL_FRAMEWORK.md +0 -466
  143. package/docs/plans/archive/agent-package-spec.md +0 -1777
  144. package/docs/plans/archive/harness-followup-capabilities.md +0 -440
  145. package/docs/plans/archive/harness-tool-ui-capabilities.md +0 -144
  146. package/docs/plans/archive/pi-followup-history-projection.md +0 -229
  147. package/docs/plans/archive/pi-tools-migration.md +0 -1061
  148. package/docs/plans/archive/reviews/pi-followup-history-codex-review.md +0 -11
  149. package/docs/plans/archive/reviews/pi-followup-history-gpt-review.md +0 -64
  150. package/docs/plans/archive/reviews/pi-followup-history-opus-review.md +0 -43
  151. package/docs/plans/archive/reviews/pi-followup-history-xai-review.md +0 -43
  152. package/docs/plans/archive/vercel-base-snapshot-template-plan.md +0 -527
  153. package/docs/plans/archive/vercel-persistent-sandbox-adapter.md +0 -553
  154. package/docs/runtime-provisioning.md +0 -157
  155. package/docs/runtime.md +0 -296
  156. package/docs/tools.md +0 -102
@@ -1,377 +0,0 @@
1
- import {
2
- REMOTE_WORKER_EXCLUSIVE_BINARY_CREATE_CAPABILITY,
3
- WORKER_INTERNAL_TOKEN_HEADER,
4
- constantTimeTokenEqual
5
- } from "../../chunk-V3H5A3BR.js";
6
- import "../../chunk-42D6KAQV.js";
7
- import "../../chunk-72KT6VWV.js";
8
- import "../../chunk-7XAOVFSN.js";
9
- import "../../chunk-YTUZFKB3.js";
10
- import "../../chunk-KN72XWP7.js";
11
- import "../../chunk-YGRQ4Q5P.js";
12
- import "../../chunk-KJIEMSQP.js";
13
-
14
- // src/server/worker/index.ts
15
- import Fastify from "fastify";
16
-
17
- // src/server/config/workerConfig.ts
18
- var FILE_SIZE_BLOCKS_PER_MIB = 2048;
19
- var KIB_PER_MIB = 1024;
20
- function requireEnv(name) {
21
- const value = process.env[name]?.trim();
22
- if (!value) throw new Error(`${name} is required`);
23
- return value;
24
- }
25
- function numberEnv(name, fallback) {
26
- const raw = process.env[name]?.trim();
27
- if (!raw) return fallback;
28
- const parsed = Number.parseInt(raw, 10);
29
- return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
30
- }
31
- function bwrapNetworkEnv() {
32
- const raw = process.env.BORING_WORKER_BWRAP_NETWORK?.trim().toLowerCase();
33
- return raw === "shared" ? "shared" : "isolated";
34
- }
35
- function resourceLimitsEnv() {
36
- return {
37
- cpuSeconds: numberEnv("BORING_WORKER_EXEC_CPU_SECONDS", 30),
38
- fileSizeBlocks: numberEnv("BORING_WORKER_EXEC_FILE_SIZE_MIB", 64) * FILE_SIZE_BLOCKS_PER_MIB,
39
- maxProcesses: numberEnv("BORING_WORKER_EXEC_MAX_PROCESSES", 512),
40
- openFiles: numberEnv("BORING_WORKER_EXEC_OPEN_FILES", 256),
41
- virtualMemoryKb: numberEnv("BORING_WORKER_EXEC_VIRTUAL_MEMORY_MIB", 1024) * KIB_PER_MIB
42
- };
43
- }
44
- function loadWorkerConfig() {
45
- return {
46
- workspaceRoot: requireEnv("BORING_WORKER_WORKSPACE_ROOT"),
47
- internalToken: requireEnv("BORING_WORKER_INTERNAL_TOKEN"),
48
- port: numberEnv("PORT", 3e3),
49
- host: process.env.HOST?.trim() || "0.0.0.0",
50
- execConcurrency: numberEnv("BORING_WORKER_EXEC_CONCURRENCY", 2),
51
- bwrapNetwork: bwrapNetworkEnv(),
52
- resourceLimits: resourceLimitsEnv()
53
- };
54
- }
55
-
56
- // src/server/worker/error-codes.ts
57
- var WORKER_ERROR_CODES = {
58
- AUTH_INVALID: "auth_invalid",
59
- VALIDATION_ERROR: "validation_error",
60
- INVALID_WORKSPACE_ID: "invalid_workspace_id",
61
- NOT_IMPLEMENTED: "not_implemented",
62
- ALREADY_EXISTS: "REMOTE_WORKER_ALREADY_EXISTS",
63
- EXEC_CONCURRENCY_LIMIT: "exec_concurrency_limit",
64
- UNSUPPORTED_WORKSPACE_OP: "unsupported_workspace_op"
65
- };
66
-
67
- // src/server/worker/auth.ts
68
- function verifyInternalToken(request, reply, expectedToken) {
69
- const provided = request.headers[WORKER_INTERNAL_TOKEN_HEADER];
70
- const token = Array.isArray(provided) ? provided[0] : provided;
71
- if (typeof token !== "string" || !constantTimeTokenEqual(token, expectedToken)) {
72
- reply.code(401).send({
73
- error: {
74
- code: WORKER_ERROR_CODES.AUTH_INVALID,
75
- message: "invalid internal token",
76
- statusCode: 401
77
- }
78
- });
79
- return false;
80
- }
81
- return true;
82
- }
83
-
84
- // src/server/worker/exec.ts
85
- var ExecSemaphore = class {
86
- constructor(limit) {
87
- this.limit = limit;
88
- }
89
- limit;
90
- active = 0;
91
- async run(fn) {
92
- if (this.active >= this.limit) {
93
- throw Object.assign(new Error("worker exec concurrency limit reached"), {
94
- statusCode: 429,
95
- code: WORKER_ERROR_CODES.EXEC_CONCURRENCY_LIMIT
96
- });
97
- }
98
- this.active += 1;
99
- try {
100
- return await fn();
101
- } finally {
102
- this.active -= 1;
103
- }
104
- }
105
- };
106
- function buildExecEnv(input) {
107
- const safe = {
108
- PATH: "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
109
- HOME: "/workspace",
110
- LANG: "C.UTF-8"
111
- };
112
- if (!input) return safe;
113
- for (const [key, value] of Object.entries(input)) {
114
- if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) continue;
115
- if (key.startsWith("BORING_WORKER_")) continue;
116
- if (key.endsWith("_API_KEY") || key.endsWith("_TOKEN") || key.endsWith("_SECRET")) continue;
117
- if (key === "DATABASE_URL") continue;
118
- safe[key] = String(value);
119
- }
120
- return safe;
121
- }
122
-
123
- // src/server/worker/workspace.ts
124
- import { mkdir } from "node:fs/promises";
125
- import { join } from "node:path";
126
- var WORKSPACE_UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
127
- function assertSafeWorkspaceId(workspaceId) {
128
- const normalized = workspaceId.trim().toLowerCase();
129
- if (!WORKSPACE_UUID.test(normalized)) {
130
- throw Object.assign(new Error("workspace id must be a uuid"), { statusCode: 400, code: WORKER_ERROR_CODES.INVALID_WORKSPACE_ID });
131
- }
132
- return normalized;
133
- }
134
- async function createWorkerRuntime(root, workspaceId, provider) {
135
- const safeId = assertSafeWorkspaceId(workspaceId);
136
- const hostRoot = join(root, safeId);
137
- await mkdir(hostRoot, { recursive: true });
138
- const pair = await provider.create({
139
- workspaceRoot: hostRoot,
140
- workspaceId: safeId,
141
- sessionId: safeId
142
- });
143
- return { workspace: pair.workspace, sandbox: pair.sandbox, dispose: () => pair.dispose() };
144
- }
145
- async function runWorkspaceOp(workspace, op) {
146
- switch (op.op) {
147
- case "readFile":
148
- return { content: await workspace.readFile(op.path) };
149
- case "readBinaryFile":
150
- if (!workspace.readBinaryFile) throw Object.assign(new Error("binary read unsupported"), { statusCode: 501, code: WORKER_ERROR_CODES.NOT_IMPLEMENTED });
151
- return { dataBase64: Buffer.from(await workspace.readBinaryFile(op.path)).toString("base64") };
152
- case "writeFile":
153
- await workspace.writeFile(op.path, op.data);
154
- return { ok: true };
155
- case "writeBinaryFile":
156
- if (!workspace.writeBinaryFile) throw Object.assign(new Error("binary write unsupported"), { statusCode: 501, code: WORKER_ERROR_CODES.NOT_IMPLEMENTED });
157
- await workspace.writeBinaryFile(op.path, new Uint8Array(Buffer.from(op.dataBase64, "base64")));
158
- return { ok: true };
159
- case "createBinaryFile":
160
- if (!workspace.createBinaryFile) throw Object.assign(new Error("exclusive binary create unsupported"), { statusCode: 501, code: WORKER_ERROR_CODES.NOT_IMPLEMENTED });
161
- try {
162
- await workspace.createBinaryFile(op.path, new Uint8Array(Buffer.from(op.dataBase64, "base64")));
163
- } catch (error) {
164
- if (error?.code === "EEXIST") {
165
- throw Object.assign(new Error("exclusive binary create destination exists"), {
166
- statusCode: 409,
167
- code: WORKER_ERROR_CODES.ALREADY_EXISTS
168
- });
169
- }
170
- throw error;
171
- }
172
- return { ok: true };
173
- case "readFileWithStat":
174
- if (!workspace.readFileWithStat) {
175
- return { content: await workspace.readFile(op.path), stat: await workspace.stat(op.path) };
176
- }
177
- return await workspace.readFileWithStat(op.path);
178
- case "writeFileWithStat":
179
- if (!workspace.writeFileWithStat) {
180
- await workspace.writeFile(op.path, op.data);
181
- return { stat: await workspace.stat(op.path) };
182
- }
183
- return { stat: await workspace.writeFileWithStat(op.path, op.data) };
184
- case "writeBinaryFileWithStat":
185
- if (!workspace.writeBinaryFile) throw Object.assign(new Error("binary write unsupported"), { statusCode: 501, code: WORKER_ERROR_CODES.NOT_IMPLEMENTED });
186
- if (!workspace.writeBinaryFileWithStat) {
187
- await workspace.writeBinaryFile(op.path, new Uint8Array(Buffer.from(op.dataBase64, "base64")));
188
- return { stat: await workspace.stat(op.path) };
189
- }
190
- return { stat: await workspace.writeBinaryFileWithStat(op.path, new Uint8Array(Buffer.from(op.dataBase64, "base64"))) };
191
- case "unlink":
192
- await workspace.unlink(op.path);
193
- return { ok: true };
194
- case "readdir":
195
- return { entries: await workspace.readdir(op.path) };
196
- case "stat":
197
- return { stat: await workspace.stat(op.path) };
198
- case "mkdir":
199
- await workspace.mkdir(op.path, { recursive: op.recursive });
200
- return { ok: true };
201
- case "rename":
202
- await workspace.rename(op.from, op.to);
203
- return { ok: true };
204
- default: {
205
- const _never = op;
206
- throw Object.assign(new Error(`unsupported workspace op ${op.op ?? "unknown"}`), {
207
- statusCode: 400,
208
- code: WORKER_ERROR_CODES.UNSUPPORTED_WORKSPACE_OP,
209
- details: _never
210
- });
211
- }
212
- }
213
- }
214
-
215
- // src/server/worker/routes.ts
216
- function errorPayload(error) {
217
- const record = error;
218
- const statusCode = typeof record.statusCode === "number" ? record.statusCode : 500;
219
- return {
220
- error: {
221
- code: typeof record.code === "string" ? record.code : statusCode >= 500 ? "internal" : "bad_request",
222
- message: typeof record.message === "string" ? record.message : "worker request failed",
223
- statusCode,
224
- ...record.details === void 0 ? {} : { details: record.details }
225
- }
226
- };
227
- }
228
- function sendError(reply, error) {
229
- const payload = errorPayload(error);
230
- reply.code(payload.error.statusCode).send(payload);
231
- }
232
- function resultToResponse(result) {
233
- return {
234
- stdoutBase64: Buffer.from(result.stdout).toString("base64"),
235
- stderrBase64: Buffer.from(result.stderr).toString("base64"),
236
- exitCode: result.exitCode,
237
- durationMs: result.durationMs,
238
- truncated: result.truncated,
239
- stdoutEncoding: result.stdoutEncoding,
240
- stderrEncoding: result.stderrEncoding
241
- };
242
- }
243
- async function registerWorkerRoutes(app, config, runtimeProvider) {
244
- const semaphore = new ExecSemaphore(config.execConcurrency);
245
- const runtimes = /* @__PURE__ */ new Map();
246
- const getRuntime = (workspaceId) => {
247
- const safeId = assertSafeWorkspaceId(workspaceId);
248
- let runtime = runtimes.get(safeId);
249
- if (!runtime) {
250
- if (!runtimeProvider) throw new Error("worker runtime provider must be injected by the host");
251
- runtime = createWorkerRuntime(config.workspaceRoot, safeId, runtimeProvider);
252
- runtimes.set(safeId, runtime);
253
- }
254
- return runtime;
255
- };
256
- app.addHook("onClose", async () => {
257
- for (const runtimePromise of runtimes.values()) {
258
- try {
259
- const runtime = await runtimePromise;
260
- await runtime.dispose();
261
- } catch {
262
- }
263
- }
264
- });
265
- app.get("/health", async () => ({ ok: true }));
266
- app.get("/internal/health", async () => ({
267
- ok: true,
268
- capabilities: [REMOTE_WORKER_EXCLUSIVE_BINARY_CREATE_CAPABILITY]
269
- }));
270
- app.addHook("preHandler", async (request, reply) => {
271
- if (request.method === "GET" && request.url === "/health") return;
272
- if (!verifyInternalToken(request, reply, config.internalToken)) return reply;
273
- });
274
- app.post(
275
- "/internal/workspaces/:workspaceId/fs",
276
- async (request, reply) => {
277
- try {
278
- const runtime = await getRuntime(request.params.workspaceId);
279
- if (!request.body || typeof request.body.op !== "string") {
280
- throw Object.assign(new Error("workspace op is required"), { statusCode: 400, code: WORKER_ERROR_CODES.VALIDATION_ERROR });
281
- }
282
- return await runWorkspaceOp(runtime.workspace, request.body);
283
- } catch (error) {
284
- sendError(reply, error);
285
- }
286
- }
287
- );
288
- app.post(
289
- "/internal/workspaces/:workspaceId/exec",
290
- async (request, reply) => {
291
- try {
292
- const runtime = await getRuntime(request.params.workspaceId);
293
- const body = request.body;
294
- if (!body || typeof body.cmd !== "string" || body.cmd.length === 0) {
295
- throw Object.assign(new Error("cmd is required"), { statusCode: 400, code: WORKER_ERROR_CODES.VALIDATION_ERROR });
296
- }
297
- const abortController = new AbortController();
298
- const abort = () => abortController.abort();
299
- request.raw.on("aborted", abort);
300
- reply.raw.on("close", abort);
301
- const result = await semaphore.run(() => runtime.sandbox.exec(body.cmd, {
302
- cwd: body.cwd,
303
- env: buildExecEnv(body.env),
304
- timeoutMs: body.timeoutMs,
305
- maxOutputBytes: body.maxOutputBytes,
306
- signal: abortController.signal
307
- }));
308
- return resultToResponse(result);
309
- } catch (error) {
310
- sendError(reply, error);
311
- }
312
- }
313
- );
314
- app.get(
315
- "/internal/workspaces/:workspaceId/fs/events",
316
- async (request, reply) => {
317
- let unsubscribe = null;
318
- let heartbeat = null;
319
- try {
320
- const runtime = await getRuntime(request.params.workspaceId);
321
- reply.hijack();
322
- reply.raw.writeHead(200, {
323
- "content-type": "text/event-stream; charset=utf-8",
324
- "cache-control": "no-cache, no-transform",
325
- connection: "keep-alive",
326
- "x-accel-buffering": "no"
327
- });
328
- reply.raw.flushHeaders?.();
329
- reply.raw.write(": connected\n\n");
330
- const send = (payload) => {
331
- reply.raw.write(`event: change
332
- data: ${JSON.stringify(payload)}
333
-
334
- `);
335
- };
336
- if (!runtime.workspace.watch) {
337
- throw Object.assign(new Error("workspace events unsupported"), { statusCode: 501, code: WORKER_ERROR_CODES.NOT_IMPLEMENTED });
338
- }
339
- unsubscribe = runtime.workspace.watch().subscribe((event) => send({ event }));
340
- heartbeat = setInterval(() => reply.raw.write(": heartbeat\n\n"), 15e3);
341
- const cleanup = () => {
342
- unsubscribe?.();
343
- unsubscribe = null;
344
- if (heartbeat) clearInterval(heartbeat);
345
- heartbeat = null;
346
- };
347
- request.raw.on("close", cleanup);
348
- reply.raw.on("close", cleanup);
349
- } catch (error) {
350
- if (heartbeat) clearInterval(heartbeat);
351
- unsubscribe?.();
352
- if (!reply.sent) sendError(reply, error);
353
- }
354
- }
355
- );
356
- }
357
-
358
- // src/server/worker/index.ts
359
- var DEFAULT_BODY_LIMIT = 20 * 1024 * 1024;
360
- async function createWorkerServer(options = {}) {
361
- const config = options.config ?? loadWorkerConfig();
362
- const app = Fastify({ logger: true, bodyLimit: DEFAULT_BODY_LIMIT, ...options.fastify });
363
- await registerWorkerRoutes(app, config, options.runtimeProvider);
364
- return { app, config };
365
- }
366
- export {
367
- ExecSemaphore,
368
- WORKER_ERROR_CODES,
369
- assertSafeWorkspaceId,
370
- buildExecEnv,
371
- createWorkerRuntime,
372
- createWorkerServer,
373
- loadWorkerConfig,
374
- registerWorkerRoutes,
375
- runWorkspaceOp,
376
- verifyInternalToken
377
- };