@hachej/boring-agent 0.1.84 → 0.1.86

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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ErrorCode
3
- } from "./chunk-PG2WOJ22.js";
3
+ } from "./chunk-HDIRWHJB.js";
4
4
 
5
5
  // src/shared/tool-ui.ts
6
6
  function isRecord(value) {
@@ -73,6 +73,9 @@ var ErrorCode = z.enum([
73
73
  "PROVISIONING_UV_BOOTSTRAP_FAILED",
74
74
  "PROVISIONING_UV_INSTALL_FAILED",
75
75
  "PROVISIONING_ARTIFACT_FAILED",
76
+ // Lane W same-workspace share deep-link (AR1-003)
77
+ "AR1_SHARE_NOT_FOUND",
78
+ "AR1_SHARE_TOMBSTONED",
76
79
  // Internal
77
80
  "ERR_NOT_IMPLEMENTED_UNTIL_T1",
78
81
  "INTERNAL_ERROR"
@@ -90,7 +93,8 @@ var AgentConsumptionErrorCode = z.enum([
90
93
  "AGENT_CONSUMPTION_INVALID_TRANSITION",
91
94
  "AGENT_CONSUMPTION_CYCLE_DETECTED",
92
95
  "AGENT_CONSUMPTION_DEPTH_EXCEEDED",
93
- "AGENT_CONSUMPTION_SCHEMA_MISMATCH"
96
+ "AGENT_CONSUMPTION_SCHEMA_MISMATCH",
97
+ "AGENT_CONSUMPTION_LEGACY_ARTIFACT_REJECTED"
94
98
  ]);
95
99
  var ApiErrorPayloadSchema = z.object({
96
100
  code: ErrorCode,
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-WSQ5QNIY.js";
4
4
  import {
5
5
  ErrorCode
6
- } from "./chunk-PG2WOJ22.js";
6
+ } from "./chunk-HDIRWHJB.js";
7
7
 
8
8
  // src/core/piChatSessionService.ts
9
9
  var AgentEffectAdmissionError = class extends Error {
@@ -3,19 +3,21 @@ import {
3
3
  AgentDeploymentValidationError,
4
4
  OpaqueRefSchema,
5
5
  Sha256DigestSchema,
6
+ ShareEntryErrorCode,
6
7
  canonicalStringify,
7
8
  createAgentAssetDigest,
8
9
  createAgentDefinitionDigest,
9
10
  createAgentDeploymentDigest,
11
+ resolveShareEntry,
10
12
  sha256Bytes,
11
13
  validateAgentDefinition,
12
14
  validateAgentDeployment,
13
15
  validateTool
14
- } from "./chunk-WODTQBXR.js";
16
+ } from "./chunk-YONTHCD7.js";
15
17
  import {
16
18
  AgentEffectAdmissionError,
17
19
  createAgentRuntimeBridge
18
- } from "./chunk-2XADUCX7.js";
20
+ } from "./chunk-LYBTHR7J.js";
19
21
  import {
20
22
  sessionStreamPath
21
23
  } from "./chunk-WSQ5QNIY.js";
@@ -30,7 +32,7 @@ import {
30
32
  StopReceiptSchema,
31
33
  extractToolUiMetadata,
32
34
  sanitizeToolUiMetadata2 as sanitizeToolUiMetadata
33
- } from "./chunk-DC3S7SZG.js";
35
+ } from "./chunk-6O5ADR57.js";
34
36
  import {
35
37
  createLogger,
36
38
  createPiCodingAgentHarness,
@@ -41,7 +43,7 @@ import {
41
43
  registerConfiguredModelProviders,
42
44
  setEnvDefault,
43
45
  withPiHarnessDefaults
44
- } from "./chunk-5NAN3TAR.js";
46
+ } from "./chunk-ZUDWQAAB.js";
45
47
  import {
46
48
  safeCapture
47
49
  } from "./chunk-AQBXNPMD.js";
@@ -49,7 +51,7 @@ import {
49
51
  AgentDefinitionErrorCode,
50
52
  AgentDeploymentErrorCode,
51
53
  ErrorCode
52
- } from "./chunk-PG2WOJ22.js";
54
+ } from "./chunk-HDIRWHJB.js";
53
55
 
54
56
  // src/server/sandbox/direct/createDirectSandbox.ts
55
57
  import { spawn } from "child_process";
@@ -1809,6 +1811,14 @@ async function prepareVercelDeploymentSnapshot(opts) {
1809
1811
  });
1810
1812
  }
1811
1813
 
1814
+ // src/server/config/workspaceRoot.ts
1815
+ var WORKSPACE_ROOT_ENV = "BORING_AGENT_WORKSPACE_ROOT";
1816
+ function resolveWorkspaceRoot(defaultRoot = process.cwd()) {
1817
+ const configured = process.env[WORKSPACE_ROOT_ENV]?.trim();
1818
+ if (!configured) return defaultRoot;
1819
+ return configured;
1820
+ }
1821
+
1812
1822
  // src/server/runtime/createServerFileSearch.ts
1813
1823
  var DEFAULT_LIMIT = 500;
1814
1824
  var MAX_LIMIT = 5e3;
@@ -7310,6 +7320,19 @@ var PiChatMeteringCoordinator = class {
7310
7320
  if (run2) this.release(run2, "run-rejected");
7311
7321
  this.pruneSession(stateKey, state);
7312
7322
  }
7323
+ /**
7324
+ * Mark the currently-active run as voluntarily user-stopped (the /stop button),
7325
+ * so its terminal accounting RELEASES the hold instead of charging the fallback.
7326
+ * Must be called before the abort so the flag is set when the native aborted
7327
+ * agent-end is observed. Runs with real usage recorded before the stop still
7328
+ * settle that usage; only the unused remainder of the hold is released. No-op if
7329
+ * there is no active run (e.g. the stop landed before agent-start — releasePending
7330
+ * handles that case).
7331
+ */
7332
+ markActiveStopped(sessionId) {
7333
+ const active = this.sessions.get(sessionId)?.active;
7334
+ if (active && !active.terminal) active.userStopped = true;
7335
+ }
7313
7336
  /**
7314
7337
  * Release prompt runs reserved but not yet bound to an agent-start —
7315
7338
  * e.g. a stop/interrupt landing in the window between acceptance and the
@@ -7495,6 +7518,7 @@ var PiChatMeteringCoordinator = class {
7495
7518
  recordedMessageIds: /* @__PURE__ */ new Set(),
7496
7519
  lastIdlessUsageKey: void 0,
7497
7520
  usageWriteFailed: false,
7521
+ userStopped: false,
7498
7522
  reservation: Promise.resolve(),
7499
7523
  terminal: false,
7500
7524
  ops: Promise.resolve()
@@ -7536,7 +7560,7 @@ var PiChatMeteringCoordinator = class {
7536
7560
  if (run2.billableUsageCount > 0) {
7537
7561
  return this.sink.settleRun({ ...run2.scope, reservationId: run2.reservationId, status });
7538
7562
  }
7539
- const didPaidWork = status === "ok";
7563
+ const didPaidWork = status === "ok" && !run2.userStopped;
7540
7564
  if (didPaidWork) {
7541
7565
  return this.sink.releaseRun({ ...run2.scope, reservationId: run2.reservationId, reason: "fallback-hold-charge" });
7542
7566
  }
@@ -7988,6 +8012,7 @@ var HarnessPiChatService = class {
7988
8012
  const sessionKey = this.sessionKey(ctx, sessionId);
7989
8013
  const adapter = await this.getAdapter(ctx, sessionId, "");
7990
8014
  const clearedQueue = this.clearAllFollowUps(adapter, sessionId, sessionKey);
8015
+ this.metering?.markActiveStopped(sessionKey);
7991
8016
  this.metering?.releaseQueued(sessionKey);
7992
8017
  this.metering?.releasePending(sessionKey);
7993
8018
  await adapter.abort();
@@ -8486,7 +8511,7 @@ function createAgentRuntimeBridge2(config, options = {}) {
8486
8511
  });
8487
8512
  }
8488
8513
  async function createRuntime(config, options) {
8489
- const harnessFactory = config.harnessFactory ?? (await import("./createHarness-TGBJZISM.js")).createPiCodingAgentHarness;
8514
+ const harnessFactory = config.harnessFactory ?? (await import("./createHarness-MJ5GEL6J.js")).createPiCodingAgentHarness;
8490
8515
  const harnessInput = {
8491
8516
  tools: config.tools ?? [],
8492
8517
  cwd: config.workdir ?? DEFAULT_WORKDIR,
@@ -9498,6 +9523,166 @@ function sameSessionCtx(a, b) {
9498
9523
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
9499
9524
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
9500
9525
  import { z as z2 } from "zod";
9526
+
9527
+ // src/server/mcp/shareEntryResources.ts
9528
+ import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
9529
+ var MAX_SHARE_READ_BYTES = 256 * 1024;
9530
+ var SHARE_RESOURCE_URI_TEMPLATE = "share:///{id}";
9531
+ var strictUtf8Decoder2 = new TextDecoder("utf-8", { fatal: true });
9532
+ function shareResourceUri(id) {
9533
+ return `share:///${encodeURIComponent(id)}`;
9534
+ }
9535
+ function registerShareEntryResources(server, options) {
9536
+ const template = new ResourceTemplate(SHARE_RESOURCE_URI_TEMPLATE, {
9537
+ list: async (extra) => listShareResources(options, requestContextFromResourceExtra(extra))
9538
+ });
9539
+ const readCallback = async (uri, variables, extra) => readShareResource(options, variables.id, requestContextFromResourceExtra(extra));
9540
+ server.registerResource(
9541
+ "share",
9542
+ template,
9543
+ {
9544
+ title: "Lane W share entry",
9545
+ description: "Same-workspace shareable file reference (AR1). Resolves live, never a blob snapshot."
9546
+ },
9547
+ readCallback
9548
+ );
9549
+ }
9550
+ function requestContextFromResourceExtra(extra) {
9551
+ return {
9552
+ sessionId: extra?.sessionId,
9553
+ authInfo: extra?.authInfo
9554
+ };
9555
+ }
9556
+ async function listShareResources(options, request) {
9557
+ const ctx = await options.resolveSessionCtx(request);
9558
+ if (!ctx.workspaceId) return { resources: [] };
9559
+ const entries = await options.store.list(ctx.workspaceId);
9560
+ return {
9561
+ resources: entries.map((entry) => ({
9562
+ uri: shareResourceUri(entry.id),
9563
+ name: entry.id
9564
+ }))
9565
+ };
9566
+ }
9567
+ async function readShareResource(options, rawId, request) {
9568
+ const id = typeof rawId === "string" ? rawId : Array.isArray(rawId) ? rawId[0] : void 0;
9569
+ if (!id) return notFoundResult(shareResourceUri(""));
9570
+ const uri = shareResourceUri(id);
9571
+ const ctx = await options.resolveSessionCtx(request);
9572
+ if (!ctx.workspaceId) return notFoundResult(uri);
9573
+ const entry = await options.store.get(id);
9574
+ if (!entry || entry.workspaceId !== ctx.workspaceId) {
9575
+ return notFoundResult(uri);
9576
+ }
9577
+ const workspace = await options.resolveWorkspace(ctx);
9578
+ const resolution = await resolveShareEntry(options.store, id, workspace);
9579
+ if (resolution.status === "not_found") return notFoundResult(uri);
9580
+ if (resolution.status === "tombstoned") {
9581
+ return tombstoneResult(uri, resolution.tombstone);
9582
+ }
9583
+ return readShareEntryContents(uri, resolution.entry, workspace);
9584
+ }
9585
+ function notFoundResult(uri) {
9586
+ return {
9587
+ contents: [
9588
+ {
9589
+ uri,
9590
+ mimeType: "application/json",
9591
+ text: JSON.stringify({
9592
+ status: "not_found",
9593
+ error: { code: ErrorCode.enum.AR1_SHARE_NOT_FOUND, message: "share not found" }
9594
+ })
9595
+ }
9596
+ ]
9597
+ };
9598
+ }
9599
+ function tombstoneResult(uri, tombstone) {
9600
+ return {
9601
+ contents: [
9602
+ {
9603
+ uri,
9604
+ mimeType: "application/json",
9605
+ text: JSON.stringify({
9606
+ status: "tombstoned",
9607
+ error: { code: ErrorCode.enum.AR1_SHARE_TOMBSTONED, message: "share target is gone" },
9608
+ id: tombstone.id,
9609
+ workspaceId: tombstone.workspaceId,
9610
+ provenance: tombstone.provenance
9611
+ })
9612
+ }
9613
+ ]
9614
+ };
9615
+ }
9616
+ async function readShareEntryContents(uri, entry, workspace) {
9617
+ const before = await statShareTarget(workspace, entry.path);
9618
+ assertShareTargetStat(before);
9619
+ assertWithinCap(before.size);
9620
+ if (!workspace.readBinaryFile) {
9621
+ throw new ManagedAgentMcpError(
9622
+ ErrorCode.enum.MCP_AGENT_ARTIFACT_UNAVAILABLE,
9623
+ "share target bytes are unavailable through the authorized workspace"
9624
+ );
9625
+ }
9626
+ const bytes = await workspace.readBinaryFile(entry.path);
9627
+ const after = await statShareTarget(workspace, entry.path);
9628
+ assertShareTargetStat(after);
9629
+ if (!sameStat2(before, after) || bytes.byteLength !== before.size) {
9630
+ throw new ManagedAgentMcpError(ErrorCode.enum.MCP_AGENT_ARTIFACT_UNAVAILABLE, "share target changed while it was being read");
9631
+ }
9632
+ assertWithinCap(bytes.byteLength);
9633
+ const text = decodeUtf83(bytes);
9634
+ const digest = await sha256Bytes(bytes);
9635
+ return {
9636
+ contents: [
9637
+ {
9638
+ uri,
9639
+ mimeType: "text/plain",
9640
+ text,
9641
+ _meta: {
9642
+ status: "ok",
9643
+ digest,
9644
+ byteSize: bytes.byteLength,
9645
+ provenance: entry.provenance
9646
+ }
9647
+ }
9648
+ ]
9649
+ };
9650
+ }
9651
+ async function statShareTarget(workspace, path4) {
9652
+ try {
9653
+ return await workspace.stat(path4);
9654
+ } catch {
9655
+ throw new ManagedAgentMcpError(ErrorCode.enum.MCP_AGENT_ARTIFACT_UNAVAILABLE, "share target is unavailable");
9656
+ }
9657
+ }
9658
+ function assertShareTargetStat(stat13) {
9659
+ if (stat13.kind !== "file") {
9660
+ throw new ManagedAgentMcpError(ErrorCode.enum.MCP_AGENT_ARTIFACT_INVALID, "share target must be a file");
9661
+ }
9662
+ if (!Number.isFinite(stat13.size) || stat13.size < 0) {
9663
+ throw new ManagedAgentMcpError(ErrorCode.enum.MCP_AGENT_ARTIFACT_INVALID, "share target size is invalid");
9664
+ }
9665
+ }
9666
+ function assertWithinCap(byteSize) {
9667
+ if (byteSize > MAX_SHARE_READ_BYTES) {
9668
+ throw new ManagedAgentMcpError(
9669
+ ErrorCode.enum.MCP_AGENT_ARTIFACT_TOO_LARGE,
9670
+ `share target must be ${MAX_SHARE_READ_BYTES} bytes or fewer`
9671
+ );
9672
+ }
9673
+ }
9674
+ function sameStat2(left, right) {
9675
+ return left.kind === right.kind && left.size === right.size && left.mtimeMs === right.mtimeMs;
9676
+ }
9677
+ function decodeUtf83(bytes) {
9678
+ try {
9679
+ return strictUtf8Decoder2.decode(bytes);
9680
+ } catch {
9681
+ throw new ManagedAgentMcpError(ErrorCode.enum.MCP_AGENT_ARTIFACT_INVALID, "share target must be well-formed UTF-8");
9682
+ }
9683
+ }
9684
+
9685
+ // src/server/mcp/managedAgentMcpServer.ts
9501
9686
  var DEFAULT_MAX_BRIEF_SCHEMA_CHARS = 32 * 1024;
9502
9687
  var delegateTaskStatusInputSchema = {
9503
9688
  delegationId: z2.string().min(1)
@@ -9510,6 +9695,13 @@ function createManagedAgentMcpServerWithController(options, controller) {
9510
9695
  name: options.name ?? "boring-managed-agent",
9511
9696
  version: options.version ?? "0.0.0"
9512
9697
  });
9698
+ if (options.shareEntryStore && options.resolveShareSessionCtx && options.resolveShareWorkspace) {
9699
+ registerShareEntryResources(server, {
9700
+ store: options.shareEntryStore,
9701
+ resolveSessionCtx: options.resolveShareSessionCtx,
9702
+ resolveWorkspace: options.resolveShareWorkspace
9703
+ });
9704
+ }
9513
9705
  const registerTool = server.registerTool.bind(server);
9514
9706
  const delegateTaskInputSchema = createDelegateTaskInputSchema(options.maxBriefChars ?? DEFAULT_MAX_BRIEF_SCHEMA_CHARS);
9515
9707
  registerTool(
@@ -12643,7 +12835,7 @@ function requirePath(value, reply) {
12643
12835
  return value;
12644
12836
  }
12645
12837
  function gitRoutes(app, opts, done) {
12646
- async function resolveWorkspaceRoot(request) {
12838
+ async function resolveWorkspaceRoot2(request) {
12647
12839
  const workspace = opts.getWorkspace ? await opts.getWorkspace(request) : opts.workspace;
12648
12840
  return workspace === void 0 ? void 0 : getNodeWorkspaceHostRoot(workspace);
12649
12841
  }
@@ -12651,7 +12843,7 @@ function gitRoutes(app, opts, done) {
12651
12843
  const query = request.query;
12652
12844
  const path4 = requirePath(query.path, reply);
12653
12845
  if (path4 === null) return;
12654
- const workspaceRoot = await resolveWorkspaceRoot(request);
12846
+ const workspaceRoot = await resolveWorkspaceRoot2(request);
12655
12847
  if (!workspaceRoot) {
12656
12848
  return {
12657
12849
  enabled: false,
@@ -13315,6 +13507,51 @@ function buildUploadAgentTools(bundle) {
13315
13507
  ];
13316
13508
  }
13317
13509
 
13510
+ // src/server/http/routes/deepLink.ts
13511
+ var DEFAULT_WORKSPACE_ID4 = "default";
13512
+ function getRequestWorkspaceId2(request) {
13513
+ return request.workspaceContext?.workspaceId ?? DEFAULT_WORKSPACE_ID4;
13514
+ }
13515
+ function sendShareNotFound(reply) {
13516
+ return reply.code(404).send({
13517
+ error: { code: ShareEntryErrorCode.enum.AR1_SHARE_NOT_FOUND, message: "share not found" }
13518
+ });
13519
+ }
13520
+ var deepLinkRoutes = (app, opts, done) => {
13521
+ async function resolveWorkspace(request) {
13522
+ if (opts.getWorkspace) return await opts.getWorkspace(request);
13523
+ if (opts.workspace) return opts.workspace;
13524
+ throw new Error("deep-link route requires workspace or getWorkspace");
13525
+ }
13526
+ app.get("/a/:id", async (request, reply) => {
13527
+ const { id } = request.params;
13528
+ const requestWorkspaceId = getRequestWorkspaceId2(request);
13529
+ const entry = await opts.store.get(id);
13530
+ if (!entry || entry.workspaceId !== requestWorkspaceId) {
13531
+ return sendShareNotFound(reply);
13532
+ }
13533
+ const workspace = await resolveWorkspace(request);
13534
+ const resolution = await resolveShareEntry(opts.store, id, workspace);
13535
+ switch (resolution.status) {
13536
+ case "not_found":
13537
+ return sendShareNotFound(reply);
13538
+ case "tombstoned":
13539
+ return reply.code(200).send({
13540
+ status: "tombstoned",
13541
+ code: resolution.code,
13542
+ tombstone: resolution.tombstone
13543
+ });
13544
+ case "ok":
13545
+ return reply.code(200).send({
13546
+ status: "ok",
13547
+ workspaceId: resolution.entry.workspaceId,
13548
+ id: resolution.entry.id
13549
+ });
13550
+ }
13551
+ });
13552
+ done();
13553
+ };
13554
+
13318
13555
  // src/server/runtime/runtimeBindingLifecycle.ts
13319
13556
  function createRuntimeBindingLifecycle(options) {
13320
13557
  const { app } = options;
@@ -13602,7 +13839,7 @@ function createRuntimeBindingLifecycle(options) {
13602
13839
 
13603
13840
  // src/server/registerAgentRoutes.ts
13604
13841
  var DEFAULT_VERSION2 = "0.1.0-dev";
13605
- var DEFAULT_WORKSPACE_ID4 = "default";
13842
+ var DEFAULT_WORKSPACE_ID5 = "default";
13606
13843
  var STANDARD_AGENT_TOOL_NAMES = ["bash", "read", "write", "edit", "find", "grep", "ls"];
13607
13844
  function pluginNameFromPath(path4) {
13608
13845
  const fileName = basename2(path4);
@@ -13622,8 +13859,8 @@ function getAvailableModelProviders() {
13622
13859
  new Set(availableModels.map((model) => model.provider))
13623
13860
  ).sort((a, b) => a.localeCompare(b));
13624
13861
  }
13625
- function getRequestWorkspaceId2(request) {
13626
- return request.workspaceContext?.workspaceId ?? DEFAULT_WORKSPACE_ID4;
13862
+ function getRequestWorkspaceId3(request) {
13863
+ return request.workspaceContext?.workspaceId ?? DEFAULT_WORKSPACE_ID5;
13627
13864
  }
13628
13865
  function promoteRawFileWorkspaceQueryToHeader(request) {
13629
13866
  const pathname = request.url.split("?")[0] ?? request.url;
@@ -13716,7 +13953,7 @@ function createRuntimeReadinessCheck(workspaceId, getRuntimeDependencies) {
13716
13953
  };
13717
13954
  }
13718
13955
  var registerAgentRoutes = async (app, opts) => {
13719
- const sessionId = opts.sessionId ?? DEFAULT_WORKSPACE_ID4;
13956
+ const sessionId = opts.sessionId ?? DEFAULT_WORKSPACE_ID5;
13720
13957
  const resolvedMode = opts.runtimeModeAdapter?.id ?? opts.mode ?? autoDetectMode();
13721
13958
  const workspaceRoot = opts.workspaceRoot ?? process.cwd();
13722
13959
  const templatePath = opts.templatePath ?? getEnv("BORING_AGENT_TEMPLATE_PATH");
@@ -13738,7 +13975,8 @@ var registerAgentRoutes = async (app, opts) => {
13738
13975
  }
13739
13976
  });
13740
13977
  const modelsWorkspaceScoped = Boolean(opts.filterModels);
13741
- const requestScopedRuntime = typeof opts.getWorkspaceId === "function" || typeof opts.getWorkspaceRoot === "function" || typeof opts.getTemplatePath === "function" || typeof opts.getPi === "function" || typeof opts.getExtraTools === "function" || typeof opts.getSessionNamespace === "function" || typeof opts.getSystemPromptDynamic === "function" || typeof opts.getTrustedWorkspaceRoot === "function";
13978
+ const requestScopedRuntime = typeof opts.getWorkspaceId === "function" || typeof opts.getWorkspaceRoot === "function" || typeof opts.getTemplatePath === "function" || typeof opts.getPi === "function" || typeof opts.getExtraTools === "function" || typeof opts.getSessionNamespace === "function" || typeof opts.getSystemPromptDynamic === "function" || typeof opts.getRuntimeScopeContribution === "function" || typeof opts.getTrustedWorkspaceRoot === "function";
13979
+ const runtimeScopeByRequest = /* @__PURE__ */ new WeakMap();
13742
13980
  const sessionChangesTracker = new InMemorySessionChangesTracker();
13743
13981
  const externalPluginsEnabled = opts.externalPlugins !== false;
13744
13982
  async function resolveScopePi(workspaceId, root, request) {
@@ -13761,11 +13999,13 @@ var registerAgentRoutes = async (app, opts) => {
13761
13999
  const pi = await resolveScopePi(workspaceId, root, request);
13762
14000
  const sessionNamespace = normalizeSessionNamespace(opts.getSessionNamespace ? await opts.getSessionNamespace({ workspaceId, workspaceRoot: root, request, userId: trustedCtx?.userId }) : opts.sessionNamespace);
13763
14001
  const extraToolsAuthSubject = opts.getExtraTools ? trustedCtx?.userId ?? getRequestAuthSubject2(request) : void 0;
14002
+ const contribution = await opts.getRuntimeScopeContribution?.({ workspaceId, workspaceRoot: root, request });
13764
14003
  return {
13765
14004
  root,
13766
14005
  templatePath: scopedTemplatePath,
13767
14006
  pi,
13768
14007
  sessionNamespace,
14008
+ loadSystemPromptAppend: contribution?.loadSystemPromptAppend,
13769
14009
  key: JSON.stringify([
13770
14010
  resolvedMode,
13771
14011
  workspaceId,
@@ -13773,10 +14013,26 @@ var registerAgentRoutes = async (app, opts) => {
13773
14013
  scopedTemplatePath ?? null,
13774
14014
  pi,
13775
14015
  sessionNamespace ?? null,
13776
- extraToolsAuthSubject ?? null
14016
+ extraToolsAuthSubject ?? null,
14017
+ contribution?.identity ?? null
13777
14018
  ])
13778
14019
  };
13779
14020
  }
14021
+ function getRuntimeScope(workspaceId, request, trustedCtx) {
14022
+ if (!request) return resolveRuntimeScope(workspaceId, void 0, trustedCtx);
14023
+ let scopes = runtimeScopeByRequest.get(request);
14024
+ if (!scopes) {
14025
+ scopes = /* @__PURE__ */ new Map();
14026
+ runtimeScopeByRequest.set(request, scopes);
14027
+ }
14028
+ const identity = JSON.stringify([workspaceId, trustedCtx?.userId ?? null]);
14029
+ let promise = scopes.get(identity);
14030
+ if (!promise) {
14031
+ promise = resolveRuntimeScope(workspaceId, request, trustedCtx);
14032
+ scopes.set(identity, promise);
14033
+ }
14034
+ return promise;
14035
+ }
13780
14036
  async function resolveSkillScope(workspaceId, request) {
13781
14037
  const root = request && opts.getWorkspaceRoot ? await opts.getWorkspaceRoot(workspaceId, request) : workspaceRoot;
13782
14038
  const pi = await resolveScopePi(workspaceId, root, request);
@@ -13823,6 +14079,7 @@ var registerAgentRoutes = async (app, opts) => {
13823
14079
  }
13824
14080
  async function createRuntimeBinding(workspaceId, scope, request, trustedCtx) {
13825
14081
  const root = scope.root;
14082
+ const scopedSystemPromptAppend = await scope.loadSystemPromptAppend?.();
13826
14083
  const modeCtx = {
13827
14084
  workspaceRoot: root,
13828
14085
  sessionId: workspaceId,
@@ -14036,7 +14293,7 @@ var registerAgentRoutes = async (app, opts) => {
14036
14293
  checkReadiness
14037
14294
  }),
14038
14295
  harnessFactory,
14039
- systemPromptAppend: opts.systemPromptAppend,
14296
+ systemPromptAppend: [opts.systemPromptAppend, scopedSystemPromptAppend].filter(Boolean).join("\n\n") || void 0,
14040
14297
  systemPromptDynamic,
14041
14298
  telemetry: opts.telemetry,
14042
14299
  metering: opts.metering,
@@ -14095,7 +14352,7 @@ var registerAgentRoutes = async (app, opts) => {
14095
14352
  }
14096
14353
  async function resolveRuntimeBinding(workspaceId, request, options = {}) {
14097
14354
  bindingLifecycle.assertAdmission(workspaceId, request);
14098
- const scope = await resolveRuntimeScope(workspaceId, request, options.trustedCtx);
14355
+ const scope = await getRuntimeScope(workspaceId, request, options.trustedCtx);
14099
14356
  bindingLifecycle.assertAdmission(workspaceId, request);
14100
14357
  const existing = bindingLifecycle.getEntry(scope.key);
14101
14358
  if (existing) {
@@ -14286,14 +14543,14 @@ var registerAgentRoutes = async (app, opts) => {
14286
14543
  function getSkillsScopeForRequest(request) {
14287
14544
  let promise = skillsScopeByRequest.get(request);
14288
14545
  if (!promise) {
14289
- promise = resolveSkillScope(getRequestWorkspaceId2(request), request);
14546
+ promise = resolveSkillScope(getRequestWorkspaceId3(request), request);
14290
14547
  skillsScopeByRequest.set(request, promise);
14291
14548
  }
14292
14549
  return promise;
14293
14550
  }
14294
14551
  async function getBindingForRequest(request, options = {}) {
14295
14552
  if (staticBinding) return staticBinding;
14296
- return await getOrCreateRuntimeBinding(getRequestWorkspaceId2(request), request, options);
14553
+ return await getOrCreateRuntimeBinding(getRequestWorkspaceId3(request), request, options);
14297
14554
  }
14298
14555
  async function getFilesystemBindingsForRequest(request) {
14299
14556
  const binding = await getBindingForRequest(request);
@@ -14301,7 +14558,7 @@ var registerAgentRoutes = async (app, opts) => {
14301
14558
  const user = request.user;
14302
14559
  return await opts.getFilesystemBindings({
14303
14560
  request,
14304
- workspaceId: getRequestWorkspaceId2(request),
14561
+ workspaceId: getRequestWorkspaceId3(request),
14305
14562
  workspaceRoot: binding.workspaceRoot,
14306
14563
  userId: user?.id,
14307
14564
  userEmail: user?.email,
@@ -14328,7 +14585,7 @@ var registerAgentRoutes = async (app, opts) => {
14328
14585
  }
14329
14586
  app.addHook("onRequest", async (request, reply) => {
14330
14587
  const user = request.user;
14331
- let workspaceId = DEFAULT_WORKSPACE_ID4;
14588
+ let workspaceId = DEFAULT_WORKSPACE_ID5;
14332
14589
  promoteRawFileWorkspaceQueryToHeader(request);
14333
14590
  if (opts.getWorkspaceId && !isWorkspaceAgnosticAgentRequest(request, { readyStatusWorkspaceScoped: requestScopedRuntime, modelsWorkspaceScoped })) {
14334
14591
  try {
@@ -14382,6 +14639,12 @@ var registerAgentRoutes = async (app, opts) => {
14382
14639
  await app.register(searchRoutes, {
14383
14640
  getFileSearch: async (request) => (await getBindingForRequest(request)).runtimeBundle.fileSearch
14384
14641
  });
14642
+ if (opts.shareEntryStore) {
14643
+ await app.register(deepLinkRoutes, {
14644
+ store: opts.shareEntryStore,
14645
+ getWorkspace: async (request) => (await getBindingForRequest(request)).runtimeBundle.workspace
14646
+ });
14647
+ }
14385
14648
  await app.register(gitRoutes, {
14386
14649
  getWorkspace: async (request) => {
14387
14650
  const runtimeBundle = (await getBindingForRequest(request)).runtimeBundle;
@@ -14427,7 +14690,7 @@ var registerAgentRoutes = async (app, opts) => {
14427
14690
  });
14428
14691
  await app.register(sessionChangesRoutes, { tracker: sessionChangesTracker });
14429
14692
  app.post("/api/v1/agent/reload", async (request, reply) => {
14430
- const workspaceId = getRequestWorkspaceId2(request);
14693
+ const workspaceId = getRequestWorkspaceId3(request);
14431
14694
  const binding = await getBindingForRequest(request);
14432
14695
  if (!binding.harness.reloadSession) {
14433
14696
  return reply.status(501).send({ ok: false, error: "Agent harness does not support reload" });
@@ -14511,6 +14774,8 @@ export {
14511
14774
  getBoringAgentPathEntries,
14512
14775
  getBoringAgentRuntimeEnv,
14513
14776
  createDirectSandbox,
14777
+ validatePath,
14778
+ assertRealPathWithinWorkspace,
14514
14779
  createNodeWorkspace,
14515
14780
  createBwrapSandbox,
14516
14781
  FileHandleStore,
@@ -14523,6 +14788,7 @@ export {
14523
14788
  prepareDeploymentSnapshot,
14524
14789
  createVercelDeploymentSnapshotProvider,
14525
14790
  prepareVercelDeploymentSnapshot,
14791
+ resolveWorkspaceRoot,
14526
14792
  REMOTE_WORKER_RUNTIME_CWD,
14527
14793
  REMOTE_WORKER_PROVIDER,
14528
14794
  WORKER_INTERNAL_TOKEN_HEADER,
@@ -14557,6 +14823,8 @@ export {
14557
14823
  ManagedAgentMcpError,
14558
14824
  ManagedAgentMcpDelegateController,
14559
14825
  createManagedAgentMcpDelegateController,
14826
+ shareResourceUri,
14827
+ registerShareEntryResources,
14560
14828
  createManagedAgentMcpServer,
14561
14829
  createManagedAgentMcpHttpHandler,
14562
14830
  createAgentApp,