@hachej/boring-agent 0.1.101 → 0.1.104

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 (36) hide show
  1. package/dist/{DebugDrawer-2TO5SE2D.js → DebugDrawer-JNA43SVR.js} +2 -1
  2. package/dist/chunk-2BGLZZ7T.js +10 -0
  3. package/dist/{chunk-46HJK2ES.js → chunk-4XOW57KJ.js} +3 -8
  4. package/dist/{chunk-XCZBICZS.js → chunk-6DRHERVK.js} +8 -6
  5. package/dist/{chunk-XTMY3PWI.js → chunk-BTYOMR7W.js} +118 -16
  6. package/dist/{chunk-T37OVD6L.js → chunk-I7KFNGB4.js} +28 -2
  7. package/dist/{chunk-3OEDBRKY.js → chunk-JNEKOVMJ.js} +1 -1
  8. package/dist/{chunk-VXF5DWS6.js → chunk-K25PK5EC.js} +1 -0
  9. package/dist/chunk-N6THTH7P.js +110 -0
  10. package/dist/core/index.d.ts +5 -5
  11. package/dist/core/index.js +1 -1
  12. package/dist/{createHarness-7C2A5UVH.js → createHarness-POZ4AXCZ.js} +2 -2
  13. package/dist/{errors-Ci0dzmcP.d.ts → errors-DH7C01Pm.d.ts} +2 -2
  14. package/dist/{file-search-DmoDnMan.d.ts → file-search-qcD5zItr.d.ts} +5 -5
  15. package/dist/front/artifacts.d.ts +34 -0
  16. package/dist/front/artifacts.js +21 -0
  17. package/dist/front/index.d.ts +8 -14
  18. package/dist/front/index.js +775 -762
  19. package/dist/front/styles.css +4 -0
  20. package/dist/{harness-s-kEgJkK.d.ts → harness-Dcd08yKr.d.ts} +2 -2
  21. package/dist/{lease-D5-CBoPs.d.ts → lease-DffrPrQn.d.ts} +3 -3
  22. package/dist/{middleware-Cq_cYHjJ.d.ts → middleware-CaAEXpi5.d.ts} +11 -2
  23. package/dist/{piChatEvent-Bzof4IEy.d.ts → piChatEvent-iNSXiFQq.d.ts} +19 -14
  24. package/dist/{piChatSessionService-BU4L5hxM.d.ts → piChatSessionService-DQSQ_kWZ.d.ts} +1 -1
  25. package/dist/{sandbox-KQiEdz4W.d.ts → sandbox-BMhut3kh.d.ts} +6 -1
  26. package/dist/server/agent-host/testing/gatewayConformance.d.ts +6 -6
  27. package/dist/server/agent-host/testing/gatewayConformance.js +3 -3
  28. package/dist/server/index.d.ts +21 -16
  29. package/dist/server/index.js +7 -5
  30. package/dist/server/worker/index.d.ts +3 -2
  31. package/dist/server/worker/index.js +25 -6
  32. package/dist/shared/index.d.ts +113 -39
  33. package/dist/shared/index.js +3 -3
  34. package/dist/{types-OwI_m-2p.d.ts → types-B1xDlBSo.d.ts} +13 -5
  35. package/docs/ERROR_CODES.md +1 -0
  36. package/package.json +16 -12
@@ -1,21 +1,22 @@
1
- import { P as ProvisionWorkspaceRuntimeOptions, W as WorkspaceProvisioningResult, a as PiPackageSource, R as RuntimeModeAdapter, b as RuntimeModeId, B as BuiltinRuntimeModeId, c as AgentRuntimeHostOperations, d as RuntimeBashStrategy, e as RuntimeFilesystemStrategy, M as ModeContext, f as WorkspaceProvisioningAdapter, g as AgentInstructionFileRef, C as ConfiguredAgentHostAgentSpec, h as AgentHostAgentSpec, i as RuntimeBundle, j as PiHarnessOptions, k as AgentMeteringSink, l as RuntimeFilesystemBinding, m as CreatedAgentHost, n as MeteringErrorLogger, o as ReadyStatusTracker, p as CreateAgentHostOptions, q as CompiledAgentHostAgentSpec, r as AgentRequestLedger, s as AgentEffectAdmission, t as AuthorizedEnvironmentIntent, u as AgentHostEnvironmentScope, v as ResolvedAgentRuntimeScope, w as AgentRequestKey, x as AgentRequestLedgerPrepareResult, y as AgentRequestFailure, z as AgentRequestLedgerRecord, D as AgentFleetCompiler, E as AgentRequestTarget, F as RuntimeFilesystemAccessDecision } from '../types-OwI_m-2p.js';
2
- export { A as AgentGatewayEffect, G as AgentHostDescription, H as AgentHostDirectProjectionOptions, I as AgentHostDispatcherRunInput, J as AgentHostEnvironmentLease, K as AgentHostHandle, L as LegacyDefaultAgentHostSpec, N as MeteringReleaseInput, O as MeteringReleaseReason, Q as MeteringReservationResult, S as MeteringReserveInput, T as MeteringRunKind, U as MeteringRunScope, V as MeteringRunStatus, X as MeteringSettleInput, Y as MeteringUsage, Z as MeteringUsageInput, _ as PI_PACKAGE_RESOURCE_FILTERS, $ as PiExtensionFactory, a0 as PluginSkillSource, a1 as ResolvedEnvironmentScope, a2 as RuntimeFilesystemBindingOperations, a3 as RuntimeNodePackageSpec, a4 as RuntimeProvisioningContribution, a5 as RuntimePythonSpec, a6 as RuntimeTemplateContribution, a7 as WorkspaceProvisioningExecResult, a8 as compactPiPackages, a9 as mergePiPackageSources, aa as normalizeMeteringUsage, ab as piPackageSourceKey } from '../types-OwI_m-2p.js';
3
- import { E as ExecOptions, a as ExecResult, W as WorkspaceChangeEvent, b as Workspace, S as Sandbox } from '../sandbox-KQiEdz4W.js';
4
- export { R as RuntimeFilesystemCapability } from '../sandbox-KQiEdz4W.js';
5
- import { R as RemoteWorkerWorkspaceOp, a as RemoteWorkerWorkspaceResult, b as RemoteWorkerExecRequest } from '../middleware-Cq_cYHjJ.js';
6
- export { c as REMOTE_WORKER_PROVIDER, d as REMOTE_WORKER_RUNTIME_CWD, e as RemoteWorkerErrorPayload, f as RemoteWorkerExecResponse, g as RemoteWorkerFsEventEnvelope, W as WORKER_INTERNAL_TOKEN_HEADER, h as WORKER_REQUEST_ID_HEADER, i as WORKER_WORKSPACE_ID_HEADER, j as createAgentAuthMiddleware } from '../middleware-Cq_cYHjJ.js';
1
+ import { P as ProvisionWorkspaceRuntimeOptions, W as WorkspaceProvisioningResult, a as PiPackageSource, R as RuntimeModeAdapter, b as RuntimeModeId, B as BuiltinRuntimeModeId, c as AgentRuntimeHostOperations, d as RuntimeBashStrategy, e as RuntimeFilesystemStrategy, M as ModeContext, f as WorkspaceProvisioningAdapter, g as AgentInstructionFileRef, C as ConfiguredAgentHostAgentSpec, h as AgentHostAgentSpec, i as RuntimeBundle, j as PiHarnessOptions, k as AgentMeteringSink, l as RuntimeFilesystemBinding, m as CreatedAgentHost, n as MeteringErrorLogger, o as ReadyStatusTracker, p as CreateAgentHostOptions, q as CompiledAgentHostAgentSpec, r as AgentRequestLedger, s as AgentEffectAdmission, t as AuthorizedEnvironmentIntent, u as AgentHostEnvironmentScope, v as ResolvedAgentRuntimeScope, w as AgentRequestKey, x as AgentRequestLedgerPrepareResult, y as AgentRequestFailure, z as AgentRequestLedgerRecord, D as AgentFleetCompiler, E as AgentRequestTarget, F as RuntimeFilesystemAccessDecision } from '../types-B1xDlBSo.js';
2
+ export { A as AgentGatewayEffect, G as AgentHostDescription, H as AgentHostDirectProjectionOptions, I as AgentHostDispatcherRunInput, J as AgentHostEnvironmentLease, K as AgentHostHandle, L as LegacyDefaultAgentHostSpec, N as MeteringReleaseInput, O as MeteringReleaseReason, Q as MeteringReservationResult, S as MeteringReserveInput, T as MeteringRunKind, U as MeteringRunScope, V as MeteringRunStatus, X as MeteringSettleInput, Y as MeteringUsage, Z as MeteringUsageInput, _ as PI_PACKAGE_RESOURCE_FILTERS, $ as PiExtensionFactory, a0 as PluginSkillSource, a1 as ResolvedEnvironmentScope, a2 as RuntimeFilesystemBindingOperations, a3 as RuntimeNodePackageSpec, a4 as RuntimeProvisioningContribution, a5 as RuntimePythonSpec, a6 as RuntimeTemplateContribution, a7 as WorkspaceProvisioningExecResult, a8 as compactPiPackages, a9 as mergePiPackageSources, aa as normalizeMeteringUsage, ab as piPackageSourceKey } from '../types-B1xDlBSo.js';
3
+ import { d as ExecOptions, a as ExecResult, W as WorkspaceChangeEvent, b as Workspace, c as Sandbox } from '../sandbox-BMhut3kh.js';
4
+ export { h as RuntimeFilesystemCapability } from '../sandbox-BMhut3kh.js';
5
+ import { b as RemoteWorkerHealthResponse, R as RemoteWorkerWorkspaceOp, a as RemoteWorkerWorkspaceResult, c as RemoteWorkerExecRequest } from '../middleware-CaAEXpi5.js';
6
+ export { d as REMOTE_WORKER_EXCLUSIVE_BINARY_CREATE_CAPABILITY, e as REMOTE_WORKER_PROVIDER, f as REMOTE_WORKER_RUNTIME_CWD, g as RemoteWorkerErrorPayload, h as RemoteWorkerExecResponse, i as RemoteWorkerFsEventEnvelope, W as WORKER_INTERNAL_TOKEN_HEADER, j as WORKER_REQUEST_ID_HEADER, k as WORKER_WORKSPACE_ID_HEADER, l as createAgentAuthMiddleware } from '../middleware-CaAEXpi5.js';
7
7
  import { SandboxProviderV1, WorkspaceSandboxPairV1 } from '@hachej/boring-sandbox/shared';
8
- import { S as SandboxHandleStore, C as CompiledAgentBundle, a as Sha256Digest, A as AgentDeployment, b as ShareEntryStore, P as ProviderId, c as CredentialFieldId, R as ResolvedCredentialMaterialV1, d as AuthorizedWorkspaceCredentialScopeV1, V as VerifiedWorkspaceCredentialAuthorityV1, W as WorkspaceCredentialAuthorityVerifierV1, e as CredentialConsumerBindingRegistryV1, f as ProviderRegistryV1, g as WorkspaceCredentialResolverV1, h as ProviderCredentialRefV1, i as ResolvedCredentialLeaseV1 } from '../lease-D5-CBoPs.js';
9
- import { E as ErrorCode, l as SessionCtx, b as PiChatEvent, S as SessionStore, m as SessionListOptions, k as SessionSummary, n as PiChatSnapshot, c as PromptPayload, d as PromptReceipt, F as FollowUpPayload, e as FollowUpReceipt, f as QueueClearPayload, g as QueueClearReceipt, I as InterruptPayload, i as StopPayload, j as StopReceipt } from '../piChatEvent-Bzof4IEy.js';
10
- import { J as JsonValue, b as AgentGateway, c as AuthorizedAgentScope, d as AgentSessionRef, e as AgentSessionActivity, V as VerifiedAgentScopeClaim, f as AgentGatewayErrorDTO, g as AgentSessionSummary, h as AgentSessionStateSnapshot, i as AgentSessionConnection } from '../errors-Ci0dzmcP.js';
11
- import { d as AgentActor, j as AgentEvent, T as TelemetrySink, s as AgentTool, t as AgentHarnessFactory, A as AgentHarness } from '../harness-s-kEgJkK.js';
12
- export { u as AgentConfig, v as AgentHarnessFactoryInput } from '../harness-s-kEgJkK.js';
8
+ import { BwrapSandboxProviderOptions } from '@hachej/boring-sandbox/providers/bwrap';
9
+ import { F as SandboxHandleStore, k as CompiledAgentBundle, a as Sha256Digest, i as AgentDeployment, M as ShareEntryStore, y as ProviderId, c as CredentialFieldId, B as ResolvedCredentialMaterialV1, d as AuthorizedWorkspaceCredentialScopeV1, V as VerifiedWorkspaceCredentialAuthorityV1, X as WorkspaceCredentialAuthorityVerifierV1, n as CredentialConsumerBindingRegistryV1, z as ProviderRegistryV1, Y as WorkspaceCredentialResolverV1, P as ProviderCredentialRefV1, R as ResolvedCredentialLeaseV1 } from '../lease-DffrPrQn.js';
10
+ import { y as ErrorCode, n as SessionCtx, c as PiChatEvent, S as SessionStore, a as SessionListOptions, b as SessionSummary, P as PiChatSnapshot, d as PromptPayload, e as PromptReceipt, F as FollowUpPayload, f as FollowUpReceipt, Q as QueueClearPayload, g as QueueClearReceipt, I as InterruptPayload, i as StopPayload, j as StopReceipt } from '../piChatEvent-iNSXiFQq.js';
11
+ import { x as JsonValue, A as AgentGateway, a as AuthorizedAgentScope, b as AgentSessionRef, c as AgentSessionActivity, V as VerifiedAgentScopeClaim, i as AgentGatewayErrorDTO, p as AgentSessionSummary, o as AgentSessionStateSnapshot, l as AgentSessionConnection } from '../errors-DH7C01Pm.js';
12
+ import { d as AgentActor, j as AgentEvent, v as TelemetrySink, s as AgentTool, D as AgentHarnessFactory, A as AgentHarness } from '../harness-Dcd08yKr.js';
13
+ export { u as AgentConfig, E as AgentHarnessFactoryInput } from '../harness-Dcd08yKr.js';
13
14
  import { IncomingMessage, ServerResponse } from 'node:http';
14
15
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
15
16
  import { FastifyRequest, FastifyInstance, FastifyPluginCallback } from 'fastify';
16
- import { i as PiSessionRequestContext, g as PiChatSessionService, h as PiSessionCreateInit, e as PiChatEventSubscriber, P as PiChatEventStreamResult } from '../piChatSessionService-BU4L5hxM.js';
17
- import { W as WorkspaceAgentDirectRunInput, a as WorkspaceAgentDirectRunCallback, b as WorkspaceAgentDispatcherContext, c as WorkspaceAgentDispatcher, d as WorkspaceAgentGatewayBinding } from '../file-search-DmoDnMan.js';
18
- export { L as LeaseBoundWorkspaceAgent } from '../file-search-DmoDnMan.js';
17
+ import { i as PiSessionRequestContext, g as PiChatSessionService, h as PiSessionCreateInit, e as PiChatEventSubscriber, P as PiChatEventStreamResult } from '../piChatSessionService-DQSQ_kWZ.js';
18
+ import { c as WorkspaceAgentDirectRunInput, W as WorkspaceAgentDirectRunCallback, f as WorkspaceAgentDispatcherContext, e as WorkspaceAgentDispatcher, i as WorkspaceAgentGatewayBinding } from '../file-search-qcD5zItr.js';
19
+ export { L as LeaseBoundWorkspaceAgent } from '../file-search-qcD5zItr.js';
19
20
  import { SettingsManager } from '@mariozechner/pi-coding-agent';
20
21
  import '@hachej/boring-bash/agent';
21
22
  import '@hachej/boring-sandbox/providers/node-workspace';
@@ -95,7 +96,7 @@ declare class RemoteWorkerClient {
95
96
  private timeoutError;
96
97
  private abortedError;
97
98
  private fetchWithTimeout;
98
- health(): Promise<void>;
99
+ health(): Promise<RemoteWorkerHealthResponse>;
99
100
  workspace(op: RemoteWorkerWorkspaceOp): Promise<RemoteWorkerWorkspaceResult>;
100
101
  exec(input: RemoteWorkerExecRequest, opts?: Pick<ExecOptions, 'signal'>): Promise<ExecResult>;
101
102
  watch(onEvent: (event: WorkspaceChangeEvent) => void, onError?: (error: Error) => void): {
@@ -115,7 +116,7 @@ interface RemoteWorkerModeAdapterOptions {
115
116
  }
116
117
  declare function createRemoteWorkerModeAdapter(opts?: RemoteWorkerModeAdapterOptions): RuntimeModeAdapter;
117
118
 
118
- declare function createRemoteWorkerWorkspace(client: RemoteWorkerClient): Workspace;
119
+ declare function createRemoteWorkerWorkspace(client: RemoteWorkerClient, supportsExclusiveBinaryCreate?: boolean): Workspace;
119
120
 
120
121
  declare function createRemoteWorkerSandbox(client: RemoteWorkerClient): Sandbox;
121
122
 
@@ -221,6 +222,7 @@ declare function createProviderRuntimeModeAdapter(options: ProviderRuntimeModeAd
221
222
  declare const sandboxRuntimeHostOperations: AgentRuntimeHostOperations;
222
223
  interface SandboxRuntimeModeOptions {
223
224
  readonly sandboxHandleStore?: SandboxHandleStore;
225
+ readonly bwrap?: BwrapSandboxProviderOptions;
224
226
  }
225
227
  /** Built-in runtime layout root without exposing provider package constants to consumers. */
226
228
  declare function resolveBuiltinRuntimeLayoutRoot(mode: BuiltinRuntimeModeId, workspaceRoot: string): string;
@@ -1336,6 +1338,8 @@ interface PiResourceDigestInput {
1336
1338
  readonly piUserHome: string;
1337
1339
  /** Mirrors Pi's noSkills resource-loader option. */
1338
1340
  readonly noSkills: boolean;
1341
+ /** Mirrors Pi's noContextFiles resource-loader option; omitted stays sealed. */
1342
+ readonly noContextFiles?: boolean;
1339
1343
  readonly promptParts?: readonly (string | undefined)[];
1340
1344
  readonly additionalSkillPaths?: readonly string[];
1341
1345
  readonly packages?: readonly PiPackageSource[];
@@ -1356,6 +1360,7 @@ declare function createPiResourceDigestInput(input: {
1356
1360
  readonly piAgentDir?: string;
1357
1361
  readonly piUserHome?: string;
1358
1362
  readonly noSkills?: boolean;
1363
+ readonly noContextFiles?: boolean;
1359
1364
  readonly resourceSets: readonly PiResourceSet[];
1360
1365
  readonly authorizedRoots: readonly string[];
1361
1366
  readonly limits?: Partial<PiResourceDigestLimits>;
@@ -13,6 +13,7 @@ import {
13
13
  MANAGED_AGENT_MCP_ORIGIN_SURFACE,
14
14
  ManagedAgentMcpDelegateController,
15
15
  ManagedAgentMcpError,
16
+ REMOTE_WORKER_EXCLUSIVE_BINARY_CREATE_CAPABILITY,
16
17
  REMOTE_WORKER_PROVIDER,
17
18
  REMOTE_WORKER_RUNTIME_CWD,
18
19
  RUNTIME_FILESYSTEM_BINDING_DUPLICATE_CODE,
@@ -88,20 +89,20 @@ import {
88
89
  shareResourceUri,
89
90
  withResolvedCredential,
90
91
  withRuntimeEnvContributions
91
- } from "../chunk-XTMY3PWI.js";
92
+ } from "../chunk-BTYOMR7W.js";
92
93
  import {
93
94
  PI_PACKAGE_RESOURCE_FILTERS,
94
95
  compactPiPackages,
95
96
  createResourceSettingsManager,
96
97
  mergePiPackageSources,
97
98
  piPackageSourceKey
98
- } from "../chunk-T37OVD6L.js";
99
- import "../chunk-3OEDBRKY.js";
99
+ } from "../chunk-I7KFNGB4.js";
100
+ import "../chunk-JNEKOVMJ.js";
100
101
  import "../chunk-4IQ4HHBG.js";
101
102
  import "../chunk-WSQ5QNIY.js";
102
- import "../chunk-XCZBICZS.js";
103
+ import "../chunk-6DRHERVK.js";
103
104
  import "../chunk-YGRQ4Q5P.js";
104
- import "../chunk-VXF5DWS6.js";
105
+ import "../chunk-K25PK5EC.js";
105
106
  export {
106
107
  AgentDirectoryCompilerError,
107
108
  AgentFleetCompilationError,
@@ -118,6 +119,7 @@ export {
118
119
  ManagedAgentMcpDelegateController,
119
120
  ManagedAgentMcpError,
120
121
  PI_PACKAGE_RESOURCE_FILTERS,
122
+ REMOTE_WORKER_EXCLUSIVE_BINARY_CREATE_CAPABILITY,
121
123
  REMOTE_WORKER_PROVIDER,
122
124
  REMOTE_WORKER_RUNTIME_CWD,
123
125
  RUNTIME_FILESYSTEM_BINDING_DUPLICATE_CODE,
@@ -1,8 +1,8 @@
1
1
  import { FastifyInstance, FastifyRequest, FastifyReply, FastifyServerOptions } from 'fastify';
2
2
  import { BwrapResourceLimits } from '@hachej/boring-sandbox/providers/bwrap';
3
3
  import { SandboxProviderV1 } from '@hachej/boring-sandbox/shared';
4
- import { b as Workspace, S as Sandbox } from '../../sandbox-KQiEdz4W.js';
5
- import { R as RemoteWorkerWorkspaceOp, a as RemoteWorkerWorkspaceResult } from '../../middleware-Cq_cYHjJ.js';
4
+ import { b as Workspace, c as Sandbox } from '../../sandbox-BMhut3kh.js';
5
+ import { R as RemoteWorkerWorkspaceOp, a as RemoteWorkerWorkspaceResult } from '../../middleware-CaAEXpi5.js';
6
6
 
7
7
  interface WorkerConfig {
8
8
  workspaceRoot: string;
@@ -22,6 +22,7 @@ declare const WORKER_ERROR_CODES: {
22
22
  readonly VALIDATION_ERROR: "validation_error";
23
23
  readonly INVALID_WORKSPACE_ID: "invalid_workspace_id";
24
24
  readonly NOT_IMPLEMENTED: "not_implemented";
25
+ readonly ALREADY_EXISTS: "REMOTE_WORKER_ALREADY_EXISTS";
25
26
  readonly EXEC_CONCURRENCY_LIMIT: "exec_concurrency_limit";
26
27
  readonly UNSUPPORTED_WORKSPACE_OP: "unsupported_workspace_op";
27
28
  };
@@ -1,14 +1,15 @@
1
1
  import {
2
+ REMOTE_WORKER_EXCLUSIVE_BINARY_CREATE_CAPABILITY,
2
3
  WORKER_INTERNAL_TOKEN_HEADER,
3
4
  constantTimeTokenEqual
4
- } from "../../chunk-XTMY3PWI.js";
5
- import "../../chunk-T37OVD6L.js";
6
- import "../../chunk-3OEDBRKY.js";
5
+ } from "../../chunk-BTYOMR7W.js";
6
+ import "../../chunk-I7KFNGB4.js";
7
+ import "../../chunk-JNEKOVMJ.js";
7
8
  import "../../chunk-4IQ4HHBG.js";
8
9
  import "../../chunk-WSQ5QNIY.js";
9
- import "../../chunk-XCZBICZS.js";
10
+ import "../../chunk-6DRHERVK.js";
10
11
  import "../../chunk-YGRQ4Q5P.js";
11
- import "../../chunk-VXF5DWS6.js";
12
+ import "../../chunk-K25PK5EC.js";
12
13
 
13
14
  // src/server/worker/index.ts
14
15
  import Fastify from "fastify";
@@ -58,6 +59,7 @@ var WORKER_ERROR_CODES = {
58
59
  VALIDATION_ERROR: "validation_error",
59
60
  INVALID_WORKSPACE_ID: "invalid_workspace_id",
60
61
  NOT_IMPLEMENTED: "not_implemented",
62
+ ALREADY_EXISTS: "REMOTE_WORKER_ALREADY_EXISTS",
61
63
  EXEC_CONCURRENCY_LIMIT: "exec_concurrency_limit",
62
64
  UNSUPPORTED_WORKSPACE_OP: "unsupported_workspace_op"
63
65
  };
@@ -154,6 +156,20 @@ async function runWorkspaceOp(workspace, op) {
154
156
  if (!workspace.writeBinaryFile) throw Object.assign(new Error("binary write unsupported"), { statusCode: 501, code: WORKER_ERROR_CODES.NOT_IMPLEMENTED });
155
157
  await workspace.writeBinaryFile(op.path, new Uint8Array(Buffer.from(op.dataBase64, "base64")));
156
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 };
157
173
  case "readFileWithStat":
158
174
  if (!workspace.readFileWithStat) {
159
175
  return { content: await workspace.readFile(op.path), stat: await workspace.stat(op.path) };
@@ -247,7 +263,10 @@ async function registerWorkerRoutes(app, config, runtimeProvider) {
247
263
  }
248
264
  });
249
265
  app.get("/health", async () => ({ ok: true }));
250
- app.get("/internal/health", async () => ({ ok: true }));
266
+ app.get("/internal/health", async () => ({
267
+ ok: true,
268
+ capabilities: [REMOTE_WORKER_EXCLUSIVE_BINARY_CREATE_CAPABILITY]
269
+ }));
251
270
  app.addHook("preHandler", async (request, reply) => {
252
271
  if (request.method === "GET" && request.url === "/health") return;
253
272
  if (!verifyInternalToken(request, reply, config.internalToken)) return reply;