@hachej/boring-agent 0.1.20 → 0.1.22

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.
package/README.md CHANGED
@@ -28,6 +28,7 @@ npx @hachej/boring-agent
28
28
  | **Three execution modes** | `direct` (no isolation, macOS dev) / `local` (bwrap sandbox) / `vercel-sandbox` (Firecracker microVM) |
29
29
  | **CLI + embeddable** | `npx @hachej/boring-agent` works standalone; `<ChatPanel />` composes into any layout |
30
30
  | **7 standard tools** | `bash`, `read`, `write`, `edit`, `find`, `grep`, `ls` — ported from pi-coding-agent |
31
+ | **Workspace-local runtime provisioning** | Generates `.boring-agent` inside the selected workspace for mirrored skills, SDKs, CLIs, and templates |
31
32
  | **Workspace-agnostic FS** | `Workspace` interface — agent tools and HTTP routes share the same filesystem view |
32
33
  | **Session management** | List, create, switch, delete sessions with streamed history hydration |
33
34
  | **UI bridge** | Agent opens files, panels, and surfaces in the workbench via typed commands |
@@ -58,6 +59,21 @@ write a test for src/utils.ts
58
59
 
59
60
  ---
60
61
 
62
+ ## Workspace-local runtime provisioning
63
+
64
+ Boring UI keeps generated runtime state in the selected workspace at
65
+ `$BORING_AGENT_WORKSPACE_ROOT/.boring-agent`. Plugin skills are mirrored to
66
+ `.boring-agent/skills`, runtime CLIs live under `.boring-agent/node` or
67
+ `.boring-agent/venv`, and templates seed only missing workspace files. The
68
+ folder is generated/disposable and should not be hand-edited or committed.
69
+
70
+ See [docs/runtime-provisioning.md](docs/runtime-provisioning.md) for the full
71
+ user and plugin-author contract, including package metadata shape,
72
+ `provisionWorkspace: false`, `/api/v1/agent/reload`, and direct/local/Vercel
73
+ mode behavior.
74
+
75
+ ---
76
+
61
77
  ## Architecture
62
78
 
63
79
  ```
@@ -1,3 +1,16 @@
1
+ // src/shared/telemetry.ts
2
+ var noopTelemetry = {
3
+ capture() {
4
+ }
5
+ };
6
+ function safeCapture(telemetry, event) {
7
+ try {
8
+ void Promise.resolve(telemetry.capture(event)).catch(() => {
9
+ });
10
+ } catch {
11
+ }
12
+ }
13
+
1
14
  // src/shared/error-codes.ts
2
15
  import { z } from "zod";
3
16
  var ErrorCode = z.enum([
@@ -37,6 +50,15 @@ var ErrorCode = z.enum([
37
50
  // Plugin
38
51
  "PLUGIN_LOAD_FAILED",
39
52
  "PLUGIN_NAME_COLLISION",
53
+ // Runtime provisioning
54
+ "PROVISIONING_LAYOUT_FAILED",
55
+ "PROVISIONING_SKILLS_FAILED",
56
+ "PROVISIONING_TEMPLATES_FAILED",
57
+ "PROVISIONING_NODE_PREFLIGHT_FAILED",
58
+ "PROVISIONING_NPM_INSTALL_FAILED",
59
+ "PROVISIONING_UV_BOOTSTRAP_FAILED",
60
+ "PROVISIONING_UV_INSTALL_FAILED",
61
+ "PROVISIONING_ARTIFACT_FAILED",
40
62
  // Internal
41
63
  "INTERNAL_ERROR"
42
64
  ]);
@@ -68,6 +90,8 @@ function validateTool(tool) {
68
90
  }
69
91
 
70
92
  export {
93
+ noopTelemetry,
94
+ safeCapture,
71
95
  ErrorCode,
72
96
  ERROR_CODES,
73
97
  ApiErrorPayloadSchema,
@@ -5,7 +5,7 @@ import { T as ToolUiMetadata } from '../tool-ui-DIFNGwYd.js';
5
5
  import * as ai from 'ai';
6
6
  import { UIMessage, FileUIPart, ChatStatus } from 'ai';
7
7
  import * as _ai_sdk_react from '@ai-sdk/react';
8
- import { S as SendMessageInput, e as SessionSummary } from '../harness-DRrTn_5T.js';
8
+ import { S as SendMessageInput, e as SessionSummary } from '../harness-BCit36Ha.js';
9
9
  import { Button, Collapsible, CollapsibleContent, CollapsibleTrigger, InputGroupAddon, InputGroupButton, InputGroupTextarea } from '@hachej/boring-ui-kit';
10
10
  import { Streamdown } from 'streamdown';
11
11
  import { StickToBottom } from 'use-stick-to-bottom';
@@ -29,6 +29,18 @@ interface SessionDetail extends SessionSummary {
29
29
  messages: UIMessage[];
30
30
  }
31
31
 
32
+ interface TelemetrySink {
33
+ capture(event: TelemetryEvent): void | Promise<void>;
34
+ flush?(): void | Promise<void>;
35
+ }
36
+ interface TelemetryEvent {
37
+ name: string;
38
+ distinctId?: string;
39
+ properties?: Record<string, unknown>;
40
+ }
41
+ declare const noopTelemetry: TelemetrySink;
42
+ declare function safeCapture(telemetry: TelemetrySink, event: TelemetryEvent): void;
43
+
32
44
  type JSONSchema = Record<string, unknown>;
33
45
  interface AgentTool {
34
46
  name: string;
@@ -67,6 +79,8 @@ interface AgentHarnessFactoryInput {
67
79
  * prompt context without a workspace-injected harness extension.
68
80
  */
69
81
  systemPromptDynamic?: () => string | undefined | Promise<string | undefined>;
82
+ /** Host-provided telemetry sink. Optional and best-effort; harnesses may ignore it. */
83
+ telemetry?: TelemetrySink;
70
84
  }
71
85
  type AgentHarnessFactory = (input: AgentHarnessFactoryInput) => AgentHarness | Promise<AgentHarness>;
72
86
  interface AgentHarness {
@@ -127,4 +141,4 @@ interface RunContext {
127
141
  userId?: string;
128
142
  }
129
143
 
130
- export type { AgentTool as A, JSONSchema as J, RunContext as R, SendMessageInput as S, ToolExecContext as T, AgentHarness as a, SessionCtx as b, SessionDetail as c, SessionStore as d, SessionSummary as e, ToolResult as f, AgentHarnessFactory as g, AgentHarnessFactoryInput as h };
144
+ export { type AgentTool as A, type JSONSchema as J, type RunContext as R, type SendMessageInput as S, type TelemetryEvent as T, type AgentHarness as a, type SessionCtx as b, type SessionDetail as c, type SessionStore as d, type SessionSummary as e, type TelemetrySink as f, type ToolExecContext as g, type ToolResult as h, type AgentHarnessFactory as i, type AgentHarnessFactoryInput as j, noopTelemetry as n, safeCapture as s };
@@ -1,8 +1,8 @@
1
1
  import { S as Sandbox, f as SandboxHandleStore, e as SandboxHandleRecord, W as Workspace, F as FileSearch, P as PluginRestartWarning } from '../agentPluginEvents-zyIvVjsA.js';
2
2
  import { Sandbox as Sandbox$1 } from '@vercel/sandbox';
3
3
  import { FastifyInstance, FastifyRequest, FastifyPluginAsync } from 'fastify';
4
- import { A as AgentTool, g as AgentHarnessFactory } from '../harness-DRrTn_5T.js';
5
- export { h as AgentHarnessFactoryInput } from '../harness-DRrTn_5T.js';
4
+ import { f as TelemetrySink, A as AgentTool, i as AgentHarnessFactory } from '../harness-BCit36Ha.js';
5
+ export { j as AgentHarnessFactoryInput } from '../harness-BCit36Ha.js';
6
6
  import { PackageSource, ExtensionFactory, SettingsManager } from '@mariozechner/pi-coding-agent';
7
7
  import 'ai';
8
8
 
@@ -181,12 +181,12 @@ declare function fileRoutes(app: FastifyInstance, opts: {
181
181
  getWorkspace?: (request: FastifyRequest) => Workspace | Promise<Workspace>;
182
182
  }, done: (err?: Error) => void): void;
183
183
 
184
- interface RuntimeTemplateContribution {
184
+ interface RuntimeTemplateContribution$1 {
185
185
  id: string;
186
186
  path: string | URL;
187
187
  target?: string;
188
188
  }
189
- interface RuntimePythonSpec {
189
+ interface RuntimePythonSpec$1 {
190
190
  id: string;
191
191
  /** uv-compatible pyproject.toml. Console scripts declared here are exposed to the agent. */
192
192
  projectFile: string | URL;
@@ -195,23 +195,23 @@ interface RuntimePythonSpec {
195
195
  /** Env vars exported by command shims, e.g. plugin builtin paths. */
196
196
  env?: Record<string, string | URL>;
197
197
  }
198
- interface RuntimeNodePackageSpec {
198
+ interface RuntimeNodePackageSpec$1 {
199
199
  id: string;
200
200
  /** Package name materialized under workspaceRoot/node_modules, e.g. @boring/workspace. */
201
201
  packageName: string;
202
202
  /** Source package root. The provisioner copies the built package payload into node_modules. */
203
203
  packageRoot: string | URL;
204
204
  }
205
- interface RuntimeProvisioningContribution {
206
- templateDirs?: RuntimeTemplateContribution[];
207
- python?: RuntimePythonSpec[];
208
- nodePackages?: RuntimeNodePackageSpec[];
205
+ interface RuntimeProvisioningContribution$1 {
206
+ templateDirs?: RuntimeTemplateContribution$1[];
207
+ python?: RuntimePythonSpec$1[];
208
+ nodePackages?: RuntimeNodePackageSpec$1[];
209
209
  }
210
210
  interface ProvisionRuntimeWorkspaceOptions {
211
211
  workspaceRoot: string;
212
212
  contributions?: Array<{
213
213
  id: string;
214
- provisioning?: RuntimeProvisioningContribution;
214
+ provisioning?: RuntimeProvisioningContribution$1;
215
215
  }>;
216
216
  force?: boolean;
217
217
  }
@@ -223,6 +223,31 @@ interface RuntimeWorkspaceProvisioningResult {
223
223
  }
224
224
  declare function provisionRuntimeWorkspace({ workspaceRoot, contributions, force, }: ProvisionRuntimeWorkspaceOptions): Promise<RuntimeWorkspaceProvisioningResult>;
225
225
 
226
+ interface BoringAgentRuntimePaths {
227
+ /** Runtime-visible workspace root. This is BORING_AGENT_WORKSPACE_ROOT. */
228
+ workspaceRoot: string;
229
+ agentDir: string;
230
+ node: string;
231
+ nodeModules: string;
232
+ nodeBin: string;
233
+ venv: string;
234
+ venvBin: string;
235
+ venvPython: string;
236
+ sdk: string;
237
+ uvHome: string;
238
+ uvBin: string;
239
+ skills: string;
240
+ cache: string;
241
+ nodeCache: string;
242
+ uvCache: string;
243
+ pipCache: string;
244
+ tmp: string;
245
+ }
246
+ declare function getBoringAgentRuntimePaths(runtimeWorkspaceRoot: string): BoringAgentRuntimePaths;
247
+ declare function getBoringAgentPathEntries(paths: BoringAgentRuntimePaths): string[];
248
+ declare function getBoringAgentRuntimeEnv(paths: BoringAgentRuntimePaths, adapterCacheRoot?: string): Record<string, string>;
249
+
250
+ declare const VERCEL_SANDBOX_WORKSPACE_ROOT = "/workspace";
226
251
  interface VercelSandboxWorkspace extends Workspace {
227
252
  invalidateMetadataCache(): void;
228
253
  }
@@ -231,6 +256,120 @@ interface VercelSandboxWorkspaceOptions {
231
256
  }
232
257
  declare function createVercelSandboxWorkspace(sandbox: Sandbox$1, workspaceOpts?: VercelSandboxWorkspaceOptions): VercelSandboxWorkspace;
233
258
 
259
+ interface ProvisioningLogger {
260
+ info?(message: string, fields?: Record<string, unknown>): void;
261
+ warn?(message: string, fields?: Record<string, unknown>): void;
262
+ error?(message: string, fields?: Record<string, unknown>): void;
263
+ }
264
+
265
+ interface PluginSkillSource {
266
+ name: string;
267
+ source: string | URL;
268
+ }
269
+ interface RuntimeTemplateContribution {
270
+ id: string;
271
+ path: string | URL;
272
+ target?: string;
273
+ }
274
+ interface RuntimePythonSpec {
275
+ id: string;
276
+ projectFile: string | URL;
277
+ packageName?: string;
278
+ packageRoot?: string | URL;
279
+ version?: string;
280
+ extraLibs?: string[];
281
+ env?: Record<string, string | URL>;
282
+ expectedBins?: string[];
283
+ }
284
+ interface RuntimeNodePackageSpec {
285
+ id: string;
286
+ packageName: string;
287
+ packageRoot?: string | URL;
288
+ version?: string;
289
+ expectedBins?: string[];
290
+ }
291
+ interface RuntimeProvisioningContribution {
292
+ templateDirs?: RuntimeTemplateContribution[];
293
+ python?: RuntimePythonSpec[];
294
+ nodePackages?: RuntimeNodePackageSpec[];
295
+ }
296
+ interface WorkspaceProvisioningResult {
297
+ changed: boolean;
298
+ env: Record<string, string>;
299
+ pathEntries: string[];
300
+ skillPaths: string[];
301
+ }
302
+ interface WorkspaceProvisioningExecResult {
303
+ stdout?: string;
304
+ stderr?: string;
305
+ }
306
+ interface WorkspaceProvisioningAdapter {
307
+ mode: 'direct' | 'local' | 'vercel-sandbox';
308
+ exec(command: string, args: string[], opts?: {
309
+ cwd?: string;
310
+ env?: Record<string, string>;
311
+ timeoutMs?: number;
312
+ }): Promise<WorkspaceProvisioningExecResult | void>;
313
+ resolveInstallSource(source: string | URL, opts: {
314
+ kind: 'node' | 'python';
315
+ id: string;
316
+ fingerprint: string;
317
+ }): Promise<string>;
318
+ workspaceFs: {
319
+ exists(workspaceRelativePath: string): Promise<boolean>;
320
+ /** Remove a workspace-relative generated path. Missing path is success. */
321
+ rm(workspaceRelativePath: string): Promise<void>;
322
+ /** Create a workspace-relative directory recursively. */
323
+ mkdir(workspaceRelativePath: string): Promise<void>;
324
+ writeText(workspaceRelativePath: string, content: string): Promise<void>;
325
+ readText(workspaceRelativePath: string): Promise<string | null>;
326
+ /** Copy a host file or directory into the workspace; directory copies are recursive. */
327
+ copyFromHost(hostSourcePath: string | URL, workspaceRelativeTarget: string): Promise<void>;
328
+ };
329
+ getRuntimeCacheRoot(): string;
330
+ }
331
+ interface ProvisioningTelemetryContext {
332
+ workspaceId?: string;
333
+ sessionId?: string;
334
+ requestId?: string;
335
+ runtimeMode?: string;
336
+ }
337
+ interface ProvisionWorkspaceRuntimeOptions {
338
+ plugins: Array<{
339
+ id: string;
340
+ skills?: PluginSkillSource[];
341
+ provisioning?: RuntimeProvisioningContribution;
342
+ }>;
343
+ adapter: WorkspaceProvisioningAdapter;
344
+ runtimeLayout: BoringAgentRuntimePaths;
345
+ logger?: ProvisioningLogger;
346
+ telemetry?: TelemetrySink;
347
+ telemetryContext?: ProvisioningTelemetryContext;
348
+ }
349
+
350
+ declare function provisionWorkspaceRuntime(opts: ProvisionWorkspaceRuntimeOptions): Promise<WorkspaceProvisioningResult>;
351
+
352
+ declare const VERCEL_PROVISIONING_CACHE_ROOT = "/tmp/boring-agent-cache";
353
+ interface VercelProvisioningArtifactRequest {
354
+ kind: 'node' | 'python';
355
+ id: string;
356
+ fingerprint: string;
357
+ source: string | URL;
358
+ outputPath: string;
359
+ }
360
+ interface CreateVercelProvisioningAdapterOptions {
361
+ runtimeLayout: BoringAgentRuntimePaths;
362
+ workspaceFs: WorkspaceProvisioningAdapter['workspaceFs'];
363
+ exec(command: string, args: string[], opts?: {
364
+ cwd?: string;
365
+ env?: Record<string, string>;
366
+ timeoutMs?: number;
367
+ }): Promise<WorkspaceProvisioningExecResult | void>;
368
+ prepareArtifact(request: VercelProvisioningArtifactRequest): Promise<void>;
369
+ cacheRoot?: string;
370
+ }
371
+ declare function createVercelProvisioningAdapter(options: CreateVercelProvisioningAdapterOptions): WorkspaceProvisioningAdapter;
372
+
234
373
  type BuiltinRuntimeModeId = 'direct' | 'local' | 'vercel-sandbox';
235
374
  type RuntimeModeId = BuiltinRuntimeModeId | (string & {});
236
375
  interface RuntimeModeAdapter {
@@ -242,6 +381,7 @@ interface RuntimeModeAdapter {
242
381
  */
243
382
  readonly workspaceFsCapability?: Workspace['fsCapability'];
244
383
  create(ctx: ModeContext): Promise<RuntimeBundle>;
384
+ createProvisioningAdapter?(runtimeLayout: BoringAgentRuntimePaths, ctx?: ModeContext): WorkspaceProvisioningAdapter;
245
385
  dispose?(): Promise<void>;
246
386
  }
247
387
  interface ModeContext {
@@ -249,6 +389,8 @@ interface ModeContext {
249
389
  sessionId: string;
250
390
  workspaceId?: string;
251
391
  templatePath?: string;
392
+ requestId?: string;
393
+ telemetry?: TelemetrySink;
252
394
  }
253
395
  interface RuntimeBundle {
254
396
  workspace: Workspace;
@@ -342,8 +484,14 @@ interface CreateAgentAppOptions {
342
484
  harnessFactory?: AgentHarnessFactory;
343
485
  /** Optional pi adapter/runtime knobs used by the default harness. */
344
486
  pi?: PiHarnessOptions;
487
+ /** Optional runtime provisioning result used to wire generated PATH/env/skills into tools and Pi. */
488
+ runtimeProvisioning?: WorkspaceProvisioningResult;
489
+ /** Optional dynamic runtime provisioning source used after /reload refreshes generated env/PATH. */
490
+ getRuntimeProvisioning?: () => WorkspaceProvisioningResult | undefined;
345
491
  /** Optional stable namespace for file-backed session storage. */
346
492
  sessionNamespace?: string;
493
+ /** Optional best-effort telemetry sink supplied by an embedding host. */
494
+ telemetry?: TelemetrySink;
347
495
  /** Optional explicit file-backed session directory. Mostly for tests/hosts. */
348
496
  sessionDir?: string;
349
497
  /**
@@ -400,6 +548,8 @@ interface RegisterAgentRoutesOptions {
400
548
  request?: FastifyRequest;
401
549
  }) => PiHarnessOptions | undefined | Promise<PiHarnessOptions | undefined>;
402
550
  sessionNamespace?: string;
551
+ /** Optional best-effort telemetry sink supplied by an embedding host. */
552
+ telemetry?: TelemetrySink;
403
553
  getSessionNamespace?: (ctx: {
404
554
  workspaceId: string;
405
555
  workspaceRoot: string;
@@ -409,6 +559,26 @@ interface RegisterAgentRoutesOptions {
409
559
  sandboxHandleStore?: SandboxHandleStore;
410
560
  getWorkspaceId?: (request: FastifyRequest) => string | Promise<string>;
411
561
  getWorkspaceRoot?: (workspaceId: string, request: FastifyRequest) => string | Promise<string>;
562
+ /**
563
+ * Optional runtime reconciliation hook. Callers own plugin discovery and may
564
+ * call provisionWorkspaceRuntime() with the normalized structural inputs.
565
+ * registerAgentRoutes only consumes the returned env/PATH/skill paths.
566
+ */
567
+ provisionRuntime?: (ctx: {
568
+ workspaceId: string;
569
+ workspaceRoot: string;
570
+ runtimeMode: RuntimeModeId;
571
+ runtimeLayout: BoringAgentRuntimePaths;
572
+ provisioningAdapter?: WorkspaceProvisioningAdapter;
573
+ request?: FastifyRequest;
574
+ }) => WorkspaceProvisioningResult | undefined | Promise<WorkspaceProvisioningResult | undefined>;
575
+ provisionWorkspace?: boolean;
576
+ /** Optional hook called before /api/v1/agent/reload reloads the harness. */
577
+ beforeReload?: (ctx: {
578
+ workspaceId: string;
579
+ workspaceRoot: string;
580
+ request: FastifyRequest;
581
+ }) => void | ReloadHookResult | undefined | Promise<void | ReloadHookResult | undefined>;
412
582
  }
413
583
  /**
414
584
  * Fastify plugin that mounts agent routes onto a host app (typically core-built).
@@ -430,4 +600,4 @@ interface Logger {
430
600
  }
431
601
  declare function createLogger(prefix: string): Logger;
432
602
 
433
- export { AgentHarnessFactory, type BuiltinRuntimeModeId, type CreateAgentAppOptions, type DeploymentSnapshotProvider, type DeploymentSnapshotRecipe, type DeploymentSnapshotResult, type DeploymentSnapshotStatus, FileHandleStore, type LogFields, type Logger, type ModeContext, PI_PACKAGE_RESOURCE_FILTERS, type PiExtensionFactory, type PiHarnessOptions, type PiPackageSource, type ProvisionRuntimeWorkspaceOptions, type RegisterAgentRoutesOptions, type RuntimeBundle, type RuntimeModeAdapter, type RuntimeModeId, type RuntimeNodePackageSpec, type RuntimeProvisioningContribution, type RuntimePythonSpec, type RuntimeTemplateContribution, type RuntimeWorkspaceProvisioningResult, type SnapshotBakeOptions, type SnapshotBakeResult, UV_SETUP_COMMANDS, UV_SETUP_COMMANDS as VERCEL_UV_SETUP_COMMANDS, type VercelBakeClient, type VercelBakeSandbox, type VercelDeploymentSnapshotOptions, applyCspHeaders, autoDetectMode, bakeSnapshotIfNeeded, buildDeploymentSnapshotRecipe, buildPackageHash, buildSnapshotRecipeHash, compactPiPackages, createAgentApp, createBwrapSandbox, createDirectSandbox, createLogger, createNodeWorkspace, createResourceSettingsManager, createVercelDeploymentSnapshotProvider, createVercelSandboxWorkspace, fileRoutes, hasBwrap, mergePiPackageSources, piPackageSourceKey, prepareDeploymentSnapshot, prepareVercelDeploymentSnapshot, provisionRuntimeWorkspace, registerAgentRoutes, resolveMode, resolveSandboxHandle };
603
+ export { AgentHarnessFactory, type BoringAgentRuntimePaths, type BuiltinRuntimeModeId, type CreateAgentAppOptions, type CreateVercelProvisioningAdapterOptions, type DeploymentSnapshotProvider, type DeploymentSnapshotRecipe, type DeploymentSnapshotResult, type DeploymentSnapshotStatus, FileHandleStore, type LogFields, type Logger, type ModeContext, PI_PACKAGE_RESOURCE_FILTERS, type PiExtensionFactory, type PiHarnessOptions, type PiPackageSource, type PluginSkillSource, type ProvisionRuntimeWorkspaceOptions, type ProvisionWorkspaceRuntimeOptions, type RegisterAgentRoutesOptions, type RuntimeBundle, type RuntimeModeAdapter, type RuntimeModeId, type RuntimeNodePackageSpec, type RuntimeProvisioningContribution, type RuntimePythonSpec, type RuntimeTemplateContribution, type RuntimeWorkspaceProvisioningResult, type SnapshotBakeOptions, type SnapshotBakeResult, UV_SETUP_COMMANDS, VERCEL_PROVISIONING_CACHE_ROOT, VERCEL_SANDBOX_WORKSPACE_ROOT, UV_SETUP_COMMANDS as VERCEL_UV_SETUP_COMMANDS, type VercelBakeClient, type VercelBakeSandbox, type VercelDeploymentSnapshotOptions, type VercelProvisioningArtifactRequest, type WorkspaceProvisioningAdapter, type WorkspaceProvisioningExecResult, type WorkspaceProvisioningResult, applyCspHeaders, autoDetectMode, bakeSnapshotIfNeeded, buildDeploymentSnapshotRecipe, buildPackageHash, buildSnapshotRecipeHash, compactPiPackages, createAgentApp, createBwrapSandbox, createDirectSandbox, createLogger, createNodeWorkspace, createResourceSettingsManager, createVercelDeploymentSnapshotProvider, createVercelProvisioningAdapter, createVercelSandboxWorkspace, fileRoutes, getBoringAgentPathEntries, getBoringAgentRuntimeEnv, getBoringAgentRuntimePaths, hasBwrap, mergePiPackageSources, piPackageSourceKey, prepareDeploymentSnapshot, prepareVercelDeploymentSnapshot, provisionRuntimeWorkspace, provisionWorkspaceRuntime, registerAgentRoutes, resolveMode, resolveSandboxHandle };