@hachej/boring-agent 0.1.100 → 0.1.103

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-ZOHN72OS.js → chunk-6WKQ4FC4.js} +127 -138
  5. package/dist/{chunk-LSO2AO6Q.js → chunk-7QM22DU7.js} +1 -3
  6. package/dist/{chunk-3OEDBRKY.js → chunk-JNEKOVMJ.js} +1 -1
  7. package/dist/{chunk-VXF5DWS6.js → chunk-K25PK5EC.js} +1 -0
  8. package/dist/chunk-N6THTH7P.js +110 -0
  9. package/dist/{chunk-GRMDMWBW.js → chunk-TW7G33QH.js} +23 -40
  10. package/dist/core/index.d.ts +5 -5
  11. package/dist/core/index.js +1 -1
  12. package/dist/{createHarness-5TEXLUYX.js → createHarness-4Q6DQBRT.js} +2 -2
  13. package/dist/{errors-cNC4HMpV.d.ts → errors-szpcDUFQ.d.ts} +3 -4
  14. package/dist/{file-search-QxnanNjO.d.ts → file-search-BXdSm-Yq.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 +6 -20
  18. package/dist/front/index.js +604 -710
  19. package/dist/{harness-DS8jLKIx.d.ts → harness-erpL2SER.d.ts} +2 -2
  20. package/dist/{lease-D8WC6pQl.d.ts → lease-K-EZhdL-.d.ts} +3 -3
  21. package/dist/{middleware-Cq_cYHjJ.d.ts → middleware-CaAEXpi5.d.ts} +11 -2
  22. package/dist/{piChatEvent-B3ehh9V0.d.ts → piChatEvent-g1nIBh44.d.ts} +14 -16
  23. package/dist/{piChatSessionService-xnv8rcdh.d.ts → piChatSessionService-DugeRHzb.d.ts} +1 -3
  24. package/dist/{sandbox-KQiEdz4W.d.ts → sandbox-BMhut3kh.d.ts} +6 -1
  25. package/dist/server/agent-host/testing/gatewayConformance.d.ts +6 -6
  26. package/dist/server/agent-host/testing/gatewayConformance.js +3 -4
  27. package/dist/server/index.d.ts +24 -35
  28. package/dist/server/index.js +7 -5
  29. package/dist/server/worker/index.d.ts +3 -2
  30. package/dist/server/worker/index.js +25 -6
  31. package/dist/shared/index.d.ts +29 -29
  32. package/dist/shared/index.js +3 -3
  33. package/dist/{types-BPzq-RwN.d.ts → types-BnjMLAd5.d.ts} +14 -6
  34. package/docs/AGENT_GATEWAY_V0.md +3 -4
  35. package/docs/ERROR_CODES.md +1 -0
  36. package/package.json +16 -12
@@ -7,7 +7,7 @@ import {
7
7
  readConfiguredDefaultModel,
8
8
  registerConfiguredModelProviders,
9
9
  withPiHarnessDefaults
10
- } from "./chunk-GRMDMWBW.js";
10
+ } from "./chunk-TW7G33QH.js";
11
11
  import {
12
12
  AGENT_KNOWLEDGE_FILESYSTEM_ID,
13
13
  AgentDefinitionValidationError,
@@ -29,7 +29,7 @@ import {
29
29
  validateAgentDefinition,
30
30
  validateAgentDeployment,
31
31
  validateTool
32
- } from "./chunk-3OEDBRKY.js";
32
+ } from "./chunk-JNEKOVMJ.js";
33
33
  import {
34
34
  safeCapture
35
35
  } from "./chunk-4IQ4HHBG.js";
@@ -41,12 +41,12 @@ import {
41
41
  AgentGatewayErrorCode,
42
42
  extractToolUiMetadata,
43
43
  sanitizeToolUiMetadata2 as sanitizeToolUiMetadata
44
- } from "./chunk-LSO2AO6Q.js";
44
+ } from "./chunk-7QM22DU7.js";
45
45
  import {
46
46
  AgentDefinitionErrorCode,
47
47
  AgentDeploymentErrorCode,
48
48
  ErrorCode
49
- } from "./chunk-VXF5DWS6.js";
49
+ } from "./chunk-K25PK5EC.js";
50
50
 
51
51
  // src/server/sandbox/snapshots/deploymentSnapshot.ts
52
52
  var VERCEL_UV_BIN_DIR = "/workspace/.boring-agent/sdk/uv/bin";
@@ -147,6 +147,7 @@ function createServerFileSearch(workspace, sandbox) {
147
147
  // src/server/sandbox/remote-worker/protocol.ts
148
148
  var REMOTE_WORKER_RUNTIME_CWD = "/workspace";
149
149
  var REMOTE_WORKER_PROVIDER = "remote-worker";
150
+ var REMOTE_WORKER_EXCLUSIVE_BINARY_CREATE_CAPABILITY = "exclusive-binary-create";
150
151
  var WORKER_INTERNAL_TOKEN_HEADER = "x-boring-internal-token";
151
152
  var WORKER_WORKSPACE_ID_HEADER = "x-boring-workspace-id";
152
153
  var WORKER_REQUEST_ID_HEADER = "x-boring-request-id";
@@ -314,6 +315,9 @@ var RemoteWorkerClient = class {
314
315
  headers: makeHeaders({ token: this.token, workspaceId: this.workspaceId, requestId: this.requestId })
315
316
  }, this.requestTimeoutMs);
316
317
  if (!response.ok) throw await parseError(response);
318
+ const body2 = await response.json().catch(() => ({}));
319
+ const capabilities2 = Array.isArray(body2.capabilities) ? body2.capabilities.filter((capability) => capability === "exclusive-binary-create") : void 0;
320
+ return { ok: true, ...capabilities2 ? { capabilities: capabilities2 } : {} };
317
321
  }
318
322
  async workspace(op) {
319
323
  const response = await this.fetchWithTimeout(`${this.baseUrl}/internal/workspaces/${encodeWorkspaceId(this.workspaceId)}/fs`, {
@@ -412,6 +416,7 @@ function constantTimeTokenEqual(a, b) {
412
416
  }
413
417
 
414
418
  // src/server/workspace/createRemoteWorkerWorkspace.ts
419
+ var EEXIST_CODE = "EEXIST";
415
420
  function expectContent(result) {
416
421
  if ("content" in result && typeof result.content === "string") return result.content;
417
422
  throw new Error("remote worker returned invalid file content response");
@@ -492,7 +497,7 @@ function createRemoteWatcher(client) {
492
497
  }
493
498
  };
494
499
  }
495
- function createRemoteWorkerWorkspace(client) {
500
+ function createRemoteWorkerWorkspace(client, supportsExclusiveBinaryCreate = false) {
496
501
  let watcher = null;
497
502
  return {
498
503
  root: REMOTE_WORKER_RUNTIME_CWD,
@@ -514,6 +519,18 @@ function createRemoteWorkerWorkspace(client) {
514
519
  async writeBinaryFile(path, data) {
515
520
  await client.workspace({ op: "writeBinaryFile", path, dataBase64: encodeBytesForWorker(data) });
516
521
  },
522
+ ...supportsExclusiveBinaryCreate ? {
523
+ async createBinaryFile(path, data) {
524
+ try {
525
+ await client.workspace({ op: "createBinaryFile", path, dataBase64: encodeBytesForWorker(data) });
526
+ } catch (error) {
527
+ if (error?.code === ErrorCode.enum.REMOTE_WORKER_ALREADY_EXISTS) {
528
+ throw Object.assign(new Error("EEXIST: file already exists"), { code: EEXIST_CODE });
529
+ }
530
+ throw error;
531
+ }
532
+ }
533
+ } : {},
517
534
  async readFileWithStat(path) {
518
535
  const result = await client.workspace({ op: "readFileWithStat", path });
519
536
  if ("content" in result && "stat" in result) return { content: result.content, stat: result.stat };
@@ -562,9 +579,14 @@ function createRemoteWorkerModeAdapter(opts = {}) {
562
579
  requestId: ctx.requestId,
563
580
  fetchImpl: opts.fetchImpl
564
581
  });
565
- const workspace = createRemoteWorkerWorkspace(client);
582
+ const health = await client.health();
583
+ const workspace = createRemoteWorkerWorkspace(
584
+ client,
585
+ health.capabilities?.includes(
586
+ REMOTE_WORKER_EXCLUSIVE_BINARY_CREATE_CAPABILITY
587
+ ) ?? false
588
+ );
566
589
  const sandbox = createRemoteWorkerSandbox(client);
567
- await sandbox.init?.({ workspace, sessionId: ctx.sessionId });
568
590
  return {
569
591
  runtimeContext: { runtimeCwd: REMOTE_WORKER_RUNTIME_CWD },
570
592
  bash: { kind: "remote" },
@@ -4713,6 +4735,7 @@ function toolInputFromCall(part) {
4713
4735
  }
4714
4736
  function assistantParts(message, messageId) {
4715
4737
  const content = message.content;
4738
+ const assistantAborted = message.stopReason === "aborted";
4716
4739
  if (typeof content === "string") return [{ type: "text", id: `${messageId}:text:0`, text: content }];
4717
4740
  if (!Array.isArray(content)) return [];
4718
4741
  return content.flatMap((part, index) => {
@@ -4732,7 +4755,7 @@ function assistantParts(message, messageId) {
4732
4755
  }
4733
4756
  if (part.type === "toolCall") {
4734
4757
  const toolCallId = optionalString(part.id) ?? `${messageId}:tool:${index}`;
4735
- const state = part.state === "output-error" ? "output-error" : part.state === "output-available" ? "output-available" : "input-available";
4758
+ const state = part.state === "output-error" ? "output-error" : part.state === "output-available" ? "output-available" : part.state === "aborted" || assistantAborted ? "aborted" : "input-available";
4736
4759
  return [
4737
4760
  {
4738
4761
  type: "tool-call",
@@ -7334,11 +7357,7 @@ function toSessionCtx(ctx) {
7334
7357
  if (ctx.sessionAuthority !== "workspace-scope") {
7335
7358
  return { workspaceId: ctx.workspaceId, userId: ctx.authSubject };
7336
7359
  }
7337
- const sessionCtx = { workspaceId: ctx.storageScope ?? ctx.workspaceId };
7338
- if (ctx.runtimeScopeIdentity) {
7339
- Object.assign(sessionCtx, { runtimeScopeIdentity: ctx.runtimeScopeIdentity });
7340
- }
7341
- return sessionCtx;
7360
+ return { workspaceId: ctx.storageScope ?? ctx.workspaceId };
7342
7361
  }
7343
7362
  function liveAttachmentKey(sessionId, messageId, index) {
7344
7363
  return `${JSON.stringify(sessionId)}:${JSON.stringify(messageId)}:${index}`;
@@ -7591,6 +7610,7 @@ function assertUniqueRuntimeFilesystemBindings(bindings) {
7591
7610
  var MUTATION_CAPABILITY = {
7592
7611
  write: "write",
7593
7612
  writeBinary: "write",
7613
+ createBinary: "write",
7594
7614
  delete: "delete",
7595
7615
  mkdir: "create-child"
7596
7616
  };
@@ -7611,6 +7631,7 @@ function intersectRuntimeFilesystemBinding(host, request) {
7611
7631
  ...request.operations,
7612
7632
  write: guarded(request.operations.write?.bind(request.operations), MUTATION_CAPABILITY.write),
7613
7633
  writeBinary: guarded(request.operations.writeBinary?.bind(request.operations), MUTATION_CAPABILITY.writeBinary),
7634
+ createBinary: guarded(request.operations.createBinary?.bind(request.operations), MUTATION_CAPABILITY.createBinary),
7614
7635
  delete: guarded(request.operations.delete?.bind(request.operations), MUTATION_CAPABILITY.delete),
7615
7636
  mkdir: guarded(request.operations.mkdir?.bind(request.operations), MUTATION_CAPABILITY.mkdir),
7616
7637
  move: request.operations.move ? async (args) => {
@@ -7732,18 +7753,7 @@ var AgentSessionInventory = class {
7732
7753
  async resolveSessionRuntime(agentTypeId, scope, claim, sessionId) {
7733
7754
  const resolved = await this.resolveStore(agentTypeId, scope, claim);
7734
7755
  if (!resolved) return void 0;
7735
- try {
7736
- return {
7737
- runtimeScope: resolved.runtimeScope,
7738
- runtimeScopeIdentity: await resolved.store.readRuntimeScopeIdentity(
7739
- { workspaceId: claim.workspaceScopeId },
7740
- sessionId
7741
- )
7742
- };
7743
- } catch (error) {
7744
- if (error instanceof Error && error.message === `Session not found: ${sessionId}`) return void 0;
7745
- throw error;
7746
- }
7756
+ return await resolved.store.has({ workspaceId: claim.workspaceScopeId }, sessionId) ? resolved.runtimeScope : void 0;
7747
7757
  }
7748
7758
  async resolveStore(agentTypeId, scope, claim) {
7749
7759
  const agent = this.compiledById.get(agentTypeId);
@@ -7931,7 +7941,7 @@ async function buildAgentComposition(input) {
7931
7941
  sessionNamespace: configuredNamespace,
7932
7942
  sessionDir: runtimeScope.sessionDir ?? factoryInput.sessionDir
7933
7943
  }) : async (factoryInput) => {
7934
- const { createPiCodingAgentHarness } = await import("./createHarness-5TEXLUYX.js");
7944
+ const { createPiCodingAgentHarness } = await import("./createHarness-4Q6DQBRT.js");
7935
7945
  return createPiCodingAgentHarness({
7936
7946
  ...factoryInput,
7937
7947
  pi,
@@ -7973,7 +7983,6 @@ async function buildAgentComposition(input) {
7973
7983
  tools,
7974
7984
  runtimeBundle,
7975
7985
  readyTracker,
7976
- runtimeScopeIdentity: runtimeScope.identity,
7977
7986
  dispose() {
7978
7987
  disposed ??= service.dispose().finally(() => durableEventStore?.close());
7979
7988
  return disposed;
@@ -8059,13 +8068,12 @@ function gatewayError(dto) {
8059
8068
  function sessionTarget(ref) {
8060
8069
  return { kind: "session", ref };
8061
8070
  }
8062
- function context(claim, requestId, runtimeScopeIdentity) {
8071
+ function context(claim, requestId) {
8063
8072
  return {
8064
8073
  workspaceId: claim.workspaceScopeId,
8065
8074
  storageScope: claim.workspaceScopeId,
8066
8075
  authSubject: claim.authSubjectId,
8067
8076
  sessionAuthority: "workspace-scope",
8068
- ...runtimeScopeIdentity ? { runtimeScopeIdentity } : {},
8069
8077
  requestId
8070
8078
  };
8071
8079
  }
@@ -8094,10 +8102,8 @@ var EmbeddedAgentGateway = class {
8094
8102
  runtime;
8095
8103
  cursorSecret = randomUUID2();
8096
8104
  connections = /* @__PURE__ */ new Set();
8097
- pins = /* @__PURE__ */ new Map();
8098
- unpinnedSessionFallbackPins = /* @__PURE__ */ new Set();
8099
8105
  writerTails = /* @__PURE__ */ new Map();
8100
- sessionRuntimeResolutionObserver;
8106
+ knownSessions = /* @__PURE__ */ new Set();
8101
8107
  closed = false;
8102
8108
  /** Host-owned addressed runtime-capability effect seam. */
8103
8109
  async runHostEffect(input) {
@@ -8132,29 +8138,36 @@ var EmbeddedAgentGateway = class {
8132
8138
  const binding = await this.bindingForSession(scope, claim, ref);
8133
8139
  return { claim, binding };
8134
8140
  }
8135
- /** Side-effect-free reload lookup: validates persisted existence/pin and requires an already-published binding. */
8141
+ /** Side-effect-free reload lookup: validates session access and requires the current binding to be published. */
8136
8142
  async inspectPublishedSessionBinding(scope, ref) {
8137
8143
  const claim = await this.verify(scope);
8138
8144
  if (!this.runtime.compiledById.has(ref.agentTypeId)) {
8139
8145
  throw new AgentGatewayError(AgentGatewayErrorCode.AGENT_SESSION_NOT_FOUND, "session was not found");
8140
8146
  }
8141
- const authority = await this.runtime.resolveSessionRuntime(
8147
+ const sessionKey = agentSessionKey(claim.workspaceScopeId, ref);
8148
+ const persistedRuntime = await this.runtime.resolveSessionRuntime(
8142
8149
  ref.agentTypeId,
8143
8150
  scope,
8144
8151
  claim,
8145
8152
  ref.sessionId
8146
8153
  );
8147
- const cached = this.pins.get(agentSessionKey(claim.workspaceScopeId, ref));
8148
- if (!authority && !cached) {
8154
+ if (!persistedRuntime && !this.knownSessions.has(sessionKey)) {
8149
8155
  throw new AgentGatewayError(AgentGatewayErrorCode.AGENT_SESSION_NOT_FOUND, "session was not found");
8150
8156
  }
8151
- const runtimeScopeIdentity = authority?.runtimeScopeIdentity ?? cached ?? authority?.runtimeScope.identity;
8152
- const binding = this.runtime.findPublishedBinding(
8157
+ const resolved = persistedRuntime ?? await this.runtime.resolveAgentRuntimeScope(
8158
+ ref.agentTypeId,
8159
+ scope,
8160
+ claim,
8161
+ "existing-session",
8162
+ `session:${ref.sessionId}`,
8163
+ ref.sessionId
8164
+ );
8165
+ const binding = this.runtime.findPublishedCurrentBinding(
8153
8166
  ref.agentTypeId,
8154
8167
  claim.workspaceScopeId,
8155
- runtimeScopeIdentity,
8156
- authority?.runtimeScope.physicalBindingIdentity ?? authority?.runtimeScope.identity,
8157
- authority?.runtimeScope.environment.provisioningFingerprint
8168
+ resolved.physicalBindingIdentity ?? resolved.identity,
8169
+ resolved.identity,
8170
+ resolved.environment.provisioningFingerprint
8158
8171
  );
8159
8172
  if (!binding) {
8160
8173
  throw new AgentGatewayError(
@@ -8164,10 +8177,6 @@ var EmbeddedAgentGateway = class {
8164
8177
  }
8165
8178
  return { claim, binding };
8166
8179
  }
8167
- /** Server-only test observer for distinguishing runtime pin resolution paths. */
8168
- setSessionRuntimeResolutionObserverForTesting(observer) {
8169
- this.sessionRuntimeResolutionObserver = observer;
8170
- }
8171
8180
  /** Test-only activity seam used by the shared implementation conformance. */
8172
8181
  setActivityForTesting(workspaceScopeId, ref, activity) {
8173
8182
  this.runtime.activity.set(workspaceScopeId, ref, activity);
@@ -8234,31 +8243,31 @@ var EmbeddedAgentGateway = class {
8234
8243
  return await this.runtime.runBindingOperation(preparedBinding.key, async () => {
8235
8244
  if (input.resumeSessionId) {
8236
8245
  const candidateRef = { agentTypeId: input.agentTypeId, sessionId: input.resumeSessionId };
8237
- const authority = await this.runtime.resolveSessionRuntime(
8246
+ const resolved = await this.runtime.resolveSessionRuntime(
8238
8247
  input.agentTypeId,
8239
8248
  input.scope,
8240
8249
  claim,
8241
8250
  input.resumeSessionId
8242
8251
  ).catch(() => void 0);
8243
- if (authority?.runtimeScopeIdentity === preparedBinding.scope.identity) {
8252
+ if (resolved) {
8244
8253
  const rows = await preparedBinding.composition.service.listSessions?.(
8245
- context(claim, input.requestId, preparedBinding.scope.identity),
8254
+ context(claim, input.requestId),
8246
8255
  { includeId: input.resumeSessionId, includeEmpty: true }
8247
8256
  ) ?? [];
8248
8257
  const candidate = rows.find((row) => row.id === input.resumeSessionId);
8249
8258
  if (candidate?.turnCount === 0) {
8250
- this.pins.set(agentSessionKey(claim.workspaceScopeId, candidateRef), preparedBinding.scope.identity);
8259
+ this.knownSessions.add(agentSessionKey(claim.workspaceScopeId, candidateRef));
8251
8260
  this.runtime.activity.set(claim.workspaceScopeId, candidateRef, "idle");
8252
8261
  return candidateRef;
8253
8262
  }
8254
8263
  }
8255
8264
  }
8256
8265
  const created = await preparedBinding.composition.service.createSession(
8257
- context(claim, input.requestId, preparedBinding.scope.identity),
8266
+ context(claim, input.requestId),
8258
8267
  { title: input.title }
8259
8268
  );
8260
8269
  const ref = { agentTypeId: input.agentTypeId, sessionId: created.id };
8261
- this.pins.set(agentSessionKey(claim.workspaceScopeId, ref), preparedBinding.scope.identity);
8270
+ this.knownSessions.add(agentSessionKey(claim.workspaceScopeId, ref));
8262
8271
  this.runtime.activity.set(claim.workspaceScopeId, ref, "idle");
8263
8272
  return ref;
8264
8273
  });
@@ -8276,13 +8285,13 @@ var EmbeddedAgentGateway = class {
8276
8285
  let state;
8277
8286
  try {
8278
8287
  state = await binding.composition.service.readState(
8279
- context(claim, randomUUID2(), binding.scope.identity),
8288
+ context(claim, randomUUID2()),
8280
8289
  input.ref.sessionId
8281
8290
  );
8282
8291
  } catch {
8283
8292
  throw new AgentGatewayError(AgentGatewayErrorCode.AGENT_SESSION_NOT_FOUND, "session was not found");
8284
8293
  }
8285
- const loaded = await this.loadSummary(binding.composition.service, claim, input.ref, binding.scope.identity);
8294
+ const loaded = await this.loadSummary(binding.composition.service, claim, input.ref);
8286
8295
  const status = this.runtime.activity.get(claim.workspaceScopeId, input.ref);
8287
8296
  return {
8288
8297
  ref: input.ref,
@@ -8294,14 +8303,14 @@ var EmbeddedAgentGateway = class {
8294
8303
  async connectSession(input) {
8295
8304
  const claim = await this.verify(input.scope);
8296
8305
  const binding = await this.bindingForSession(input.scope, claim, input.ref);
8297
- await this.loadSummary(binding.composition.service, claim, input.ref, binding.scope.identity);
8306
+ await this.loadSummary(binding.composition.service, claim, input.ref);
8298
8307
  const queue = new AgentSessionEventQueue();
8299
8308
  const initialCursor = input.cursor ?? (await binding.composition.service.readState(
8300
- context(claim, randomUUID2(), binding.scope.identity),
8309
+ context(claim, randomUUID2()),
8301
8310
  input.ref.sessionId
8302
8311
  )).seq;
8303
8312
  const subscribed = await binding.composition.service.subscribe(
8304
- context(claim, randomUUID2(), binding.scope.identity),
8313
+ context(claim, randomUUID2()),
8305
8314
  input.ref.sessionId,
8306
8315
  initialCursor,
8307
8316
  (event) => {
@@ -8349,7 +8358,7 @@ var EmbeddedAgentGateway = class {
8349
8358
  const currentBinding = await this.bindingForSession(input.scope, current, input.ref);
8350
8359
  return await this.sessionEffect(input.ref, current, "session.interrupt", requestId, {}, async () => {
8351
8360
  const receipt = await currentBinding.composition.service.interrupt(
8352
- context(current, requestId, currentBinding.scope.identity),
8361
+ context(current, requestId),
8353
8362
  input.ref.sessionId,
8354
8363
  {}
8355
8364
  );
@@ -8364,7 +8373,7 @@ var EmbeddedAgentGateway = class {
8364
8373
  const currentBinding = await this.bindingForSession(input.scope, current, input.ref);
8365
8374
  return await this.sessionEffect(input.ref, current, "session.stop", requestId, {}, async () => {
8366
8375
  const receipt = await currentBinding.composition.service.stop(
8367
- context(current, requestId, currentBinding.scope.identity),
8376
+ context(current, requestId),
8368
8377
  input.ref.sessionId,
8369
8378
  {}
8370
8379
  );
@@ -8379,7 +8388,7 @@ var EmbeddedAgentGateway = class {
8379
8388
  clientNonce: clientNonce ?? null,
8380
8389
  clientSeq: clientSeq ?? null
8381
8390
  }, () => currentBinding.composition.service.clearQueue(
8382
- context(current, requestId, currentBinding.scope.identity),
8391
+ context(current, requestId),
8383
8392
  input.ref.sessionId,
8384
8393
  { ...clientNonce ? { clientNonce } : {}, ...clientSeq === void 0 ? {} : { clientSeq } }
8385
8394
  ), {
@@ -8389,7 +8398,6 @@ var EmbeddedAgentGateway = class {
8389
8398
  currentBinding.composition.service,
8390
8399
  current,
8391
8400
  input.ref,
8392
- currentBinding.scope.identity,
8393
8401
  requestId,
8394
8402
  clientNonce,
8395
8403
  clientSeq
@@ -8406,7 +8414,7 @@ var EmbeddedAgentGateway = class {
8406
8414
  const service = binding.composition.service;
8407
8415
  if (command.kind === "prompt") {
8408
8416
  return await this.sessionEffect(ref, claim, "session.prompt", command.requestId, command, async () => {
8409
- const receipt = await service.prompt(context(claim, command.requestId, binding.scope.identity), ref.sessionId, {
8417
+ const receipt = await service.prompt(context(claim, command.requestId), ref.sessionId, {
8410
8418
  message: command.content,
8411
8419
  displayMessage: command.displayContent,
8412
8420
  clientNonce: command.clientNonce,
@@ -8430,7 +8438,7 @@ var EmbeddedAgentGateway = class {
8430
8438
  });
8431
8439
  }
8432
8440
  return await this.sessionEffect(ref, claim, "session.followup", command.requestId, command, async () => {
8433
- const receipt = await service.followUp(context(claim, command.requestId, binding.scope.identity), ref.sessionId, {
8441
+ const receipt = await service.followUp(context(claim, command.requestId), ref.sessionId, {
8434
8442
  message: command.content,
8435
8443
  displayMessage: command.displayContent,
8436
8444
  clientNonce: command.clientNonce,
@@ -8464,7 +8472,7 @@ var EmbeddedAgentGateway = class {
8464
8472
  const binding = await this.bindingForSession(input.scope, claim, input.ref);
8465
8473
  await this.sessionEffect(input.ref, claim, "session.delete", input.requestId, {}, async () => {
8466
8474
  await binding.composition.service.deleteSession(
8467
- context(claim, input.requestId, binding.scope.identity),
8475
+ context(claim, input.requestId),
8468
8476
  input.ref.sessionId
8469
8477
  );
8470
8478
  this.runtime.activity.delete(claim.workspaceScopeId, input.ref);
@@ -8481,18 +8489,17 @@ var EmbeddedAgentGateway = class {
8481
8489
  if (!this.runtime.compiledById.has(ref.agentTypeId)) {
8482
8490
  throw new AgentGatewayError(AgentGatewayErrorCode.AGENT_SESSION_NOT_FOUND, "session was not found");
8483
8491
  }
8484
- const key = agentSessionKey(claim.workspaceScopeId, ref);
8485
- const authority = await this.runtime.resolveSessionRuntime(
8492
+ const sessionKey = agentSessionKey(claim.workspaceScopeId, ref);
8493
+ const persistedRuntime = await this.runtime.resolveSessionRuntime(
8486
8494
  ref.agentTypeId,
8487
8495
  scope,
8488
8496
  claim,
8489
8497
  ref.sessionId
8490
8498
  );
8491
- const cached = this.pins.get(key);
8492
- if (!authority && !cached) {
8499
+ if (!persistedRuntime && !this.knownSessions.has(sessionKey)) {
8493
8500
  throw new AgentGatewayError(AgentGatewayErrorCode.AGENT_SESSION_NOT_FOUND, "session was not found");
8494
8501
  }
8495
- const resolved = authority?.runtimeScope ?? await this.runtime.resolveAgentRuntimeScope(
8502
+ const currentRuntime = persistedRuntime ?? await this.runtime.resolveAgentRuntimeScope(
8496
8503
  ref.agentTypeId,
8497
8504
  scope,
8498
8505
  claim,
@@ -8500,45 +8507,11 @@ var EmbeddedAgentGateway = class {
8500
8507
  `session:${ref.sessionId}`,
8501
8508
  ref.sessionId
8502
8509
  );
8503
- const persistedPin = authority?.runtimeScopeIdentity;
8504
- const pinned = persistedPin ?? cached;
8505
- if (pinned && pinned !== resolved.identity) {
8506
- throw new AgentGatewayError(
8507
- AgentGatewayErrorCode.AGENT_SESSION_RUNTIME_SCOPE_MISMATCH,
8508
- "session is pinned to a different runtime scope"
8509
- );
8510
- }
8511
- const publishedPinned = pinned && typeof this.runtime.findPublishedBinding === "function" ? this.runtime.findPublishedBinding(
8512
- ref.agentTypeId,
8513
- claim.workspaceScopeId,
8514
- pinned
8515
- ) : void 0;
8516
- if (publishedPinned && !this.unpinnedSessionFallbackPins.has(key)) {
8517
- this.sessionRuntimeResolutionObserver?.({
8518
- source: persistedPin ? "persisted-runtime-pin" : "unpinned-session-fallback",
8519
- runtimeScopeIdentity: pinned
8520
- });
8521
- this.pins.set(key, pinned);
8522
- return publishedPinned;
8523
- }
8524
- const runtimeScopeIdentity = pinned ?? resolved.identity;
8525
- this.sessionRuntimeResolutionObserver?.({
8526
- source: persistedPin ? "persisted-runtime-pin" : "unpinned-session-fallback",
8527
- runtimeScopeIdentity
8528
- });
8529
- this.pins.set(key, runtimeScopeIdentity);
8530
- if (!pinned) this.unpinnedSessionFallbackPins.add(key);
8531
- return await this.runtime.resolveBinding(
8532
- ref.agentTypeId,
8533
- scope,
8534
- claim,
8535
- resolved,
8536
- pinned ? "pinned" : "current"
8537
- );
8510
+ return await this.runtime.resolveBinding(ref.agentTypeId, scope, claim, currentRuntime);
8538
8511
  }
8539
- async loadSummary(service, claim, ref, runtimeScopeIdentity) {
8512
+ async loadSummary(service, claim, ref) {
8540
8513
  const list = await service.listSessions?.(
8541
- context(claim, randomUUID2(), runtimeScopeIdentity),
8514
+ context(claim, randomUUID2()),
8542
8515
  { includeId: ref.sessionId, includeEmpty: true }
8543
8516
  ) ?? [];
8544
8517
  const summary = list.find((item) => item.id === ref.sessionId);
@@ -8758,7 +8731,7 @@ var EmbeddedAgentGateway = class {
8758
8731
  async promptAdmission(scope, claim, ref, requestId, requireIdle) {
8759
8732
  const binding = await this.bindingForSession(scope, claim, ref);
8760
8733
  const snapshot = await binding.composition.service.readState(
8761
- context(claim, requestId, binding.scope.identity),
8734
+ context(claim, requestId),
8762
8735
  ref.sessionId
8763
8736
  );
8764
8737
  const admissible = requireIdle ? snapshot.status === "idle" : snapshot.status === "idle" || snapshot.status === "error";
@@ -8769,10 +8742,10 @@ var EmbeddedAgentGateway = class {
8769
8742
  { status: snapshot.status }
8770
8743
  ).toJSON();
8771
8744
  }
8772
- async queueClearAdmission(service, claim, ref, runtimeScopeIdentity, requestId, clientNonce, clientSeq) {
8745
+ async queueClearAdmission(service, claim, ref, requestId, clientNonce, clientSeq) {
8773
8746
  if (clientNonce === void 0 || clientSeq === void 0) return void 0;
8774
8747
  const snapshot = await service.readState(
8775
- context(claim, requestId, runtimeScopeIdentity),
8748
+ context(claim, requestId),
8776
8749
  ref.sessionId
8777
8750
  );
8778
8751
  const byNonce = snapshot.queue.followUps.find((item) => item.clientNonce === clientNonce);
@@ -9596,8 +9569,7 @@ function createAgentHostRuntimeCapabilityProjection(input) {
9596
9569
  requestId: request.id,
9597
9570
  userId: claim.authSubjectId,
9598
9571
  sessionCtx: {
9599
- workspaceId: claim.workspaceScopeId,
9600
- runtimeScopeIdentity: binding.scope.identity
9572
+ workspaceId: claim.workspaceScopeId
9601
9573
  },
9602
9574
  ...typeof user?.email === "string" && user.email.trim() ? { userEmail: user.email.trim() } : {},
9603
9575
  userEmailVerified: user?.emailVerified === true
@@ -9659,8 +9631,7 @@ function createAgentHostRuntimeCapabilityProjection(input) {
9659
9631
  requestId,
9660
9632
  userId: scope.authSubjectId,
9661
9633
  sessionCtx: {
9662
- workspaceId: scope.workspaceScopeId,
9663
- runtimeScopeIdentity: binding.scope.identity
9634
+ workspaceId: scope.workspaceScopeId
9664
9635
  }
9665
9636
  });
9666
9637
  return { ok: true, sessionId, name };
@@ -9817,7 +9788,7 @@ function body(schema, request, reply) {
9817
9788
  function statusFor(error) {
9818
9789
  if (error.code === AgentGatewayErrorCode.AGENT_SCOPE_DENIED) return 403;
9819
9790
  if (error.code === AgentGatewayErrorCode.AGENT_TYPE_UNKNOWN || error.code === AgentGatewayErrorCode.AGENT_SESSION_NOT_FOUND) return 404;
9820
- if (error.code === AgentGatewayErrorCode.AGENT_REQUEST_CONFLICT || error.code === AgentGatewayErrorCode.AGENT_REQUEST_IN_PROGRESS || error.code === AgentGatewayErrorCode.AGENT_REQUEST_OUTCOME_UNKNOWN || error.code === AgentGatewayErrorCode.AGENT_RUNTIME_RESTART_REQUIRED || error.code === AgentGatewayErrorCode.AGENT_COMMAND_INVALID_STATE || error.code === AgentGatewayErrorCode.AGENT_SESSION_RUNTIME_SCOPE_MISMATCH) return 409;
9791
+ if (error.code === AgentGatewayErrorCode.AGENT_REQUEST_CONFLICT || error.code === AgentGatewayErrorCode.AGENT_REQUEST_IN_PROGRESS || error.code === AgentGatewayErrorCode.AGENT_REQUEST_OUTCOME_UNKNOWN || error.code === AgentGatewayErrorCode.AGENT_RUNTIME_RESTART_REQUIRED || error.code === AgentGatewayErrorCode.AGENT_COMMAND_INVALID_STATE) return 409;
9821
9792
  if (error.code === AgentGatewayErrorCode.AGENT_GATEWAY_CLOSED) return 503;
9822
9793
  return 400;
9823
9794
  }
@@ -10117,7 +10088,7 @@ function parseWithSchema(schema, value, reply, scope) {
10117
10088
  function statusForGatewayError(code) {
10118
10089
  if (code === AgentGatewayErrorCode.AGENT_SCOPE_DENIED) return 403;
10119
10090
  if (code === AgentGatewayErrorCode.AGENT_SESSION_NOT_FOUND || code === AgentGatewayErrorCode.AGENT_TYPE_UNKNOWN) return 404;
10120
- if (code === AgentGatewayErrorCode.AGENT_REQUEST_CONFLICT || code === AgentGatewayErrorCode.AGENT_REQUEST_IN_PROGRESS || code === AgentGatewayErrorCode.AGENT_REQUEST_OUTCOME_UNKNOWN || code === AgentGatewayErrorCode.AGENT_RUNTIME_RESTART_REQUIRED || code === AgentGatewayErrorCode.AGENT_COMMAND_INVALID_STATE || code === AgentGatewayErrorCode.AGENT_SESSION_RUNTIME_SCOPE_MISMATCH || code.includes("CURSOR") || code.includes("REPLAY")) return 409;
10091
+ if (code === AgentGatewayErrorCode.AGENT_REQUEST_CONFLICT || code === AgentGatewayErrorCode.AGENT_REQUEST_IN_PROGRESS || code === AgentGatewayErrorCode.AGENT_REQUEST_OUTCOME_UNKNOWN || code === AgentGatewayErrorCode.AGENT_RUNTIME_RESTART_REQUIRED || code === AgentGatewayErrorCode.AGENT_COMMAND_INVALID_STATE || code.includes("CURSOR") || code.includes("REPLAY")) return 409;
10121
10092
  if (code === AgentGatewayErrorCode.AGENT_GATEWAY_CLOSED || code === AgentGatewayErrorCode.AGENT_SHARED_ENVIRONMENT_UNAVAILABLE) return 503;
10122
10093
  return 400;
10123
10094
  }
@@ -11312,7 +11283,6 @@ function createRuntime(options, compiledAgents) {
11312
11283
  );
11313
11284
  const activity = new AgentSessionActivityIndex();
11314
11285
  const bindings = /* @__PURE__ */ new Map();
11315
- const publishedBindings = /* @__PURE__ */ new Map();
11316
11286
  const publishedCurrentBindings = /* @__PURE__ */ new Map();
11317
11287
  const currentBindingReservations = /* @__PURE__ */ new Map();
11318
11288
  const nextBindingGeneration = /* @__PURE__ */ new Map();
@@ -11395,20 +11365,12 @@ function createRuntime(options, compiledAgents) {
11395
11365
  },
11396
11366
  async resolveSessionRuntime(agentTypeId, scope, claim, sessionId) {
11397
11367
  runtime.assertOpen();
11398
- try {
11399
- const authority = await inventory.resolveSessionRuntime(agentTypeId, scope, claim, sessionId);
11400
- if (!authority) return void 0;
11401
- validateResolvedRuntimeScope(authority.runtimeScope);
11402
- return authority;
11403
- } catch {
11404
- throw new AgentGatewayError(
11405
- AgentGatewayErrorCode.AGENT_SESSION_RUNTIME_SCOPE_MISMATCH,
11406
- "session runtime scope metadata is unavailable"
11407
- );
11408
- }
11368
+ const resolved = await inventory.resolveSessionRuntime(agentTypeId, scope, claim, sessionId);
11369
+ if (resolved) validateResolvedRuntimeScope(resolved);
11370
+ return resolved;
11409
11371
  },
11410
11372
  resolveAgentRuntimeScope,
11411
- async resolveBinding(agentTypeId, scope, claim, resolvedRuntimeScope, purpose = "current") {
11373
+ async resolveBinding(agentTypeId, scope, claim, resolvedRuntimeScope) {
11412
11374
  runtime.assertOpen();
11413
11375
  const agent = compiledById.get(agentTypeId);
11414
11376
  if (!agent) throw new AgentGatewayError(AgentGatewayErrorCode.AGENT_TYPE_UNKNOWN, "agent type is not available");
@@ -11429,7 +11391,7 @@ function createRuntime(options, compiledAgents) {
11429
11391
  ]);
11430
11392
  const physicalBindingIdentity = resolved.physicalBindingIdentity ?? resolved.identity;
11431
11393
  const currentKey = JSON.stringify([agentTypeId, claim.workspaceScopeId, physicalBindingIdentity]);
11432
- const useCanonicalCurrent = purpose === "current" && options.resolveAuthorizedAgentRuntimeScope !== void 0;
11394
+ const useCanonicalCurrent = options.resolveAuthorizedAgentRuntimeScope !== void 0;
11433
11395
  if (useCanonicalCurrent) {
11434
11396
  const current = publishedCurrentBindings.get(currentKey);
11435
11397
  if (current) return current;
@@ -11481,7 +11443,6 @@ function createRuntime(options, compiledAgents) {
11481
11443
  await disposeBinding(binding2);
11482
11444
  throw new AgentGatewayError(AgentGatewayErrorCode.AGENT_GATEWAY_CLOSED, "agent host is closing");
11483
11445
  }
11484
- publishedBindings.set(key, binding2);
11485
11446
  if (useCanonicalCurrent && currentBindingReservations.get(currentKey) === key && !publishedCurrentBindings.has(currentKey)) {
11486
11447
  publishedCurrentBindings.set(currentKey, binding2);
11487
11448
  currentBindingReservations.delete(currentKey);
@@ -11514,18 +11475,14 @@ function createRuntime(options, compiledAgents) {
11514
11475
  }
11515
11476
  return binding;
11516
11477
  },
11517
- findPublishedBinding(agentTypeId, workspaceScopeId, runtimeScopeIdentity, physicalBindingIdentity, provisioningFingerprint) {
11518
- const matches = [...publishedBindings.values()].filter((binding) => binding.agentTypeId === agentTypeId && binding.workspaceScopeId === workspaceScopeId && (!runtimeScopeIdentity || binding.scope.identity === runtimeScopeIdentity) && (!physicalBindingIdentity || (binding.scope.physicalBindingIdentity ?? binding.scope.identity) === physicalBindingIdentity) && (!provisioningFingerprint || binding.scope.environment.provisioningFingerprint === provisioningFingerprint));
11519
- return matches.length === 1 ? matches[0] : void 0;
11520
- },
11521
- findPublishedCurrentBinding(agentTypeId, workspaceScopeId, physicalBindingIdentity, runtimeScopeIdentity, provisioningFingerprint) {
11478
+ findPublishedCurrentBinding(agentTypeId, workspaceScopeId, physicalBindingIdentity, bindingIdentity, provisioningFingerprint) {
11522
11479
  const exact = publishedCurrentBindings.get(JSON.stringify([
11523
11480
  agentTypeId,
11524
11481
  workspaceScopeId,
11525
11482
  physicalBindingIdentity
11526
11483
  ]));
11527
11484
  if (exact) return exact;
11528
- const matches = [...publishedCurrentBindings.values()].filter((binding) => binding.agentTypeId === agentTypeId && binding.workspaceScopeId === workspaceScopeId && (!runtimeScopeIdentity || binding.scope.identity === runtimeScopeIdentity) && (!provisioningFingerprint || binding.scope.environment.provisioningFingerprint === provisioningFingerprint));
11485
+ const matches = [...publishedCurrentBindings.values()].filter((binding) => binding.agentTypeId === agentTypeId && binding.workspaceScopeId === workspaceScopeId && (!bindingIdentity || binding.scope.identity === bindingIdentity) && (!provisioningFingerprint || binding.scope.environment.provisioningFingerprint === provisioningFingerprint));
11529
11486
  return matches.length === 1 ? matches[0] : void 0;
11530
11487
  },
11531
11488
  startDrain() {
@@ -11634,7 +11591,6 @@ function createRuntime(options, compiledAgents) {
11634
11591
  }
11635
11592
  const resolvedBindings = await Promise.allSettled([...bindings.values()]);
11636
11593
  bindings.clear();
11637
- publishedBindings.clear();
11638
11594
  publishedCurrentBindings.clear();
11639
11595
  nextBindingGeneration.clear();
11640
11596
  currentBindingReservations.clear();
@@ -12138,7 +12094,7 @@ import { lstat as lstat4, open as open2, opendir, realpath as realpath5, stat as
12138
12094
  import { homedir as homedir2 } from "node:os";
12139
12095
  import { dirname as dirname8, isAbsolute as isAbsolute7, join as join9, parse, relative as relative9, resolve as resolve8, sep as sep8 } from "node:path";
12140
12096
  import { fileURLToPath as fileURLToPath7 } from "node:url";
12141
- import { DefaultPackageManager as DefaultPackageManager2, getAgentDir as getAgentDir2 } from "@mariozechner/pi-coding-agent";
12097
+ import { DefaultPackageManager as DefaultPackageManager2, getAgentDir as getAgentDir2, loadProjectContextFiles } from "@mariozechner/pi-coding-agent";
12142
12098
  var DEFAULT_PI_RESOURCE_DIGEST_LIMITS = Object.freeze({
12143
12099
  maxDepth: 32,
12144
12100
  maxFiles: 1e4,
@@ -12150,11 +12106,13 @@ function createPiResourceDigestInput(input) {
12150
12106
  const piAgentDir = resolvePiPath(input.piAgentDir ?? getAgentDir2(), process.cwd());
12151
12107
  const piUserHome = resolvePiPath(input.piUserHome ?? homedir2(), process.cwd());
12152
12108
  const noSkills = input.noSkills ?? true;
12109
+ const noContextFiles = input.noContextFiles ?? true;
12153
12110
  return {
12154
12111
  piCwd,
12155
12112
  piAgentDir,
12156
12113
  piUserHome,
12157
12114
  noSkills,
12115
+ noContextFiles,
12158
12116
  promptParts: input.resourceSets.flatMap((set) => set.promptParts ?? []),
12159
12117
  additionalSkillPaths: uniqueStrings(input.resourceSets.flatMap((set) => set.additionalSkillPaths ?? [])),
12160
12118
  packages: compactPiPackages(input.resourceSets.flatMap((set) => set.packages ?? [])),
@@ -12168,7 +12126,7 @@ function createPiResourceDigestInput(input) {
12168
12126
  ...input.limits ? { limits: input.limits } : {}
12169
12127
  };
12170
12128
  }
12171
- var FORMAT_VERSION = "boring-pi-resource-digest-v4";
12129
+ var FORMAT_VERSION = "boring-pi-resource-digest-v5";
12172
12130
  var EXCLUDED_DIRECTORIES = /* @__PURE__ */ new Set([".git", "node_modules"]);
12173
12131
  var EXCLUDED_FILES = /* @__PURE__ */ new Set([".boring-signature.json"]);
12174
12132
  async function digestPiResourceInputs(input) {
@@ -12177,6 +12135,7 @@ async function digestPiResourceInputs(input) {
12177
12135
  const piAgentDir = resolvePiPath(input.piAgentDir, process.cwd());
12178
12136
  const piUserHome = resolvePiPath(input.piUserHome, process.cwd());
12179
12137
  const projectSettingsDir = join9(piCwd, ".pi");
12138
+ const noContextFiles = input.noContextFiles ?? true;
12180
12139
  const authorizedRoots = [...new Set(input.authorizedRoots.map((path) => resolvePiPath(path, piCwd)))];
12181
12140
  if (authorizedRoots.length === 0) {
12182
12141
  throw stableError(ErrorCode.enum.CONFIG_INVALID, 400, "Pi resource digest requires at least one independently authorized root");
@@ -12188,8 +12147,28 @@ async function digestPiResourceInputs(input) {
12188
12147
  frameString(hash, "project-settings-dir", projectSettingsDir);
12189
12148
  frameString(hash, "user-agent-dir", piAgentDir);
12190
12149
  frameString(hash, "user-home", piUserHome);
12150
+ frameString(hash, "context-policy", noContextFiles ? "sealed" : "ambient");
12191
12151
  const promptText = (input.promptParts ?? []).map((part) => part?.trim()).filter((part) => Boolean(part)).join("\n\n");
12192
12152
  frameString(hash, "prompt", promptText);
12153
+ if (!noContextFiles) {
12154
+ const contextFiles = loadProjectContextFiles({ cwd: piCwd, agentDir: piAgentDir });
12155
+ for (const contextFile of contextFiles) {
12156
+ const bytes = Buffer.byteLength(contextFile.content);
12157
+ state.nodes += 1;
12158
+ if (state.nodes > state.limits.maxFiles) {
12159
+ throw limitError(`Pi resource tree exceeds maximum node count ${state.limits.maxFiles}`);
12160
+ }
12161
+ if (bytes > state.limits.maxFileBytes) {
12162
+ throw limitError(`Pi context file exceeds maximum bytes ${state.limits.maxFileBytes}: ${contextFile.path}`);
12163
+ }
12164
+ if (state.bytes + bytes > state.limits.maxTotalBytes) {
12165
+ throw limitError(`Pi resource tree exceeds maximum total bytes ${state.limits.maxTotalBytes}`);
12166
+ }
12167
+ frameString(hash, "context-path", contextFile.path);
12168
+ frameString(hash, "context-content", contextFile.content);
12169
+ state.bytes += bytes;
12170
+ }
12171
+ }
12193
12172
  await hashResourceCollection(state, piCwd, "settings", [
12194
12173
  join9(projectSettingsDir, "settings.json"),
12195
12174
  join9(piAgentDir, "settings.json")
@@ -12633,6 +12612,7 @@ async function createStandaloneAgentHostApp(options = {}) {
12633
12612
  return createPiResourceDigestInput({
12634
12613
  piCwd: workspaceRoot,
12635
12614
  noSkills: pi.noSkills,
12615
+ noContextFiles: pi.noContextFiles,
12636
12616
  resourceSets: [{
12637
12617
  promptParts: [
12638
12618
  options.systemPromptAppend,
@@ -13123,6 +13103,14 @@ function createUserFilesystemBinding(workspace, policy, resolvePolicyPath) {
13123
13103
  const stat7 = await workspace.stat(target);
13124
13104
  return { mtimeMs: stat7.kind === "file" ? stat7.mtimeMs : void 0 };
13125
13105
  },
13106
+ ...workspace.createBinaryFile ? {
13107
+ async createBinary({ path, content }) {
13108
+ await requireCapability(path, "write");
13109
+ const target = workspacePath(workspace, path);
13110
+ await workspace.createBinaryFile(target, content);
13111
+ return {};
13112
+ }
13113
+ } : {},
13126
13114
  async delete({ path }) {
13127
13115
  await requireCapability(path, "delete");
13128
13116
  await workspace.unlink(workspacePath(workspace, path));
@@ -13508,6 +13496,7 @@ export {
13508
13496
  resolveWorkspaceRoot,
13509
13497
  REMOTE_WORKER_RUNTIME_CWD,
13510
13498
  REMOTE_WORKER_PROVIDER,
13499
+ REMOTE_WORKER_EXCLUSIVE_BINARY_CREATE_CAPABILITY,
13511
13500
  WORKER_INTERNAL_TOKEN_HEADER,
13512
13501
  WORKER_WORKSPACE_ID_HEADER,
13513
13502
  WORKER_REQUEST_ID_HEADER,